diff options
author | Bob Wilson <bob.wilson@apple.com> | 2010-02-16 19:51:59 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2010-02-16 19:51:59 +0000 |
commit | 484d4a30c055eef3101d01a7a468db3413dd20d3 (patch) | |
tree | d3dbf1f999ddbf0f8516c6387d767c4c323f6f75 /lib/Transforms | |
parent | adb6f226714dcfae363f51b453c4590b0f42da5e (diff) | |
download | external_llvm-484d4a30c055eef3101d01a7a468db3413dd20d3.zip external_llvm-484d4a30c055eef3101d01a7a468db3413dd20d3.tar.gz external_llvm-484d4a30c055eef3101d01a7a468db3413dd20d3.tar.bz2 |
Split critical edges as needed for load PRE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96378 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index b3a8687..c144e16 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -674,6 +674,9 @@ namespace { ValueTable VN; DenseMap<BasicBlock*, ValueNumberScope*> localAvail; + // List of critical edges to be split between iterations. + SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit; + // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<DominatorTree>(); @@ -701,6 +704,7 @@ namespace { Value *lookupNumber(BasicBlock *BB, uint32_t num); void cleanupGlobalSets(); void verifyRemoved(const Instruction *I) const; + bool splitCriticalEdges(); }; char GVN::ID = 0; @@ -1583,10 +1587,15 @@ bool GVN::processNonLocalLoad(LoadInst *LI, continue; } PredLoads[Pred] = 0; - // We don't currently handle critical edges :( + if (Pred->getTerminator()->getNumSuccessors() != 1) { - DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF CRITICAL EDGE '" - << Pred->getName() << "': " << *LI << '\n'); + if (isa<IndirectBrInst>(Pred->getTerminator())) { + DEBUG(dbgs() << "COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '" + << Pred->getName() << "': " << *LI << '\n'); + return false; + } + unsigned SuccNum = SuccessorNumber(Pred, LoadBB); + toSplit.push_back(std::make_pair(Pred->getTerminator(), SuccNum)); return false; } } @@ -2004,6 +2013,8 @@ bool GVN::runOnFunction(Function& F) { while (ShouldContinue) { DEBUG(dbgs() << "GVN iteration: " << Iteration << "\n"); ShouldContinue = iterateOnFunction(F); + if (splitCriticalEdges()) + ShouldContinue = true; Changed |= ShouldContinue; ++Iteration; } @@ -2070,7 +2081,6 @@ bool GVN::processBlock(BasicBlock *BB) { /// control flow patterns and attempts to perform simple PRE at the join point. bool GVN::performPRE(Function &F) { bool Changed = false; - SmallVector<std::pair<TerminatorInst*, unsigned>, 4> toSplit; DenseMap<BasicBlock*, Value*> predMap; for (df_iterator<BasicBlock*> DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) { @@ -2209,11 +2219,23 @@ bool GVN::performPRE(Function &F) { } } - for (SmallVector<std::pair<TerminatorInst*, unsigned>, 4>::iterator - I = toSplit.begin(), E = toSplit.end(); I != E; ++I) - SplitCriticalEdge(I->first, I->second, this); + if (splitCriticalEdges()) + Changed = true; + + return Changed; +} - return Changed || toSplit.size(); +/// splitCriticalEdges - Split critical edges found during the previous +/// iteration that may enable further optimization. +bool GVN::splitCriticalEdges() { + if (toSplit.empty()) + return false; + do { + std::pair<TerminatorInst*, unsigned> Edge = toSplit.pop_back_val(); + SplitCriticalEdge(Edge.first, Edge.second, this); + } while (!toSplit.empty()); + MD->invalidateCachedPredecessors(); + return true; } /// iterateOnFunction - Executes one iteration of GVN |