Add SplitKit::isOriginalEndpoint and use it to force live range splitting to terminate.

An original endpoint is an instruction that killed or defined the original live
range before any live ranges were split.

When splitting global live ranges, avoid creating local live ranges without any
original endpoints. We may still create global live ranges without original
endpoints, but such a range won't be split again, and live range splitting still
terminates.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126151 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-02-21 23:09:46 +00:00
parent 89e59e6343
commit 06c0f25499
3 changed files with 32 additions and 2 deletions

View File

@ -426,8 +426,13 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
if (!IntI.valid())
break;
// Not live in, but before the first use.
if (IntI.start() < BI.FirstUse)
if (IntI.start() < BI.FirstUse) {
BC.Entry = SpillPlacement::PrefSpill;
// If the block contains a kill from an earlier split, never split
// again in the same block.
if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Kill))
BC.Entry = SpillPlacement::MustSpill;
}
}
// Does interference overlap the uses in the entry segment
@ -458,8 +463,12 @@ float RAGreedy::calcInterferenceInfo(LiveInterval &VirtReg, unsigned PhysReg) {
IntI.advanceTo(BI.LastUse);
if (!IntI.valid())
break;
if (IntI.start() < Stop)
if (IntI.start() < Stop) {
BC.Exit = SpillPlacement::PrefSpill;
// Avoid splitting twice in the same block.
if (!BI.LiveThrough && !SA->isOriginalEndpoint(BI.Def))
BC.Exit = SpillPlacement::MustSpill;
}
}
}
}

View File

@ -167,6 +167,20 @@ void SplitAnalysis::calcLiveBlockInfo() {
}
}
bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
unsigned OrigReg = VRM.getOriginal(CurLI->reg);
const LiveInterval &Orig = LIS.getInterval(OrigReg);
assert(!Orig.empty() && "Splitting empty interval?");
LiveInterval::const_iterator I = Orig.find(Idx);
// Range containing Idx should begin at Idx.
if (I != Orig.end() && I->start <= Idx)
return I->start == Idx;
// Range does not contain Idx, previous must end at Idx.
return I != Orig.begin() && (--I)->end == Idx;
}
void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const {
for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) {
unsigned count = UsingBlocks.lookup(*I);

View File

@ -125,6 +125,13 @@ public:
return UsingBlocks.lookup(MBB);
}
/// isOriginalEndpoint - Return true if the original live range was killed or
/// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def,
/// and 'use' for an early-clobber def.
/// This can be used to recognize code inserted by earlier live range
/// splitting.
bool isOriginalEndpoint(SlotIndex Idx) const;
typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
// Print a set of blocks with use counts.