mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
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:
parent
b0a882f540
commit
9c3c221364
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user