diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2010-10-19 18:58:51 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2010-10-19 18:58:51 +0000 |
| commit | 2312842de0c641107dd04d7e056d02491cc781ca (patch) | |
| tree | 95cb951c694a628d7bc9bac370b2fd929dd343d5 /lib/CodeGen/MachineLICM.cpp | |
| parent | 9cb4c7f87876ec8212bd4fae059553fcaa83f484 (diff) | |
Re-enable register pressure aware machine licm with fixes. Hoist() may have
erased the instruction during LICM so UpdateRegPressureAfter() should not
reference it afterwards.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116845 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
| -rw-r--r-- | lib/CodeGen/MachineLICM.cpp | 135 |
1 files changed, 58 insertions, 77 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 3e25e917c9..1f0412498b 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -43,11 +43,6 @@ 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, @@ -128,6 +123,7 @@ 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(); @@ -175,9 +171,10 @@ namespace { /// bool IsLoopInvariantInst(MachineInstr &I); - /// ComputeOperandLatency - Compute operand latency between a def of 'Reg' - /// and an use in the current loop. - int ComputeOperandLatency(MachineInstr &MI, unsigned DefIdx, unsigned Reg); + /// 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); /// IncreaseHighRegPressure - Visit BBs from preheader to current BB, check /// if hoisting an instruction of the given cost matrix can cause high @@ -203,8 +200,9 @@ namespace { /// UpdateRegPressureBefore / UpdateRegPressureAfter - Update estimate of /// register pressure before and after executing a specifi instruction. - void UpdateRegPressureBefore(const MachineInstr *MI); - void UpdateRegPressureAfter(const MachineInstr *MI); + void UpdateRegPressureBefore(const MachineInstr *MI, + SmallVector<unsigned, 4> &Defs); + void UpdateRegPressureAfter(SmallVector<unsigned, 4> &Defs); /// isLoadFromConstantMemory - Return true if the given instruction is a /// load from constant memory. @@ -560,28 +558,26 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) { if (!Preheader) return; - 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); + if (IsHeader) { + // Compute registers which are liveout of preheader. + RegSeen.clear(); + BackTrace.clear(); + InitRegPressure(Preheader); } + // Remember livein register pressure. + BackTrace.push_back(RegPressure); + + SmallVector<unsigned, 4> Defs; for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; MachineInstr *MI = &*MII; - if (TrackRegPressure) - UpdateRegPressureBefore(MI); + assert(Defs.empty()); + UpdateRegPressureBefore(MI, Defs); Hoist(MI, Preheader); - if (TrackRegPressure) - UpdateRegPressureAfter(MI); + UpdateRegPressureAfter(Defs); MII = NextMII; } @@ -595,8 +591,7 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) { HoistRegion(Children[I]); } - if (TrackRegPressure) - BackTrace.pop_back(); + BackTrace.pop_back(); } /// InitRegPressure - Find all virtual register references that are liveout of @@ -635,12 +630,13 @@ void MachineLICM::InitRegPressure(MachineBasicBlock *BB) { /// UpdateRegPressureBefore / UpdateRegPressureAfter - Update estimate of /// register pressure before and after executing a specifi instruction. -void MachineLICM::UpdateRegPressureBefore(const MachineInstr *MI) { +void MachineLICM::UpdateRegPressureBefore(const MachineInstr *MI, + SmallVector<unsigned, 4> &Defs) { bool NoImpact = MI->isImplicitDef() || MI->isPHI(); for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || MO.isImplicit() || !MO.isUse()) + if (!MO.isReg() || MO.isImplicit()) continue; unsigned Reg = MO.getReg(); if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) @@ -650,33 +646,26 @@ void MachineLICM::UpdateRegPressureBefore(const MachineInstr *MI) { if (NoImpact) continue; - if (!isNew && MO.isKill()) { - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); + if (MO.isDef()) + Defs.push_back(Reg); + else { + if (!isNew && MO.isKill()) { + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + EVT VT = *RC->vt_begin(); + unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); + unsigned RCCost = TLI->getRepRegClassCostFor(VT); - assert(RCCost <= RegPressure[RCId]); - RegPressure[RCId] -= RCCost; + assert(RCCost <= RegPressure[RCId]); + RegPressure[RCId] -= RCCost; + } } } } -void MachineLICM::UpdateRegPressureAfter(const MachineInstr *MI) { - bool NoImpact = MI->isImplicitDef() || MI->isPHI(); - - for (unsigned i = 0, e = MI->getDesc().getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (!MO.isReg() || MO.isImplicit() || !MO.isDef()) - continue; - unsigned Reg = MO.getReg(); - if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) - continue; - +void MachineLICM::UpdateRegPressureAfter(SmallVector<unsigned, 4> &Defs) { + while (!Defs.empty()) { + unsigned Reg = Defs.pop_back_val(); RegSeen.insert(Reg); - if (NoImpact) - continue; - const TargetRegisterClass *RC = MRI->getRegClass(Reg); EVT VT = *RC->vt_begin(); unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); @@ -792,15 +781,14 @@ bool MachineLICM::isLoadFromConstantMemory(MachineInstr *MI) { } } -/// 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) { +/// 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) { if (MRI->use_nodbg_empty(Reg)) - // No use? Return arbitrary large number! - return 300; + return false; - 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; @@ -814,18 +802,15 @@ int MachineLICM::ComputeOperandLatency(MachineInstr &MI, if (MOReg != Reg) continue; - int UseCycle = TII->getOperandLatency(InstrItins, &MI, DefIdx, UseMI, i); - Latency = std::max(Latency, UseCycle); + if (TII->hasHighOperandLatency(InstrItins, MRI, &MI, DefIdx, UseMI, i)) + return true; } - if (Latency != -1) - break; + // Only look at the first in loop use. + break; } - if (Latency == -1) - Latency = InstrItins->getOperandCycle(MI.getDesc().getSchedClass(), DefIdx); - - return Latency; + return false; } /// IncreaseHighRegPressure - Visit BBs from preheader to current BB, check @@ -859,19 +844,19 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) { if (MI.isImplicitDef()) return true; - // FIXME: For now, only hoist re-materilizable instructions. LICM will - // increase register pressure. We want to make sure it doesn't increase - // spilling. + // 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. // 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 (!TrackRegPressure || MI.getDesc().isAsCheapAsAMove()) { - if (!TII->isTriviallyReMaterializable(&MI, AA) && - !isLoadFromConstantMemory(&MI)) + if (MI.getDesc().isAsCheapAsAMove()) { + if (!TII->isTriviallyReMaterializable(&MI, AA)) 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. @@ -884,13 +869,9 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) { if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) continue; if (MO.isDef()) { - if (InstrItins && !InstrItins->isEmpty()) { - int Cycle = ComputeOperandLatency(MI, i, Reg); - if (Cycle > 3) { - // FIXME: Target specific high latency limit? - ++NumHighLatency; - return true; - } + if (HasHighOperandLatency(MI, i, Reg)) { + ++NumHighLatency; + return true; } const TargetRegisterClass *RC = MRI->getRegClass(Reg); |
