diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-03-29 21:20:19 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-03-29 21:20:19 +0000 |
commit | 6094bd87d845afabba5b99ec4848fa6116bac682 (patch) | |
tree | 16e0d4e352d6c8446a6e31a831d3740fd0570808 /lib/CodeGen | |
parent | 3d090558510de9a3601965630c5c82d663c346ce (diff) | |
download | llvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.gz llvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.bz2 llvm-6094bd87d845afabba5b99ec4848fa6116bac682.tar.xz |
Recompute register class and hint for registers created during spilling.
The spill weight is not recomputed for an unspillable register - it stays infinite.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CalcSpillWeights.cpp | 46 | ||||
-rw-r--r-- | lib/CodeGen/InlineSpiller.cpp | 74 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocGreedy.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/SplitKit.cpp | 10 |
6 files changed, 87 insertions, 60 deletions
diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp index 5637f4e024..86ab2b6f27 100644 --- a/lib/CodeGen/CalcSpillWeights.cpp +++ b/lib/CodeGen/CalcSpillWeights.cpp @@ -103,6 +103,9 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) { // Don't recompute a target specific hint. bool noHint = mri.getRegAllocationHint(li.reg).first != 0; + // Don't recompute spill weight for an unspillable register. + bool Spillable = li.isSpillable(); + for (MachineRegisterInfo::reg_iterator I = mri.reg_begin(li.reg); MachineInstr *mi = I.skipInstruction();) { if (mi->isIdentityCopy() || mi->isImplicitDef() || mi->isDebugValue()) @@ -110,25 +113,28 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) { if (!visited.insert(mi)) continue; - // Get loop info for mi. - if (mi->getParent() != mbb) { - mbb = mi->getParent(); - loop = loops_.getLoopFor(mbb); - loopDepth = loop ? loop->getLoopDepth() : 0; - isExiting = loop ? loop->isLoopExiting(mbb) : false; + float weight = 1.0f; + if (Spillable) { + // Get loop info for mi. + if (mi->getParent() != mbb) { + mbb = mi->getParent(); + loop = loops_.getLoopFor(mbb); + loopDepth = loop ? loop->getLoopDepth() : 0; + isExiting = loop ? loop->isLoopExiting(mbb) : false; + } + + // Calculate instr weight. + bool reads, writes; + tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg); + weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth); + + // Give extra weight to what looks like a loop induction variable update. + if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb)) + weight *= 3; + + totalWeight += weight; } - // Calculate instr weight. - bool reads, writes; - tie(reads, writes) = mi->readsWritesVirtualRegister(li.reg); - float weight = LiveIntervals::getSpillWeight(writes, reads, loopDepth); - - // Give extra weight to what looks like a loop induction variable update. - if (writes && isExiting && lis_.isLiveOutOfMBB(li, mbb)) - weight *= 3; - - totalWeight += weight; - // Get allocation hints from copies. if (noHint || !mi->isCopy()) continue; @@ -150,10 +156,14 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) { // Always prefer the physreg hint. if (unsigned hint = hintPhys ? hintPhys : hintVirt) { mri.setRegAllocationHint(li.reg, 0, hint); - // Weakly boost the spill weifght of hinted registers. + // Weakly boost the spill weight of hinted registers. totalWeight *= 1.01F; } + // If the live interval was already unspillable, leave it that way. + if (!Spillable) + return; + // Mark li as unspillable if all live ranges are tiny. if (li.isZeroLength()) { li.markNotSpillable(); diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 397943bf3c..d0c750777f 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -139,6 +139,7 @@ private: MachineBasicBlock::iterator MI); void spillAroundUses(unsigned Reg); + void spillAll(); }; } @@ -629,10 +630,6 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, LiveInterval &NewLI = Edit->createFrom(VirtReg.reg, LIS, VRM); NewLI.markNotSpillable(); - // Rematting for a copy: Set allocation hint to be the destination register. - if (MI->isCopy()) - MRI.setRegAllocationHint(NewLI.reg, 0, MI->getOperand(0).getReg()); - // Finally we can rematerialize OrigMI before MI. SlotIndex DefIdx = Edit->rematerializeAt(*MI->getParent(), MI, NewLI.reg, RM, LIS, TII, TRI); @@ -718,6 +715,11 @@ void InlineSpiller::reMaterializeAll() { DEBUG(dbgs() << RegsToSpill.size() << " registers to spill after remat.\n"); } + +//===----------------------------------------------------------------------===// +// Spilling +//===----------------------------------------------------------------------===// + /// If MI is a load or store of StackSlot, it can be removed. bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { int FI = 0; @@ -906,31 +908,8 @@ void InlineSpiller::spillAroundUses(unsigned Reg) { } } -void InlineSpiller::spill(LiveRangeEdit &edit) { - Edit = &edit; - assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) - && "Trying to spill a stack slot."); - // Share a stack slot among all descendants of Original. - Original = VRM.getOriginal(edit.getReg()); - StackSlot = VRM.getStackSlot(Original); - StackInt = 0; - - DEBUG(dbgs() << "Inline spilling " - << MRI.getRegClass(edit.getReg())->getName() - << ':' << edit.getParent() << "\nFrom original " - << LIS.getInterval(Original) << '\n'); - assert(edit.getParent().isSpillable() && - "Attempting to spill already spilled value."); - assert(DeadDefs.empty() && "Previous spill didn't remove dead defs"); - - collectRegsToSpill(); - analyzeSiblingValues(); - reMaterializeAll(); - - // Remat may handle everything. - if (RegsToSpill.empty()) - return; - +/// spillAll - Spill all registers remaining after rematerialization. +void InlineSpiller::spillAll() { // Update LiveStacks now that we are committed to spilling. if (StackSlot == VirtRegMap::NO_STACK_SLOT) { StackSlot = VRM.assignVirt2StackSlot(Original); @@ -939,8 +918,8 @@ void InlineSpiller::spill(LiveRangeEdit &edit) { } else StackInt = &LSS.getInterval(StackSlot); - if (Original != edit.getReg()) - VRM.assignVirt2StackSlot(edit.getReg(), StackSlot); + if (Original != Edit->getReg()) + VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot); assert(StackInt->getNumValNums() == 1 && "Bad stack interval values"); for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) @@ -959,7 +938,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) { } // Finally delete the SnippetCopies. - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(edit.getReg()); + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Edit->getReg()); MachineInstr *MI = RI.skipInstruction();) { assert(SnippetCopies.count(MI) && "Remaining use wasn't a snippet copy"); // FIXME: Do this with a LiveRangeEdit callback. @@ -968,6 +947,35 @@ void InlineSpiller::spill(LiveRangeEdit &edit) { MI->eraseFromParent(); } + // Delete all spilled registers. for (unsigned i = 0, e = RegsToSpill.size(); i != e; ++i) - edit.eraseVirtReg(RegsToSpill[i], LIS); + Edit->eraseVirtReg(RegsToSpill[i], LIS); +} + +void InlineSpiller::spill(LiveRangeEdit &edit) { + Edit = &edit; + assert(!TargetRegisterInfo::isStackSlot(edit.getReg()) + && "Trying to spill a stack slot."); + // Share a stack slot among all descendants of Original. + Original = VRM.getOriginal(edit.getReg()); + StackSlot = VRM.getStackSlot(Original); + StackInt = 0; + + DEBUG(dbgs() << "Inline spilling " + << MRI.getRegClass(edit.getReg())->getName() + << ':' << edit.getParent() << "\nFrom original " + << LIS.getInterval(Original) << '\n'); + assert(edit.getParent().isSpillable() && + "Attempting to spill already spilled value."); + assert(DeadDefs.empty() && "Previous spill didn't remove dead defs"); + + collectRegsToSpill(); + analyzeSiblingValues(); + reMaterializeAll(); + + // Remat may handle everything. + if (!RegsToSpill.empty()) + spillAll(); + + Edit->calculateRegClassAndHint(MF, LIS, Loops); } diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index 94a3fc1ed0..6b8a533b66 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -15,6 +15,7 @@ #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/SetVector.h" +#include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" @@ -236,3 +237,13 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, } } +void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF, + LiveIntervals &LIS, + const MachineLoopInfo &Loops) { + VirtRegAuxInfo VRAI(MF, LIS, Loops); + for (iterator I = begin(), E = end(); I != E; ++I) { + LiveInterval &LI = **I; + VRAI.CalculateRegClass(LI.reg); + VRAI.CalculateWeightAndHint(LI); + } +} diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h index 04eced6d79..e02e0a872d 100644 --- a/lib/CodeGen/LiveRangeEdit.h +++ b/lib/CodeGen/LiveRangeEdit.h @@ -25,6 +25,7 @@ namespace llvm { class AliasAnalysis; class LiveIntervals; +class MachineLoopInfo; class MachineRegisterInfo; class VirtRegMap; @@ -179,6 +180,10 @@ public: LiveIntervals&, VirtRegMap&, const TargetInstrInfo&); + /// calculateRegClassAndHint - Recompute register class and hint for each new + /// register. + void calculateRegClassAndHint(MachineFunction&, LiveIntervals&, + const MachineLoopInfo&); }; } diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index 77a172870a..098df59beb 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -1164,6 +1164,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); LiveRangeEdit LRE(VirtReg, NewVRegs, this); spiller().spill(LRE); + setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill); if (VerifyEnabled) MF->verify(this, "After spilling"); diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index b89ff0c4fc..2c8066fb63 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -17,7 +17,6 @@ #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -881,14 +880,7 @@ void SplitEditor::finish() { } // Calculate spill weight and allocation hints for new intervals. - VirtRegAuxInfo vrai(VRM.getMachineFunction(), LIS, SA.Loops); - for (LiveRangeEdit::iterator I = Edit->begin(), E = Edit->end(); I != E; ++I){ - LiveInterval &li = **I; - vrai.CalculateRegClass(li.reg); - vrai.CalculateWeightAndHint(li); - DEBUG(dbgs() << " new interval " << MRI.getRegClass(li.reg)->getName() - << ":" << li << '\n'); - } + Edit->calculateRegClassAndHint(VRM.getMachineFunction(), LIS, SA.Loops); } |