[llvm-branch-commits] [llvm] 8af859d - [MachineLoop] New helper isLoopInvariant()
Sjoerd Meijer via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jan 8 01:30:32 PST 2021
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());
More information about the llvm-branch-commits
mailing list