mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[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
This commit is contained in:
parent
aafed2f066
commit
8c005c9213
@ -67,6 +67,12 @@ public:
|
||||
/// 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:
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user