From 32c181c4442db7eb326cebbe1c7d8b7bbd94132e Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 12 Aug 2010 23:02:55 +0000 Subject: [PATCH] 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. llvm-svn: 110975 --- llvm/lib/CodeGen/SplitKit.cpp | 45 ++++++++++++++++++++++++++++------- llvm/lib/CodeGen/SplitKit.h | 10 +++++--- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index a45e7bf3eb89..1753c2ef86f9 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -70,7 +70,7 @@ void SplitAnalysis::analyzeUses() { if (usingBlocks_[MBB]++) continue; if (MachineLoop *Loop = loops_.getLoopFor(MBB)) - usingLoops_.insert(Loop); + usingLoops_[Loop]++; } DEBUG(dbgs() << " counted " << usingInstrs_.size() << " instrs, " @@ -78,6 +78,34 @@ void SplitAnalysis::analyzeUses() { << 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) { @@ -219,13 +247,14 @@ const MachineLoop *SplitAnalysis::getBestSplitLoop() { // 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; } @@ -238,21 +267,21 @@ const MachineLoop *SplitAnalysis::getBestSplitLoop() { 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() << " + " diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index 663626e72995..08f7c56b4708 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -45,9 +45,9 @@ public: typedef DenseMap BlockCountMap; BlockCountMap usingBlocks_; - // Loops where the curent interval is used. - typedef SmallPtrSet LoopPtrSet; - LoopPtrSet usingLoops_; + // The number of basic block using curli in each loop. + typedef DenseMap LoopCountMap; + LoopCountMap usingLoops_; private: // Current live interval. @@ -68,6 +68,9 @@ public: /// 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 @@ -75,6 +78,7 @@ public: void clear(); typedef SmallPtrSet BlockPtrSet; + typedef SmallPtrSet LoopPtrSet; // Sets of basic blocks surrounding a machine loop. struct LoopBlocks {