diff options
author | Owen Anderson <resistor@mac.com> | 2008-07-17 00:01:40 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2008-07-17 00:01:40 +0000 |
commit | b31b06d04b81c5383e2fba0cd44d4ba3f324a794 (patch) | |
tree | 550a9ec8e53cd9d7eac0538e6b2322fed375d56e /lib | |
parent | 413907000e6949849e4b9c2fabda7105f8bedabd (diff) | |
download | llvm-b31b06d04b81c5383e2fba0cd44d4ba3f324a794.tar.gz llvm-b31b06d04b81c5383e2fba0cd44d4ba3f324a794.tar.bz2 llvm-b31b06d04b81c5383e2fba0cd44d4ba3f324a794.tar.xz |
Factor MergeBlockIntoPredecessor out into BasicBlockUtils.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53705 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 55 | ||||
-rw-r--r-- | lib/Transforms/Utils/BasicBlockUtils.cpp | 52 |
2 files changed, 56 insertions, 51 deletions
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 986d755bad..b002380b74 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1125,7 +1125,10 @@ bool GVN::runOnFunction(Function& F) { for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ) { BasicBlock* BB = FI; ++FI; - changed |= mergeBlockIntoPredecessor(BB); + bool removedBlock = MergeBlockIntoPredecessor(BB, this); + if (removedBlock) NumGVNBlocks++; + + changed |= removedBlock; } while (shouldContinue) { @@ -1336,56 +1339,6 @@ bool GVN::performPRE(Function& F) { return changed; } -// mergeBlockIntoPredecessor - If this block is the only successor -// of its predecessor, and the edge is non-critical, -// fold it into that predecessor. -bool GVN::mergeBlockIntoPredecessor(BasicBlock* BB) { - // Can't merge the entry block. - if (pred_begin(BB) == pred_end(BB)) return false; - // Can't merge if there are multiple preds. - if (++pred_begin(BB) != pred_end(BB)) return false; - - BasicBlock* PredBB = *pred_begin(BB); - - // Can't merge if the edge is critical. - if (PredBB->getTerminator()->getNumSuccessors() != 1) return false; - - // Begin by getting rid of unneeded PHIs. - while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) { - PN->replaceAllUsesWith(PN->getIncomingValue(0)); - BB->getInstList().pop_front(); // Delete the phi node... - } - - // Delete the unconditional branch from the predecessor... - PredBB->getInstList().pop_back(); - - // Move all definitions in the successor to the predecessor... - PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); - - // Make all PHI nodes that referred to BB now refer to Pred as their - // source... - BB->replaceAllUsesWith(PredBB); - - // Finally, erase the old block and update dominator info. - DominatorTree& DT = getAnalysis<DominatorTree>(); - DomTreeNode* DTN = DT[BB]; - DomTreeNode* PredDTN = DT[PredBB]; - - if (DTN) { - SmallPtrSet<DomTreeNode*, 8> Children(DTN->begin(), DTN->end()); - for (SmallPtrSet<DomTreeNode*, 8>::iterator DI = Children.begin(), - DE = Children.end(); DI != DE; ++DI) - DT.changeImmediateDominator(*DI, PredDTN); - - DT.eraseNode(BB); - } - - BB->eraseFromParent(); - - NumGVNBlocks++; - return true; -} - // iterateOnFunction - Executes one iteration of GVN bool GVN::iterateOnFunction(Function &F) { // Clean out global sets from any previous functions diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index 93a8c8e593..02eb4d6f60 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -23,6 +23,58 @@ #include <algorithm> using namespace llvm; +/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor, +/// if possible. The return value indicates success or failure. +bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) { + // Can't merge the entry block. + if (pred_begin(BB) == pred_end(BB)) return false; + // Can't merge if there are multiple preds. + if (++pred_begin(BB) != pred_end(BB)) return false; + + BasicBlock* PredBB = *pred_begin(BB); + + // Can't merge if the edge is critical. + if (PredBB->getTerminator()->getNumSuccessors() != 1) return false; + + // Begin by getting rid of unneeded PHIs. + while (PHINode *PN = dyn_cast<PHINode>(&BB->front())) { + PN->replaceAllUsesWith(PN->getIncomingValue(0)); + BB->getInstList().pop_front(); // Delete the phi node... + } + + // Delete the unconditional branch from the predecessor... + PredBB->getInstList().pop_back(); + + // Move all definitions in the successor to the predecessor... + PredBB->getInstList().splice(PredBB->end(), BB->getInstList()); + + // Make all PHI nodes that referred to BB now refer to Pred as their + // source... + BB->replaceAllUsesWith(PredBB); + + // Finally, erase the old block and update dominator info. + if (P) { + if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) { + DomTreeNode* DTN = DT->getNode(BB); + DomTreeNode* PredDTN = DT->getNode(PredBB); + + if (DTN) { + SmallPtrSet<DomTreeNode*, 8> Children(DTN->begin(), DTN->end()); + for (SmallPtrSet<DomTreeNode*, 8>::iterator DI = Children.begin(), + DE = Children.end(); DI != DE; ++DI) + DT->changeImmediateDominator(*DI, PredDTN); + + DT->eraseNode(BB); + } + } + } + + BB->eraseFromParent(); + + + return true; +} + /// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI) /// with a value, then remove and delete the original instruction. /// |