Refine stack slot interval weight computation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2008-06-06 07:54:39 +00:00
parent b0a882f540
commit 9c3c221364
3 changed files with 64 additions and 27 deletions

View File

@ -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<LiveInterval*>
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<int, 4> &ReMatIds, const MachineLoopInfo *loopInfo,
unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
std::map<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs);
std::vector<LiveInterval*> &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<unsigned,std::vector<SRInfo> > &RestoreIdxes,
std::map<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs);
std::vector<LiveInterval*> &NewLIs, float &SSWeight);
static LiveInterval createInterval(unsigned Reg);

View File

@ -972,7 +972,9 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
const MachineLoopInfo *loopInfo,
unsigned &NewVReg, unsigned ImpUse, bool &HasDef, bool &HasUse,
std::map<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs) {
std::vector<LiveInterval*> &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<unsigned, std::vector<SRInfo> > &RestoreIdxes,
std::map<unsigned,unsigned> &MBBVRegsMap,
std::vector<LiveInterval*> &NewLIs) {
std::vector<LiveInterval*> &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<LiveInterval*> 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<LiveVariables>();
@ -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<unsigned, std::vector<SRInfo> > 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<SRInfo> &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<SRInfo> &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);
}

View File

@ -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<LiveInterval*> 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<LiveInterval*> 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<LiveInterval*> 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);
}