aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineLICM.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-04-13 18:16:00 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-04-13 18:16:00 +0000
commit5dc57ce53329143c2b533882410be80ea5d259a7 (patch)
tree216fb3e7305579e3fef54a2c5e8cf7cf43b459a8 /lib/CodeGen/MachineLICM.cpp
parent4183e31978146ea529a87a2fc47b96aeb6cbe000 (diff)
downloadexternal_llvm-5dc57ce53329143c2b533882410be80ea5d259a7.zip
external_llvm-5dc57ce53329143c2b533882410be80ea5d259a7.tar.gz
external_llvm-5dc57ce53329143c2b533882410be80ea5d259a7.tar.bz2
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
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
-rw-r--r--lib/CodeGen/MachineLICM.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index 9bef16e..f99aa25 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -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) {