Teach postra machine licm to hoist more obvious invariants, e.g. instructions with no source operands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101154 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-04-13 18:16:00 +00:00
parent 4183e31978
commit 5dc57ce533

View File

@ -101,10 +101,10 @@ namespace {
/// CandidateInfo - Keep track of information about hoisting candidates.
struct CandidateInfo {
MachineInstr *MI;
int FI;
unsigned Def;
CandidateInfo(MachineInstr *mi, int fi, unsigned def)
: MI(mi), FI(fi), Def(def) {}
int FI;
CandidateInfo(MachineInstr *mi, unsigned def, int fi)
: MI(mi), Def(def), FI(fi) {}
};
/// HoistRegionPostRA - Walk the specified region of the CFG and hoist loop
@ -127,6 +127,11 @@ namespace {
void AddToLiveIns(unsigned Reg,
MachineBasicBlock *MBB, MachineBasicBlock *LoopHeader);
/// IsLICMCandidate - Returns true if the instruction may be a suitable
/// candidate for LICM. e.g. If the instruction is a call, then it's obviously
/// not safe to hoist it.
bool IsLICMCandidate(MachineInstr &I);
/// IsLoopInvariantInst - 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 or implicitly),
@ -271,6 +276,7 @@ void MachineLICM::ProcessMI(MachineInstr *MI,
SmallSet<int, 32> &StoredFIs,
SmallVector<CandidateInfo, 32> &Candidates) {
bool RuledOut = false;
bool HasRegFIUse = false;
unsigned Def = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@ -281,6 +287,7 @@ void MachineLICM::ProcessMI(MachineInstr *MI,
MFI->isSpillSlotObjectIndex(FI) &&
InstructionStoresToFI(MI, FI))
StoredFIs.insert(FI);
HasRegFIUse = true;
continue;
}
@ -292,8 +299,10 @@ void MachineLICM::ProcessMI(MachineInstr *MI,
assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
"Not expecting virtual register!");
if (!MO.isDef())
if (!MO.isDef()) {
HasRegFIUse = true;
continue;
}
if (MO.isImplicit()) {
++PhysRegDefs[Reg];
@ -325,13 +334,15 @@ void MachineLICM::ProcessMI(MachineInstr *MI,
RuledOut = true;
}
// FIXME: Only consider reloads for now. We should be able to handle
// remats which does not have register operands.
// Only consider reloads for now and remats which do not have register
// operands. FIXME: Consider unfold load folding instructions.
if (Def && !RuledOut) {
int FI;
if (TII->isLoadFromStackSlot(MI, FI) &&
MFI->isSpillSlotObjectIndex(FI))
Candidates.push_back(CandidateInfo(MI, FI, Def));
int FI = INT_MIN;
// FIXME: Also hoist instructions if all source operands are live in
// to the loop.
if ((!HasRegFIUse && IsLICMCandidate(*MI)) ||
(TII->isLoadFromStackSlot(MI, FI) && MFI->isSpillSlotObjectIndex(FI)))
Candidates.push_back(CandidateInfo(MI, Def, FI));
}
}
@ -385,7 +396,8 @@ void MachineLICM::HoistRegionPostRA(MachineDomTreeNode *N) {
// 2. If the candidate is a load from stack slot (always true for now),
// check if the slot is stored anywhere in the loop.
for (unsigned i = 0, e = Candidates.size(); i != e; ++i) {
if (StoredFIs.count(Candidates[i].FI))
if (Candidates[i].FI != INT_MIN &&
StoredFIs.count(Candidates[i].FI))
continue;
if (PhysRegDefs[Candidates[i].Def] == 1)
@ -470,12 +482,10 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N) {
HoistRegion(Children[I]);
}
/// IsLoopInvariantInst - 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 MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
/// IsLICMCandidate - Returns true if the instruction may be a suitable
/// candidate for LICM. e.g. If the instruction is a call, then it's obviously
/// not safe to hoist it.
bool MachineLICM::IsLICMCandidate(MachineInstr &I) {
const TargetInstrDesc &TID = I.getDesc();
// Ignore stuff that we obviously can't hoist.
@ -493,6 +503,17 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
// This is a trivial form of alias analysis.
return false;
}
return true;
}
/// IsLoopInvariantInst - 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 MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
if (!IsLICMCandidate(I))
return false;
// The instruction is loop invariant if all of its operands are.
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {