llvm.org GIT mirror llvm / a22edc8
Simplify the side effect stuff a bit more and make licm/sinking both work right according to the new flags. This removes the TII::isReallySideEffectFree predicate, and adds TII::isInvariantLoad. It removes NeverHasSideEffects+MayHaveSideEffects and adds UnmodeledSideEffects as machine instr flags. Now the clients can decide everything they need. I think isRematerializable can be implemented in terms of the flags we have now, though I will let others tackle that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45843 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
7 changed file(s) with 77 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
9191 SimpleLoad,
9292 MayLoad,
9393 MayStore,
94 NeverHasSideEffects,
95 MayHaveSideEffects,
94 UnmodeledSideEffects,
9695 Commutable,
9796 ConvertibleTo3Addr,
9897 UsesCustomDAGSchedInserter,
325324 return Flags & (1 << TID::MayStore);
326325 }
327326
328 /// hasNoSideEffects - Return true if all instances of this instruction are
329 /// guaranteed to have no side effects other than:
330 /// 1. The register operands that are def/used by the MachineInstr.
331 /// 2. Registers that are implicitly def/used by the MachineInstr.
332 /// 3. Memory Accesses captured by mayLoad() or mayStore().
333 ///
334 /// Examples of other side effects would be calling a function, modifying
335 /// 'invisible' machine state like a control register, etc.
336 ///
337 /// If some instances of this instruction are side-effect free but others are
338 /// not, the hasConditionalSideEffects() property should return true, not this
339 /// one.
340 ///
341 /// Note that you should not call this method directly, instead, call the
342 /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis
343 /// of the machine instruction.
344 bool hasNoSideEffects() const {
345 return Flags & (1 << TID::NeverHasSideEffects);
346 }
347
348 /// hasConditionalSideEffects - Return true if some instances of this
349 /// instruction are guaranteed to have no side effects other than those listed
350 /// for hasNoSideEffects(). To determine whether a specific machineinstr has
351 /// side effects, the TargetInstrInfo::isReallySideEffectFree virtual method
352 /// is invoked to decide.
353 ///
354 /// Note that you should not call this method directly, instead, call the
355 /// TargetInstrInfo::hasUnmodelledSideEffects method, which handles analysis
356 /// of the machine instruction.
357 bool hasConditionalSideEffects() const {
358 return Flags & (1 << TID::MayHaveSideEffects);
327 /// hasUnmodeledSideEffects - Return true if this instruction has side
328 /// effects that are not modeled by other flags. This does not return true
329 /// for instructions whose effects are captured by:
330 ///
331 /// 1. Their operand list and implicit definition/use list. Register use/def
332 /// info is explicit for instructions.
333 /// 2. Memory accesses. Use mayLoad/mayStore.
334 /// 3. Calling, branching, returning: use isCall/isReturn/isBranch.
335 ///
336 /// Examples of side effects would be modifying 'invisible' machine state like
337 /// a control register, flushing a cache, modifying a register invisible to
338 /// LLVM, etc.
339 ///
340 bool hasUnmodeledSideEffects() const {
341 return Flags & (1 << TID::UnmodeledSideEffects);
359342 }
360343
361344 //===--------------------------------------------------------------------===//
6868 isReallyTriviallyReMaterializable(MI);
6969 }
7070
71 /// hasUnmodelledSideEffects - Returns true if the instruction has side
72 /// effects that are not captured by any operands of the instruction or other
73 /// flags.
74 bool hasUnmodelledSideEffects(MachineInstr *MI) const {
75 const TargetInstrDesc &TID = MI->getDesc();
76 if (TID.hasNoSideEffects()) return false;
77 if (!TID.hasConditionalSideEffects()) return true;
78 return !isReallySideEffectFree(MI); // May have side effects
79 }
8071 protected:
8172 /// isReallyTriviallyReMaterializable - For instructions with opcodes for
8273 /// which the M_REMATERIALIZABLE flag is set, this function tests whether the
9081 return true;
9182 }
9283
93 /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
94 /// method is called to determine if the specific instance of this
95 /// instruction has side effects. This is useful in cases of instructions,
96 /// like loads, which generally always have side effects. A load from a
97 /// constant pool doesn't have side effects, though. So we need to
98 /// differentiate it from the general case.
99 virtual bool isReallySideEffectFree(MachineInstr *MI) const {
100 return false;
101 }
10284 public:
10385 /// Return true if the instruction is a register to register move
10486 /// and leave the source and dest operands in the passed parameters.
126108 return 0;
127109 }
128110
111 /// isInvariantLoad - Return true if the specified instruction (which is
112 /// marked mayLoad) is loading from a location whose value is invariant across
113 /// the function. For example, loading a value from the constant pool or from
114 /// from the argument area of a function if it does not change. This should
115 /// only return true of *all* loads the instruction does are invariant (if it
116 /// does multiple loads).
117 virtual bool isInvariantLoad(MachineInstr *MI) const {
118 return false;
119 }
120
121
129122 /// convertToThreeAddress - This method must be implemented by targets that
130123 /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
131124 /// may be able to convert a two-address instruction into one or more true
222222 /// effects that aren't captured by the operands or other flags.
223223 ///
224224 bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
225 const TargetInstrDesc &TID = I.getDesc();
226
227 // Ignore stuff that we obviously can't hoist.
228 if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() ||
229 TID.hasUnmodeledSideEffects())
230 return false;
231
232 if (TID.mayLoad()) {
233 // Okay, this instruction does a load. As a refinement, allow the target
234 // to decide whether the loaded value is actually a constant. If so, we
235 // can actually use it as a load.
236 if (!TII->isInvariantLoad(&I)) {
237 // FIXME: we should be able to sink loads with no other side effects if
238 // there is nothing that can change memory from here until the end of
239 // block. This is a trivial form of alias analysis.
240 return false;
241 }
242 }
243
244
225245 DEBUG({
226246 DOUT << "--- Checking if we can hoist " << I;
227247 if (I.getDesc().getImplicitUses()) {
242262 DOUT << " -> " << MRI->getName(*ImpDefs) << "\n";
243263 }
244264
245 if (TII->hasUnmodelledSideEffects(&I))
246 DOUT << " * Instruction has side effects.\n";
265 //if (TII->hasUnmodelledSideEffects(&I))
266 //DOUT << " * Instruction has side effects.\n";
247267 });
248268
249269 // The instruction is loop invariant if all of its operands are loop-invariant
266286 if (CurLoop->contains(RegInfo->getVRegDef(Reg)->getParent()))
267287 return false;
268288 }
269
270 // Don't hoist something that has unmodelled side effects.
271 if (TII->hasUnmodelledSideEffects(&I)) return false;
272289
273290 // If we got this far, the instruction is loop invariant!
274291 return true;
132132 const TargetInstrDesc &TID = MI->getDesc();
133133
134134 // Ignore stuff that we obviously can't sink.
135 if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch())
135 if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() ||
136 TID.hasUnmodeledSideEffects())
136137 return false;
137138
138 if (TID.mayLoad())
139 return false;
140
141 // Don't sink things with side-effects we don't understand.
142 if (TII->hasUnmodelledSideEffects(MI))
143 return false;
144
145 // FIXME: we should be able to sink loads with no other side effects if there
146 // is nothing that can change memory from here until the end of block. This
147 // is a trivial form of alias analysis.
139 if (TID.mayLoad()) {
140 // Okay, this instruction does a load. As a refinement, allow the target
141 // to decide whether the loaded value is actually a constant. If so, we
142 // can actually use it as a load.
143 if (!TII->isInvariantLoad(MI)) {
144 // FIXME: we should be able to sink loads with no other side effects if
145 // there is nothing that can change memory from here until the end of
146 // block. This is a trivial form of alias analysis.
147 return false;
148 }
149 }
148150
149151 // FIXME: This should include support for sinking instructions within the
150152 // block they are currently in to shorten the live ranges. We often get
762762 return true;
763763 }
764764
765 /// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this
766 /// method is called to determine if the specific instance of this instruction
767 /// has side effects. This is useful in cases of instructions, like loads, which
768 /// generally always have side effects. A load from a constant pool doesn't have
769 /// side effects, though. So we need to differentiate it from the general case.
770 bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const {
765 /// isInvariantLoad - Return true if the specified instruction (which is marked
766 /// mayLoad) is loading from a location whose value is invariant across the
767 /// function. For example, loading a value from the constant pool or from
768 /// from the argument area of a function if it does not change. This should
769 /// only return true of *all* loads the instruction does are invariant (if it
770 /// does multiple loads).
771 bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const {
772 // FIXME: This should work with any X86 instruction that does a load, for
773 // example, all load+op instructions.
771774 switch (MI->getOpcode()) {
772775 default: break;
773776 case X86::MOV32rm:
774 // Loads from stubs of global addresses are side effect free.
777 // Loads from stubs of global addresses are invariant.
775778 if (MI->getOperand(1).isReg() &&
776779 MI->getOperand(2).isImm() && MI->getOperand(3).isReg() &&
777780 MI->getOperand(4).isGlobal() &&
793796 case X86::MOVAPDrm:
794797 case X86::MMX_MOVD64rm:
795798 case X86::MMX_MOVQ64rm:
796 // Loads from constant pools are trivially rematerializable.
799 // Loads from constant pools are trivially invariant.
797800 if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() &&
798801 MI->getOperand(3).isReg() && MI->getOperand(4).isCPI() &&
799802 MI->getOperand(1).getReg() == 0 &&
814817 return false;
815818 }
816819
817 // All other instances of these instructions are presumed to have side
818 // effects.
820 // All other instances of these instructions are presumed to have other
821 // issues.
819822 return false;
820823 }
821824
254254 unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
255255 unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
256256 bool isReallyTriviallyReMaterializable(MachineInstr *MI) const;
257 bool isReallySideEffectFree(MachineInstr *MI) const;
257 bool isInvariantLoad(MachineInstr *MI) const;
258258
259259 /// convertToThreeAddress - This method must be implemented by targets that
260260 /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
356356 if (Inst.usesCustomDAGSchedInserter)
357357 OS << "|(1<
358358 if (Inst.isVariadic) OS << "|(1<
359 if (Inst.mayHaveSideEffects) OS << "|(1<
360 if (!HasSideEffects) OS << "|(1<SideEffects)";
359 if (HasSideEffects) OS << "|(1<SideEffects)";
361360 OS << ", 0";
362361
363362 // Emit all of the target-specific flags...