From 484d4a30c055eef3101d01a7a468db3413dd20d3 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 16 Feb 2010 19:51:59 +0000 Subject: 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 --- lib/Transforms/Scalar/GVN.cpp | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'lib/Transforms') 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 localAvail; + // List of critical edges to be split between iterations. + SmallVector, 4> toSplit; + // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -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(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, 4> toSplit; DenseMap predMap; for (df_iterator DI = df_begin(&F.getEntryBlock()), DE = df_end(&F.getEntryBlock()); DI != DE; ++DI) { @@ -2209,11 +2219,23 @@ bool GVN::performPRE(Function &F) { } } - for (SmallVector, 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 Edge = toSplit.pop_back_val(); + SplitCriticalEdge(Edge.first, Edge.second, this); + } while (!toSplit.empty()); + MD->invalidateCachedPredecessors(); + return true; } /// iterateOnFunction - Executes one iteration of GVN -- cgit v1.1