if (usingBlocks_[MBB]++)
continue;
if (MachineLoop *Loop = loops_.getLoopFor(MBB))
- usingLoops_.insert(Loop);
+ usingLoops_[Loop]++;
}
DEBUG(dbgs() << " counted "
<< usingInstrs_.size() << " instrs, "
<< 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,
// predecessor blocks, and exit blocks.
void SplitAnalysis::getLoopBlocks(const MachineLoop *Loop, LoopBlocks &Blocks) {
// Find first-class and second class candidate loops.
// 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) {
- getLoopBlocks(*I, Blocks);
+ const MachineLoop *Loop = I->first;
+ getLoopBlocks(Loop, Blocks);
// FIXME: We need an SSA updater to properly handle multiple exit blocks.
if (Blocks.Exits.size() > 1) {
- DEBUG(dbgs() << " multiple exits from " << **I);
+ DEBUG(dbgs() << " multiple exits from " << *Loop);
continue;
}
LPS = &SecondLoops;
break;
case ContainedInLoop:
- DEBUG(dbgs() << " contained in " << **I);
+ DEBUG(dbgs() << " contained in " << *Loop);
continue;
case SinglePeripheral:
- DEBUG(dbgs() << " single peripheral use in " << **I);
+ DEBUG(dbgs() << " single peripheral use in " << *Loop);
continue;
}
// Will it be possible to split around this loop?
getCriticalExits(Blocks, CriticalExits);
DEBUG(dbgs() << " " << CriticalExits.size() << " critical exits from "
- << **I);
+ << *Loop);
if (!canSplitCriticalExits(Blocks, CriticalExits))
continue;
// This is a possible split.
assert(LPS);
- LPS->insert(*I);
+ LPS->insert(Loop);
}
DEBUG(dbgs() << " getBestSplitLoop found " << Loops.size() << " + "
typedef DenseMap<const MachineBasicBlock*, unsigned> BlockCountMap;
BlockCountMap usingBlocks_;
- // Loops where the curent interval is used.
- typedef SmallPtrSet<const MachineLoop*, 16> LoopPtrSet;
- LoopPtrSet usingLoops_;
+ // The number of basic block using curli in each loop.
+ typedef DenseMap<const MachineLoop*, unsigned> LoopCountMap;
+ LoopCountMap usingLoops_;
private:
// Current live interval.
/// split.
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_; }
/// clear - clear all data structures so SplitAnalysis is ready to analyze a
void clear();
typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
+ typedef SmallPtrSet<const MachineLoop*, 16> LoopPtrSet;
// Sets of basic blocks surrounding a machine loop.
struct LoopBlocks {