Author: Sjoerd Meijer Date: 2021-01-08T09:04:56Z New Revision: 8af859d514fa0ef4a75b3c3dfb1ee8f42ac9bd04
URL: https://github.com/llvm/llvm-project/commit/8af859d514fa0ef4a75b3c3dfb1ee8f42ac9bd04 DIFF: https://github.com/llvm/llvm-project/commit/8af859d514fa0ef4a75b3c3dfb1ee8f42ac9bd04.diff LOG: [MachineLoop] New helper isLoopInvariant() This factors out code from MachineLICM that determines whether an instruction is loop-invariant, which is a generally useful function. Thus this allows to use that helper elsewhere too. Differential Revision: https://reviews.llvm.org/D94082 Added: Modified: llvm/include/llvm/CodeGen/MachineLoopInfo.h llvm/lib/CodeGen/MachineLICM.cpp llvm/lib/CodeGen/MachineLoopInfo.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/CodeGen/MachineLoopInfo.h b/llvm/include/llvm/CodeGen/MachineLoopInfo.h index 8a93f91ae54d..c7491d4191de 100644 --- a/llvm/include/llvm/CodeGen/MachineLoopInfo.h +++ b/llvm/include/llvm/CodeGen/MachineLoopInfo.h @@ -67,6 +67,12 @@ class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> { /// 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 index 7c356cf0e15b..c06bc39b4940 100644 --- a/llvm/lib/CodeGen/MachineLICM.cpp +++ b/llvm/lib/CodeGen/MachineLICM.cpp @@ -1079,60 +1079,12 @@ bool MachineLICMBase::IsLICMCandidate(MachineInstr &I) { } /// 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 index 0c1439da9b29..78480d0e1488 100644 --- 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 @@ MachineLoopInfo::findLoopPreheader(MachineLoop *L, 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()); _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits