aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineLICM.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-10-19 17:14:24 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-10-19 17:14:24 +0000
commit98694138025fdb0cec0cda5727201ad00ded3d63 (patch)
tree069867aa0faebfa45f69541d5627f77ebe342fdb /lib/CodeGen/MachineLICM.cpp
parentf3a925dc7a14ade42da442b49c304c064954c1d4 (diff)
downloadexternal_llvm-98694138025fdb0cec0cda5727201ad00ded3d63.zip
external_llvm-98694138025fdb0cec0cda5727201ad00ded3d63.tar.gz
external_llvm-98694138025fdb0cec0cda5727201ad00ded3d63.tar.bz2
Revert r116781 "- Add a hook for target to determine whether an instruction def
is", which breaks some nightly tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116816 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
-rw-r--r--lib/CodeGen/MachineLICM.cpp88
1 files changed, 52 insertions, 36 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index ae3d9db..7ecf126 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -43,6 +43,11 @@
using namespace llvm;
+static cl::opt<bool>
+TrackRegPressure("rp-aware-machine-licm",
+ cl::desc("Register pressure aware machine LICM"),
+ cl::init(false), cl::Hidden);
+
STATISTIC(NumHoisted,
"Number of machine instructions hoisted out of loops");
STATISTIC(NumLowRP,
@@ -119,7 +124,6 @@ namespace {
RegSeen.clear();
RegPressure.clear();
RegLimit.clear();
- BackTrace.clear();
for (DenseMap<unsigned,std::vector<const MachineInstr*> >::iterator
CI = CSEMap.begin(), CE = CSEMap.end(); CI != CE; ++CI)
CI->second.clear();
@@ -167,10 +171,9 @@ namespace {
///
bool IsLoopInvariantInst(MachineInstr &I);
- /// HasHighOperandLatency - Compute operand latency between a def of 'Reg'
- /// and an use in the current loop, return true if the target considered
- /// it 'high'.
- bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, unsigned Reg);
+ /// ComputeOperandLatency - Compute operand latency between a def of 'Reg'
+ /// and an use in the current loop.
+ int ComputeOperandLatency(MachineInstr &MI, unsigned DefIdx, unsigned Reg);
/// IncreaseHighRegPressure - Visit BBs from preheader to current BB, check
/// if hoisting an instruction of the given cost matrix can cause high
@@ -553,24 +556,28 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) {
if (!Preheader)
return;
- if (IsHeader) {
- // Compute registers which are liveout of preheader.
- RegSeen.clear();
- BackTrace.clear();
- InitRegPressure(Preheader);
- }
+ if (TrackRegPressure) {
+ if (IsHeader) {
+ // Compute registers which are liveout of preheader.
+ RegSeen.clear();
+ BackTrace.clear();
+ InitRegPressure(Preheader);
+ }
- // Remember livein register pressure.
- BackTrace.push_back(RegPressure);
+ // Remember livein register pressure.
+ BackTrace.push_back(RegPressure);
+ }
for (MachineBasicBlock::iterator
MII = BB->begin(), E = BB->end(); MII != E; ) {
MachineBasicBlock::iterator NextMII = MII; ++NextMII;
MachineInstr *MI = &*MII;
- UpdateRegPressureBefore(MI);
+ if (TrackRegPressure)
+ UpdateRegPressureBefore(MI);
Hoist(MI, Preheader);
- UpdateRegPressureAfter(MI);
+ if (TrackRegPressure)
+ UpdateRegPressureAfter(MI);
MII = NextMII;
}
@@ -584,7 +591,8 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) {
HoistRegion(Children[I]);
}
- BackTrace.pop_back();
+ if (TrackRegPressure)
+ BackTrace.pop_back();
}
/// InitRegPressure - Find all virtual register references that are liveout of
@@ -780,14 +788,15 @@ bool MachineLICM::isLoadFromConstantMemory(MachineInstr *MI) {
}
}
-/// HasHighOperandLatency - Compute operand latency between a def of 'Reg'
-/// and an use in the current loop, return true if the target considered
-/// it 'high'.
-bool MachineLICM::HasHighOperandLatency(MachineInstr &MI,
- unsigned DefIdx, unsigned Reg) {
+/// ComputeOperandLatency - Compute operand latency between a def of 'Reg'
+/// and an use in the current loop.
+int MachineLICM::ComputeOperandLatency(MachineInstr &MI,
+ unsigned DefIdx, unsigned Reg) {
if (MRI->use_nodbg_empty(Reg))
- return false;
+ // No use? Return arbitrary large number!
+ return 300;
+ int Latency = -1;
for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg),
E = MRI->use_nodbg_end(); I != E; ++I) {
MachineInstr *UseMI = &*I;
@@ -801,15 +810,18 @@ bool MachineLICM::HasHighOperandLatency(MachineInstr &MI,
if (MOReg != Reg)
continue;
- if (TII->hasHighOperandLatency(InstrItins, MRI, &MI, DefIdx, UseMI, i))
- return true;
+ int UseCycle = TII->getOperandLatency(InstrItins, &MI, DefIdx, UseMI, i);
+ Latency = std::max(Latency, UseCycle);
}
- // Only look at the first in loop use.
- break;
+ if (Latency != -1)
+ break;
}
- return false;
+ if (Latency == -1)
+ Latency = InstrItins->getOperandCycle(MI.getDesc().getSchedClass(), DefIdx);
+
+ return Latency;
}
/// IncreaseHighRegPressure - Visit BBs from preheader to current BB, check
@@ -843,19 +855,19 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
if (MI.isImplicitDef())
return true;
- // If the instruction is cheap, only hoist if it is re-materilizable. LICM
- // will increase register pressure. It's probably not worth it if the
- // instruction is cheap.
+ // FIXME: For now, only hoist re-materilizable instructions. LICM will
+ // increase register pressure. We want to make sure it doesn't increase
+ // spilling.
// Also hoist loads from constant memory, e.g. load from stubs, GOT. Hoisting
// these tend to help performance in low register pressure situation. The
// trade off is it may cause spill in high pressure situation. It will end up
// adding a store in the loop preheader. But the reload is no more expensive.
// The side benefit is these loads are frequently CSE'ed.
- if (MI.getDesc().isAsCheapAsAMove()) {
- if (!TII->isTriviallyReMaterializable(&MI, AA))
+ if (!TrackRegPressure || MI.getDesc().isAsCheapAsAMove()) {
+ if (!TII->isTriviallyReMaterializable(&MI, AA) &&
+ !isLoadFromConstantMemory(&MI))
return false;
} else {
- // Estimate register pressure to determine whether to LICM the instruction.
// In low register pressure situation, we can be more aggressive about
// hoisting. Also, favors hoisting long latency instructions even in
// moderately high pressure situation.
@@ -868,9 +880,13 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
continue;
if (MO.isDef()) {
- if (HasHighOperandLatency(MI, i, Reg)) {
- ++NumHighLatency;
- return true;
+ if (InstrItins && !InstrItins->isEmpty()) {
+ int Cycle = ComputeOperandLatency(MI, i, Reg);
+ if (Cycle > 3) {
+ // FIXME: Target specific high latency limit?
+ ++NumHighLatency;
+ return true;
+ }
}
const TargetRegisterClass *RC = MRI->getRegClass(Reg);