Update the SplitAnalysis statistics as uses are moved from curli to the new

split intervals. THis means the analysis can be used for multiple splits as long
as curli doesn't shrink.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110975 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2010-08-12 23:02:55 +00:00
parent 1522ce9770
commit 2dee7a527b
2 changed files with 44 additions and 11 deletions

View File

@@ -70,7 +70,7 @@ void SplitAnalysis::analyzeUses() {
if (usingBlocks_[MBB]++) if (usingBlocks_[MBB]++)
continue; continue;
if (MachineLoop *Loop = loops_.getLoopFor(MBB)) if (MachineLoop *Loop = loops_.getLoopFor(MBB))
usingLoops_.insert(Loop); usingLoops_[Loop]++;
} }
DEBUG(dbgs() << " counted " DEBUG(dbgs() << " counted "
<< usingInstrs_.size() << " instrs, " << usingInstrs_.size() << " instrs, "
@@ -78,6 +78,34 @@ void SplitAnalysis::analyzeUses() {
<< usingLoops_.size() << " loops.\n"); << usingLoops_.size() << " loops.\n");
} }
/// removeUse - Update statistics by noting that MI no longer uses curli.
void SplitAnalysis::removeUse(const MachineInstr *MI) {
if (!usingInstrs_.erase(MI))
return;
// Decrement MBB count.
const MachineBasicBlock *MBB = MI->getParent();
BlockCountMap::iterator bi = usingBlocks_.find(MBB);
assert(bi != usingBlocks_.end() && "MBB missing");
assert(bi->second && "0 count in map");
if (--bi->second)
return;
// No more uses in MBB.
usingBlocks_.erase(bi);
// Decrement loop count.
MachineLoop *Loop = loops_.getLoopFor(MBB);
if (!Loop)
return;
LoopCountMap::iterator li = usingLoops_.find(Loop);
assert(li != usingLoops_.end() && "Loop missing");
assert(li->second && "0 count in map");
if (--li->second)
return;
// No more blocks in Loop.
usingLoops_.erase(li);
}
// Get three sets of basic blocks surrounding a loop: Blocks inside the loop, // Get three sets of basic blocks surrounding a loop: Blocks inside the loop,
// predecessor blocks, and exit blocks. // predecessor blocks, and exit blocks.
void SplitAnalysis::getLoopBlocks(const MachineLoop *Loop, LoopBlocks &Blocks) { void SplitAnalysis::getLoopBlocks(const MachineLoop *Loop, LoopBlocks &Blocks) {
@@ -219,13 +247,14 @@ const MachineLoop *SplitAnalysis::getBestSplitLoop() {
// Find first-class and second class candidate loops. // Find first-class and second class candidate loops.
// We prefer to split around loops where curli is used outside the periphery. // We prefer to split around loops where curli is used outside the periphery.
for (LoopPtrSet::const_iterator I = usingLoops_.begin(), for (LoopCountMap::const_iterator I = usingLoops_.begin(),
E = usingLoops_.end(); I != E; ++I) { E = usingLoops_.end(); I != E; ++I) {
getLoopBlocks(*I, Blocks); const MachineLoop *Loop = I->first;
getLoopBlocks(Loop, Blocks);
// FIXME: We need an SSA updater to properly handle multiple exit blocks. // FIXME: We need an SSA updater to properly handle multiple exit blocks.
if (Blocks.Exits.size() > 1) { if (Blocks.Exits.size() > 1) {
DEBUG(dbgs() << " multiple exits from " << **I); DEBUG(dbgs() << " multiple exits from " << *Loop);
continue; continue;
} }
@@ -238,21 +267,21 @@ const MachineLoop *SplitAnalysis::getBestSplitLoop() {
LPS = &SecondLoops; LPS = &SecondLoops;
break; break;
case ContainedInLoop: case ContainedInLoop:
DEBUG(dbgs() << " contained in " << **I); DEBUG(dbgs() << " contained in " << *Loop);
continue; continue;
case SinglePeripheral: case SinglePeripheral:
DEBUG(dbgs() << " single peripheral use in " << **I); DEBUG(dbgs() << " single peripheral use in " << *Loop);
continue; continue;
} }
// Will it be possible to split around this loop? // Will it be possible to split around this loop?
getCriticalExits(Blocks, CriticalExits); getCriticalExits(Blocks, CriticalExits);
DEBUG(dbgs() << " " << CriticalExits.size() << " critical exits from " DEBUG(dbgs() << " " << CriticalExits.size() << " critical exits from "
<< **I); << *Loop);
if (!canSplitCriticalExits(Blocks, CriticalExits)) if (!canSplitCriticalExits(Blocks, CriticalExits))
continue; continue;
// This is a possible split. // This is a possible split.
assert(LPS); assert(LPS);
LPS->insert(*I); LPS->insert(Loop);
} }
DEBUG(dbgs() << " getBestSplitLoop found " << Loops.size() << " + " DEBUG(dbgs() << " getBestSplitLoop found " << Loops.size() << " + "

View File

@@ -45,9 +45,9 @@ public:
typedef DenseMap<const MachineBasicBlock*, unsigned> BlockCountMap; typedef DenseMap<const MachineBasicBlock*, unsigned> BlockCountMap;
BlockCountMap usingBlocks_; BlockCountMap usingBlocks_;
// Loops where the curent interval is used. // The number of basic block using curli in each loop.
typedef SmallPtrSet<const MachineLoop*, 16> LoopPtrSet; typedef DenseMap<const MachineLoop*, unsigned> LoopCountMap;
LoopPtrSet usingLoops_; LoopCountMap usingLoops_;
private: private:
// Current live interval. // Current live interval.
@@ -68,6 +68,9 @@ public:
/// split. /// split.
void analyze(const LiveInterval *li); void analyze(const LiveInterval *li);
/// removeUse - Update statistics by noting that mi no longer uses curli.
void removeUse(const MachineInstr *mi);
const LiveInterval *getCurLI() { return curli_; } const LiveInterval *getCurLI() { return curli_; }
/// clear - clear all data structures so SplitAnalysis is ready to analyze a /// clear - clear all data structures so SplitAnalysis is ready to analyze a
@@ -75,6 +78,7 @@ public:
void clear(); void clear();
typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet; typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
typedef SmallPtrSet<const MachineLoop*, 16> LoopPtrSet;
// Sets of basic blocks surrounding a machine loop. // Sets of basic blocks surrounding a machine loop.
struct LoopBlocks { struct LoopBlocks {