From 9c3c2213647e3f1b71722d61875ebac01b65cb91 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 6 Jun 2008 07:54:39 +0000 Subject: [PATCH] Refine stack slot interval weight computation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52040 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveIntervalAnalysis.h | 10 ++-- lib/CodeGen/LiveIntervalAnalysis.cpp | 60 +++++++++++++++------ lib/CodeGen/RegAllocLinearScan.cpp | 21 +++++--- 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index a1fb5b9b5b1..473cc8e0996 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -283,10 +283,12 @@ namespace llvm { } /// addIntervalsForSpills - Create new intervals for spilled defs / uses of - /// the given interval. + /// the given interval. FIXME: It also returns the weight of the spill slot + /// (if any is created) by reference. This is temporary. std::vector addIntervalsForSpills(const LiveInterval& i, - const MachineLoopInfo *loopInfo, VirtRegMap& vrm); + const MachineLoopInfo *loopInfo, VirtRegMap& vrm, + float &SSWeight); /// spillPhysRegAroundRegDefsUses - Spill the specified physical register /// around all defs and uses of the specified interval. @@ -424,7 +426,7 @@ namespace llvm { SmallVector &ReMatIds, const MachineLoopInfo *loopInfo, unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse, std::map &MBBVRegsMap, - std::vector &NewLIs); + std::vector &NewLIs, float &SSWeight); void rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, LiveInterval::Ranges::const_iterator &I, MachineInstr *OrigDefMI, MachineInstr *DefMI, unsigned Slot, int LdSlot, @@ -436,7 +438,7 @@ namespace llvm { BitVector &RestoreMBBs, std::map > &RestoreIdxes, std::map &MBBVRegsMap, - std::vector &NewLIs); + std::vector &NewLIs, float &SSWeight); static LiveInterval createInterval(unsigned Reg); diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 053e4d272f8..37e3895b3c4 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -972,7 +972,9 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, const MachineLoopInfo *loopInfo, unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse, std::map &MBBVRegsMap, - std::vector &NewLIs) { + std::vector &NewLIs, float &SSWeight) { + MachineBasicBlock *MBB = MI->getParent(); + unsigned loopDepth = loopInfo->getLoopDepth(MBB); bool CanFold = false; RestartInstruction: for (unsigned i = 0; i != MI->getNumOperands(); ++i) { @@ -1041,7 +1043,14 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, } } - if (TryFold) { + // Update stack slot spill weight if we are splitting. + float Weight = getSpillWeight(HasDef, HasUse, loopDepth); + if (!TrySplit) + SSWeight += Weight; + + if (!TryFold) + CanFold = false; + else { // Do not fold load / store here if we are splitting. We'll find an // optimal point to insert a load / store later. if (!TrySplit) { @@ -1052,15 +1061,17 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, HasUse = false; HasDef = false; CanFold = false; - if (isRemoved(MI)) + if (isRemoved(MI)) { + SSWeight -= Weight; break; + } goto RestartInstruction; } } else { + // We'll try to fold it later if it's profitable. CanFold = canFoldMemoryOperand(MI, Ops, DefIsReMat); } - } else - CanFold = false; + } // Create a new virtual register for the spill interval. bool CreatedNewVReg = false; @@ -1195,7 +1206,7 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, BitVector &RestoreMBBs, std::map > &RestoreIdxes, std::map &MBBVRegsMap, - std::vector &NewLIs) { + std::vector &NewLIs, float &SSWeight) { bool AllCanFold = true; unsigned NewVReg = 0; unsigned start = getBaseIndex(I->start); @@ -1283,10 +1294,10 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, bool HasDef = false; bool HasUse = false; bool CanFold = rewriteInstructionForSpills(li, I->valno, TrySplit, - index, end, MI, ReMatOrigDefMI, ReMatDefMI, - Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, - CanDelete, vrm, rc, ReMatIds, loopInfo, NewVReg, - ImpUse, HasDef, HasUse, MBBVRegsMap, NewLIs); + index, end, MI, ReMatOrigDefMI, ReMatDefMI, + Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, + CanDelete, vrm, rc, ReMatIds, loopInfo, NewVReg, + ImpUse, HasDef, HasUse, MBBVRegsMap, NewLIs, SSWeight); if (!HasDef && !HasUse) continue; @@ -1445,7 +1456,8 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm, std::vector LiveIntervals:: addIntervalsForSpills(const LiveInterval &li, - const MachineLoopInfo *loopInfo, VirtRegMap &vrm) { + const MachineLoopInfo *loopInfo, VirtRegMap &vrm, + float &SSWeight) { // Since this is called after the analysis is done we don't know if // LiveVariables is available lv_ = getAnalysisToUpdate(); @@ -1457,6 +1469,9 @@ addIntervalsForSpills(const LiveInterval &li, li.print(DOUT, tri_); DOUT << '\n'; + // Spill slot weight. + SSWeight = 0.0f; + // Each bit specify whether it a spill is required in the MBB. BitVector SpillMBBs(mf_->getNumBlockIDs()); std::map > SpillIdxes; @@ -1511,17 +1526,18 @@ addIntervalsForSpills(const LiveInterval &li, Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, false, vrm, rc, ReMatIds, loopInfo, SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes, - MBBVRegsMap, NewLIs); + MBBVRegsMap, NewLIs, SSWeight); } else { rewriteInstructionsForSpills(li, false, I, NULL, 0, Slot, 0, false, false, false, false, vrm, rc, ReMatIds, loopInfo, SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes, - MBBVRegsMap, NewLIs); + MBBVRegsMap, NewLIs, SSWeight); } IsFirstRange = false; } + SSWeight = 0.0f; // Already accounted for when split. handleSpilledImpDefs(li, vrm, rc, NewLIs); return NewLIs; } @@ -1587,7 +1603,7 @@ addIntervalsForSpills(const LiveInterval &li, Slot, LdSlot, isLoad, isLoadSS, DefIsReMat, CanDelete, vrm, rc, ReMatIds, loopInfo, SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes, - MBBVRegsMap, NewLIs); + MBBVRegsMap, NewLIs, SSWeight); } // Insert spills / restores if we are splitting. @@ -1601,6 +1617,8 @@ addIntervalsForSpills(const LiveInterval &li, if (NeedStackSlot) { int Id = SpillMBBs.find_first(); while (Id != -1) { + MachineBasicBlock *MBB = mf_->getBlockNumbered(Id); + unsigned loopDepth = loopInfo->getLoopDepth(MBB); std::vector &spills = SpillIdxes[Id]; for (unsigned i = 0, e = spills.size(); i != e; ++i) { int index = spills[i].index; @@ -1657,6 +1675,10 @@ addIntervalsForSpills(const LiveInterval &li, if (isKill) AddedKill.insert(&nI); } + + // Update spill slot weight. + if (!isReMat) + SSWeight += getSpillWeight(true, false, loopDepth); } Id = SpillMBBs.find_next(Id); } @@ -1664,6 +1686,9 @@ addIntervalsForSpills(const LiveInterval &li, int Id = RestoreMBBs.find_first(); while (Id != -1) { + MachineBasicBlock *MBB = mf_->getBlockNumbered(Id); + unsigned loopDepth = loopInfo->getLoopDepth(MBB); + std::vector &restores = RestoreIdxes[Id]; for (unsigned i = 0, e = restores.size(); i != e; ++i) { int index = restores[i].index; @@ -1671,6 +1696,7 @@ addIntervalsForSpills(const LiveInterval &li, continue; unsigned VReg = restores[i].vreg; LiveInterval &nI = getOrCreateInterval(VReg); + bool isReMat = vrm.isReMaterialized(VReg); MachineInstr *MI = getInstructionFromIndex(index); bool CanFold = false; Ops.clear(); @@ -1694,7 +1720,7 @@ addIntervalsForSpills(const LiveInterval &li, // Fold the load into the use if possible. bool Folded = false; if (CanFold && !Ops.empty()) { - if (!vrm.isReMaterialized(VReg)) + if (!isReMat) Folded = tryFoldMemoryOperand(MI, vrm, NULL,index,Ops,true,Slot,VReg); else { MachineInstr *ReMatDefMI = vrm.getReMaterializedMI(VReg); @@ -1722,6 +1748,10 @@ addIntervalsForSpills(const LiveInterval &li, nI.removeRange(getLoadIndex(index), getUseIndex(index)+1); else vrm.addRestorePoint(VReg, MI); + + // Update spill slot weight. + if (!isReMat) + SSWeight += getSpillWeight(false, true, loopDepth); } Id = RestoreMBBs.find_next(Id); } diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 8bfa8680a7c..d29f6da7fdf 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -515,11 +515,14 @@ static void RevertVectorIteratorsTo(RALinScan::IntervalPtrs &V, unsigned Point){ /// addStackInterval - Create a LiveInterval for stack if the specified live /// interval has been spilled. static void addStackInterval(LiveInterval *cur, LiveStacks *ls_, - LiveIntervals *li_, VirtRegMap &vrm_) { + LiveIntervals *li_, float &Weight, + VirtRegMap &vrm_) { int SS = vrm_.getStackSlot(cur->reg); if (SS == VirtRegMap::NO_STACK_SLOT) return; LiveInterval &SI = ls_->getOrCreateInterval(SS); + SI.weight += Weight; + VNInfo *VNI; if (SI.getNumValNums()) VNI = SI.getValNumInfo(0); @@ -529,7 +532,6 @@ static void addStackInterval(LiveInterval *cur, LiveStacks *ls_, LiveInterval &RI = li_->getInterval(cur->reg); // FIXME: This may be overly conservative. SI.MergeRangesInAsValue(RI, VNI); - SI.weight += RI.weight; } /// assignRegOrStackSlotAtInterval - assign a register if one is available, or @@ -743,9 +745,10 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) // linearscan. if (cur->weight != HUGE_VALF && cur->weight <= minWeight) { DOUT << "\t\t\tspilling(c): " << *cur << '\n'; + float SSWeight; std::vector added = - li_->addIntervalsForSpills(*cur, loopInfo, *vrm_); - addStackInterval(cur, ls_, li_, *vrm_); + li_->addIntervalsForSpills(*cur, loopInfo, *vrm_, SSWeight); + addStackInterval(cur, ls_, li_, SSWeight, *vrm_); if (added.empty()) return; // Early exit if all spills were folded. @@ -796,9 +799,10 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) cur->overlapsFrom(*i->first, i->second)) { DOUT << "\t\t\tspilling(a): " << *i->first << '\n'; earliestStart = std::min(earliestStart, i->first->beginNumber()); + float SSWeight; std::vector newIs = - li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_); - addStackInterval(i->first, ls_, li_, *vrm_); + li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_, SSWeight); + addStackInterval(i->first, ls_, li_, SSWeight, *vrm_); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(reg); } @@ -810,9 +814,10 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) cur->overlapsFrom(*i->first, i->second-1)) { DOUT << "\t\t\tspilling(i): " << *i->first << '\n'; earliestStart = std::min(earliestStart, i->first->beginNumber()); + float SSWeight; std::vector newIs = - li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_); - addStackInterval(i->first, ls_, li_, *vrm_); + li_->addIntervalsForSpills(*i->first, loopInfo, *vrm_, SSWeight); + addStackInterval(i->first, ls_, li_, SSWeight, *vrm_); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(reg); }