diff options
author | Devang Patel <dpatel@apple.com> | 2007-07-06 21:39:20 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2007-07-06 21:39:20 +0000 |
commit | 8019893c3f55a4bfe770888fe285d6dae57cf216 (patch) | |
tree | 310b76c94207eac8f7be00a67e89b55048e442f3 /lib/Transforms/Utils/BasicBlockUtils.cpp | |
parent | ec5614b522509d91d4c1f1d2a27ac8537f1886fb (diff) | |
download | external_llvm-8019893c3f55a4bfe770888fe285d6dae57cf216.zip external_llvm-8019893c3f55a4bfe770888fe285d6dae57cf216.tar.gz external_llvm-8019893c3f55a4bfe770888fe285d6dae57cf216.tar.bz2 |
Add SplitEdge and SplitBlock utility routines.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37952 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/BasicBlockUtils.cpp')
-rw-r--r-- | lib/Transforms/Utils/BasicBlockUtils.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index f9bcd39..520cfeb 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -17,6 +17,8 @@ #include "llvm/Instructions.h" #include "llvm/Constant.h" #include "llvm/Type.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/Dominators.h" #include <algorithm> using namespace llvm; @@ -112,3 +114,62 @@ void llvm::RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum) { ReplaceInstWithInst(TI, NewTI); } +/// SplitEdge - Split the edge connecting specified block. Pass P must +/// not be NULL. +BasicBlock *llvm::SplitEdge(BasicBlock *BB, BasicBlock *Succ, Pass *P) { + TerminatorInst *LatchTerm = BB->getTerminator(); + unsigned SuccNum = 0; + for (unsigned i = 0, e = LatchTerm->getNumSuccessors(); ; ++i) { + assert(i != e && "Didn't find edge?"); + if (LatchTerm->getSuccessor(i) == Succ) { + SuccNum = i; + break; + } + } + + // If this is a critical edge, let SplitCriticalEdge do it. + if (SplitCriticalEdge(BB->getTerminator(), SuccNum, P)) + return LatchTerm->getSuccessor(SuccNum); + + // If the edge isn't critical, then BB has a single successor or Succ has a + // single pred. Split the block. + BasicBlock::iterator SplitPoint; + if (BasicBlock *SP = Succ->getSinglePredecessor()) { + // If the successor only has a single pred, split the top of the successor + // block. + assert(SP == BB && "CFG broken"); + return SplitBlock(Succ, Succ->begin(), P); + } else { + // Otherwise, if BB has a single successor, split it at the bottom of the + // block. + assert(BB->getTerminator()->getNumSuccessors() == 1 && + "Should have a single succ!"); + return SplitBlock(BB, BB->getTerminator(), P); + } +} + +/// SplitBlock - Split the specified block at the specified instruction - every +/// thing before SplitPt stays in Old and everything starting with SplitPt moves +/// to a new block. The two blocks are joined by an unconditional branch and +/// the loop info is updated. +/// +BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) { + + LoopInfo &LI = P->getAnalysis<LoopInfo>(); + BasicBlock::iterator SplitIt = SplitPt; + while (isa<PHINode>(SplitIt)) + ++SplitIt; + BasicBlock *New = Old->splitBasicBlock(SplitIt, Old->getName()+".split"); + + // The new block lives in whichever loop the old one did. + if (Loop *L = LI.getLoopFor(Old)) + L->addBasicBlockToLoop(New, LI); + + if (DominatorTree *DT = P->getAnalysisToUpdate<DominatorTree>()) + DT->addNewBlock(New, Old); + + if (DominanceFrontier *DF = P->getAnalysisToUpdate<DominanceFrontier>()) + DF->splitBlock(Old); + + return New; +} |