Add RAGreedy::calcCompactRegion.

This method computes the edge bundles that should be live when splitting
around a compact region. This is independent of interference.

The function returns false if the live range was already a compact
region, or the compact region doesn't have any live bundles - it would
be the same as splitting around basic blocks.

Compact regions are computed using the normal spill placement code. We
pretend there is interference in all live-through blocks that don't use
the live range. This removes all edges from the Hopfield network used
for spill placement, so it converges instantly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135847 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-07-23 03:41:57 +00:00
parent fe9b2d142a
commit 87972fa63f

View File

@ -208,6 +208,7 @@ private:
void addThroughConstraints(InterferenceCache::Cursor, ArrayRef<unsigned>);
void growRegion(GlobalSplitCandidate &Cand);
float calcGlobalSplitCost(GlobalSplitCandidate&);
bool calcCompactRegion(GlobalSplitCandidate&);
void splitAroundRegion(LiveInterval&, GlobalSplitCandidate&,
SmallVectorImpl<LiveInterval*>&);
void calcGapWeights(unsigned, SmallVectorImpl<float>&);
@ -765,6 +766,51 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) {
DEBUG(dbgs() << ", v=" << Visited);
}
/// calcCompactRegion - Compute the set of edge bundles that should be live
/// when splitting the current live range into compact regions. Compact
/// regions can be computed without looking at interference. They are the
/// regions formed by removing all the live-through blocks from the live range.
///
/// Returns false if the current live range is already compact, or if the
/// compact regions would form single block regions anyway.
bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) {
// Without any through blocks, the live range is already compact.
if (!SA->getNumThroughBlocks())
return false;
// Compact regions don't correspond to any physreg.
Cand.reset(IntfCache, 0);
DEBUG(dbgs() << "Compact region bundles");
// Use the spill placer to determine the live bundles. GrowRegion pretends
// that all the through blocks have interference when PhysReg is unset.
SpillPlacer->prepare(Cand.LiveBundles);
// The static split cost will be zero since Cand.Intf reports no interference.
float Cost;
if (!addSplitConstraints(Cand.Intf, Cost)) {
DEBUG(dbgs() << ", none.\n");
return false;
}
growRegion(Cand);
SpillPlacer->finish();
if (!Cand.LiveBundles.any()) {
DEBUG(dbgs() << ", none.\n");
return false;
}
DEBUG({
for (int i = Cand.LiveBundles.find_first(); i>=0;
i = Cand.LiveBundles.find_next(i))
dbgs() << " EB#" << i;
dbgs() << ".\n";
});
return true;
}
/// calcSpillCost - Compute how expensive it would be to split the live range in
/// SA around all use blocks instead of forming bundle regions.
float RAGreedy::calcSpillCost() {