diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/MachineLICM.cpp | 27 | ||||
-rw-r--r-- | lib/CodeGen/MachineSink.cpp | 24 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.cpp | 23 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.h | 2 |
4 files changed, 49 insertions, 27 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 04211aba97..92256eb3c2 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -223,6 +223,26 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) { /// effects that aren't captured by the operands or other flags. /// bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { + const TargetInstrDesc &TID = I.getDesc(); + + // Ignore stuff that we obviously can't hoist. + if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || + TID.hasUnmodeledSideEffects()) + return false; + + if (TID.mayLoad()) { + // Okay, this instruction does a load. As a refinement, allow the target + // to decide whether the loaded value is actually a constant. If so, we + // can actually use it as a load. + if (!TII->isInvariantLoad(&I)) { + // FIXME: we should be able to sink loads with no other side effects if + // there is nothing that can change memory from here until the end of + // block. This is a trivial form of alias analysis. + return false; + } + } + + DEBUG({ DOUT << "--- Checking if we can hoist " << I; if (I.getDesc().getImplicitUses()) { @@ -243,8 +263,8 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { DOUT << " -> " << MRI->getName(*ImpDefs) << "\n"; } - if (TII->hasUnmodelledSideEffects(&I)) - DOUT << " * Instruction has side effects.\n"; + //if (TII->hasUnmodelledSideEffects(&I)) + //DOUT << " * Instruction has side effects.\n"; }); // The instruction is loop invariant if all of its operands are loop-invariant @@ -268,9 +288,6 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { return false; } - // Don't hoist something that has unmodelled side effects. - if (TII->hasUnmodelledSideEffects(&I)) return false; - // If we got this far, the instruction is loop invariant! return true; } diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index b83d844a16..dc3e364e8a 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -133,19 +133,21 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI) { const TargetInstrDesc &TID = MI->getDesc(); // Ignore stuff that we obviously can't sink. - if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch()) + if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() || + TID.hasUnmodeledSideEffects()) return false; - if (TID.mayLoad()) - return false; - - // Don't sink things with side-effects we don't understand. - if (TII->hasUnmodelledSideEffects(MI)) - return false; - - // FIXME: we should be able to sink loads with no other side effects if there - // is nothing that can change memory from here until the end of block. This - // is a trivial form of alias analysis. + if (TID.mayLoad()) { + // Okay, this instruction does a load. As a refinement, allow the target + // to decide whether the loaded value is actually a constant. If so, we + // can actually use it as a load. + if (!TII->isInvariantLoad(MI)) { + // FIXME: we should be able to sink loads with no other side effects if + // there is nothing that can change memory from here until the end of + // block. This is a trivial form of alias analysis. + return false; + } + } // FIXME: This should include support for sinking instructions within the // block they are currently in to shorten the live ranges. We often get diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index 26ab7d2d0a..100d308c56 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -763,16 +763,19 @@ bool X86InstrInfo::isReallyTriviallyReMaterializable(MachineInstr *MI) const { return true; } -/// isReallySideEffectFree - If the M_MAY_HAVE_SIDE_EFFECTS flag is set, this -/// method is called to determine if the specific instance of this instruction -/// has side effects. This is useful in cases of instructions, like loads, which -/// generally always have side effects. A load from a constant pool doesn't have -/// side effects, though. So we need to differentiate it from the general case. -bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const { +/// isInvariantLoad - Return true if the specified instruction (which is marked +/// mayLoad) is loading from a location whose value is invariant across the +/// function. For example, loading a value from the constant pool or from +/// from the argument area of a function if it does not change. This should +/// only return true of *all* loads the instruction does are invariant (if it +/// does multiple loads). +bool X86InstrInfo::isInvariantLoad(MachineInstr *MI) const { + // FIXME: This should work with any X86 instruction that does a load, for + // example, all load+op instructions. switch (MI->getOpcode()) { default: break; case X86::MOV32rm: - // Loads from stubs of global addresses are side effect free. + // Loads from stubs of global addresses are invariant. if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && MI->getOperand(4).isGlobal() && @@ -794,7 +797,7 @@ bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const { case X86::MOVAPDrm: case X86::MMX_MOVD64rm: case X86::MMX_MOVQ64rm: - // Loads from constant pools are trivially rematerializable. + // Loads from constant pools are trivially invariant. if (MI->getOperand(1).isReg() && MI->getOperand(2).isImm() && MI->getOperand(3).isReg() && MI->getOperand(4).isCPI() && MI->getOperand(1).getReg() == 0 && @@ -815,8 +818,8 @@ bool X86InstrInfo::isReallySideEffectFree(MachineInstr *MI) const { return false; } - // All other instances of these instructions are presumed to have side - // effects. + // All other instances of these instructions are presumed to have other + // issues. return false; } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 27675b94b1..68f1664746 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -255,7 +255,7 @@ public: unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; bool isReallyTriviallyReMaterializable(MachineInstr *MI) const; - bool isReallySideEffectFree(MachineInstr *MI) const; + bool isInvariantLoad(MachineInstr *MI) const; /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target |