diff --git a/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/llvm/include/llvm/CodeGen/MachineLoopInfo.h --- a/llvm/include/llvm/CodeGen/MachineLoopInfo.h +++ b/llvm/include/llvm/CodeGen/MachineLoopInfo.h @@ -67,6 +67,12 @@ /// it returns an unknown location. DebugLoc getStartLoc() const; + /// Returns true if the instruction is loop invariant. + /// I.e., all virtual register operands are defined outside of the loop, + /// physical registers aren't accessed explicitly, and there are no side + /// effects that aren't captured by the operands or other flags. + bool isLoopInvariant(MachineInstr &I) const; + void dump() const; private: diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp --- a/llvm/lib/CodeGen/MachineLICM.cpp +++ b/llvm/lib/CodeGen/MachineLICM.cpp @@ -1079,60 +1079,12 @@ } /// Returns true if the instruction is loop invariant. -/// I.e., all virtual register operands are defined outside of the loop, -/// physical registers aren't accessed explicitly, and there are no side -/// effects that aren't captured by the operands or other flags. bool MachineLICMBase::IsLoopInvariantInst(MachineInstr &I) { if (!IsLICMCandidate(I)) { LLVM_DEBUG(dbgs() << "LICM: Instruction not a LICM candidate\n"); return false; } - - // The instruction is loop invariant if all of its operands are. - for (const MachineOperand &MO : I.operands()) { - if (!MO.isReg()) - continue; - - Register Reg = MO.getReg(); - if (Reg == 0) continue; - - // Don't hoist an instruction that uses or defines a physical register. - if (Register::isPhysicalRegister(Reg)) { - if (MO.isUse()) { - // If the physreg has no defs anywhere, it's just an ambient register - // and we can freely move its uses. Alternatively, if it's allocatable, - // it could get allocated to something with a def during allocation. - // However, if the physreg is known to always be caller saved/restored - // then this use is safe to hoist. - if (!MRI->isConstantPhysReg(Reg) && - !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF()))) - return false; - // Otherwise it's safe to move. - continue; - } else if (!MO.isDead()) { - // A def that isn't dead. We can't move it. - return false; - } else if (CurLoop->getHeader()->isLiveIn(Reg)) { - // If the reg is live into the loop, we can't hoist an instruction - // which would clobber it. - return false; - } - } - - if (!MO.isUse()) - continue; - - assert(MRI->getVRegDef(Reg) && - "Machine instr not mapped for this vreg?!"); - - // If the loop contains the definition of an operand, then the instruction - // isn't loop invariant. - if (CurLoop->contains(MRI->getVRegDef(Reg))) - return false; - } - - // If we got this far, the instruction is loop invariant! - return true; + return CurLoop->isLoopInvariant(I); } /// Return true if the specified instruction is used by a phi node and hoisting diff --git a/llvm/lib/CodeGen/MachineLoopInfo.cpp b/llvm/lib/CodeGen/MachineLoopInfo.cpp --- a/llvm/lib/CodeGen/MachineLoopInfo.cpp +++ b/llvm/lib/CodeGen/MachineLoopInfo.cpp @@ -16,11 +16,14 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/Analysis/LoopInfoImpl.h" #include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/Config/llvm-config.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; // Explicitly instantiate methods in LoopInfoImpl.h for MI-level Loops. @@ -146,6 +149,59 @@ return Preheader; } +bool MachineLoop::isLoopInvariant(MachineInstr &I) const { + MachineFunction *MF = I.getParent()->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); + + // The instruction is loop invariant if all of its operands are. + for (const MachineOperand &MO : I.operands()) { + if (!MO.isReg()) + continue; + + Register Reg = MO.getReg(); + if (Reg == 0) continue; + + // An instruction that uses or defines a physical register can't e.g. be + // hoisted, so mark this as not invariant. + if (Register::isPhysicalRegister(Reg)) { + if (MO.isUse()) { + // If the physreg has no defs anywhere, it's just an ambient register + // and we can freely move its uses. Alternatively, if it's allocatable, + // it could get allocated to something with a def during allocation. + // However, if the physreg is known to always be caller saved/restored + // then this use is safe to hoist. + if (!MRI->isConstantPhysReg(Reg) && + !(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF()))) + return false; + // Otherwise it's safe to move. + continue; + } else if (!MO.isDead()) { + // A def that isn't dead can't be moved. + return false; + } else if (getHeader()->isLiveIn(Reg)) { + // If the reg is live into the loop, we can't hoist an instruction + // which would clobber it. + return false; + } + } + + if (!MO.isUse()) + continue; + + assert(MRI->getVRegDef(Reg) && + "Machine instr not mapped for this vreg?!"); + + // If the loop contains the definition of an operand, then the instruction + // isn't loop invariant. + if (contains(MRI->getVRegDef(Reg))) + return false; + } + + // If we got this far, the instruction is loop invariant! + return true; +} + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MachineLoop::dump() const { print(dbgs());