[llvm-commits] [llvm] r138014 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h lib/Transforms/Utils/BasicBlockUtils.cpp

Bill Wendling isanbard at gmail.com
Thu Aug 18 17:05:40 PDT 2011


Author: void
Date: Thu Aug 18 19:05:40 2011
New Revision: 138014

URL: http://llvm.org/viewvc/llvm-project?rev=138014&view=rev
Log:
Add SplitLandingPadPredecessors().

SplitLandingPadPredecessors is similar to SplitBlockPredecessors in that it
splits the current block and attaches a set of predecessors to the new basic
block. However, it differs from SplitBlockPredecessors in that it's specifically
designed to handle landing pad blocks.

Two new basic blocks are created: one that is has the vector of predecessors as
its predecessors and one that has the remaining predecessors as its
predecessors. Those two new blocks then receive a cloned copy of the landingpad
instruction from the original block. The landingpad instructions are joined in a
PHI, etc. Like SplitBlockPredecessors, it updates the LLVM IR, AliasAnalysis,
DominatorTree, DominanceFrontier, LoopInfo, and LCCSA analyses.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
    llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp

Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=138014&r1=138013&r2=138014&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Thu Aug 18 19:05:40 2011
@@ -174,6 +174,23 @@
                                    unsigned NumPreds, const char *Suffix,
                                    Pass *P = 0);
 
+/// SplitLandingPadPredecessors - This method transforms the landing pad,
+/// OrigBB, by introducing two new basic blocks into the function. One of those
+/// new basic blocks gets the predecessors listed in Preds. The other basic
+/// block gets the remaining predecessors of OrigBB. The landingpad instruction
+/// OrigBB is clone into both of the new basic blocks. The new blocks are given
+/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector.
+/// 
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular,
+/// it does not preserve LoopSimplify (because it's complicated to handle the
+/// case where one of the edges being split is an exit of a loop with other
+/// exits).
+/// 
+void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef<BasicBlock*> Preds,
+                                 const char *Suffix, const char *Suffix2,
+                                 Pass *P, SmallVectorImpl<BasicBlock*> &NewBBs);
+
 /// FoldReturnIntoUncondBranch - This method duplicates the specified return
 /// instruction into a predecessor which ends in an unconditional branch. If
 /// the return instruction returns a value defined by a PHI, propagate the

Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=138014&r1=138013&r2=138014&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Thu Aug 18 19:05:40 2011
@@ -323,16 +323,17 @@
 
   LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>();
   Loop *L = LI ? LI->getLoopFor(OldBB) : 0;
-  bool PreserveLCSSA = P->mustPreserveAnalysisID(LCSSAID);
 
   // If we need to preserve loop analyses, collect some information about how
   // this split will affect loops.
   bool IsLoopEntry = !!L;
   bool SplitMakesNewLoopHeader = false;
   if (LI) {
+    bool PreserveLCSSA = P->mustPreserveAnalysisID(LCSSAID);
     for (ArrayRef<BasicBlock*>::iterator
            i = Preds.begin(), e = Preds.end(); i != e; ++i) {
       BasicBlock *Pred = *i;
+
       // If we need to preserve LCSSA, determine if any of the preds is a loop
       // exit.
       if (PreserveLCSSA)
@@ -493,6 +494,99 @@
   return NewBB;
 }
 
+/// SplitLandingPadPredecessors - This method transforms the landing pad,
+/// OrigBB, by introducing two new basic blocks into the function. One of those
+/// new basic blocks gets the predecessors listed in Preds. The other basic
+/// block gets the remaining predecessors of OrigBB. The landingpad instruction
+/// OrigBB is clone into both of the new basic blocks. The new blocks are given
+/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector.
+/// 
+/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree,
+/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular,
+/// it does not preserve LoopSimplify (because it's complicated to handle the
+/// case where one of the edges being split is an exit of a loop with other
+/// exits).
+/// 
+void llvm::SplitLandingPadPredecessors(BasicBlock *OrigBB,
+                                       ArrayRef<BasicBlock*> Preds,
+                                       const char *Suffix1, const char *Suffix2,
+                                       Pass *P,
+                                       SmallVectorImpl<BasicBlock*> &NewBBs) {
+  assert(OrigBB->isLandingPad() && "Trying to split a non-landing pad!");
+
+  // Create a new basic block for OrigBB's predecessors listed in Preds. Insert
+  // it right before the original block.
+  BasicBlock *NewBB1 = BasicBlock::Create(OrigBB->getContext(),
+                                          OrigBB->getName() + Suffix1,
+                                          OrigBB->getParent(), OrigBB);
+  NewBBs.push_back(NewBB1);
+
+  // The new block unconditionally branches to the old block.
+  BranchInst *BI1 = BranchInst::Create(OrigBB, NewBB1);
+
+  // Move the edges from Preds to point to NewBB1 instead of OrigBB.
+  for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
+    // This is slightly more strict than necessary; the minimum requirement
+    // is that there be no more than one indirectbr branching to BB. And
+    // all BlockAddress uses would need to be updated.
+    assert(!isa<IndirectBrInst>(Preds[i]->getTerminator()) &&
+           "Cannot split an edge from an IndirectBrInst");
+    Preds[i]->getTerminator()->replaceUsesOfWith(OrigBB, NewBB1);
+  }
+
+  // Update DominatorTree, LoopInfo, and LCCSA analysis information.
+  bool HasLoopExit = false;
+  UpdateAnalysisInformation(OrigBB, NewBB1, Preds, P, HasLoopExit);
+
+  // Update the PHI nodes in OrigBB with the values coming from NewBB1.
+  UpdatePHINodes(OrigBB, NewBB1, Preds, BI1, P, HasLoopExit);
+
+  // Create another basic block for the rest of OrigBB's predecessors.
+  BasicBlock *NewBB2 = BasicBlock::Create(OrigBB->getContext(),
+                                          OrigBB->getName() + Suffix2,
+                                          OrigBB->getParent(), OrigBB);
+  NewBBs.push_back(NewBB2);
+
+  // The new block unconditionally branches to the old block.
+  BranchInst *BI2 = BranchInst::Create(OrigBB, NewBB2);
+
+  // Move the remaining edges from OrigBB to point to NewBB2.
+  SmallVector<BasicBlock*, 8> NewBB2Preds;
+  for (pred_iterator i = pred_begin(OrigBB), e = pred_end(OrigBB);
+       i != e; ) {
+    BasicBlock *Pred = *i++;
+    if (Pred == NewBB1 || Pred == NewBB2 ) continue;
+    assert(!isa<IndirectBrInst>(Pred->getTerminator()) &&
+           "Cannot split an edge from an IndirectBrInst");
+    Pred->getTerminator()->replaceUsesOfWith(OrigBB, NewBB2);
+    NewBB2Preds.push_back(Pred);
+    e = pred_end(OrigBB);
+  }
+
+  // Update DominatorTree, LoopInfo, and LCCSA analysis information.
+  HasLoopExit = false;
+  UpdateAnalysisInformation(OrigBB, NewBB2, NewBB2Preds, P, HasLoopExit);
+
+  // Update the PHI nodes in OrigBB with the values coming from NewBB2.
+  UpdatePHINodes(OrigBB, NewBB2, NewBB2Preds, BI2, P, HasLoopExit);
+
+  LandingPadInst *LPad = OrigBB->getLandingPadInst();
+  Instruction *Clone1 = LPad->clone();
+  Clone1->setName(Twine("lpad") + Suffix1);
+  NewBB1->getInstList().insert(NewBB1->getFirstInsertionPt(), Clone1);
+
+  Instruction *Clone2 = LPad->clone();
+  Clone2->setName(Twine("lpad") + Suffix2);
+  NewBB2->getInstList().insert(NewBB2->getFirstInsertionPt(), Clone2);
+
+  // Create a PHI node for the two cloned landingpad instructions.
+  PHINode *PN = PHINode::Create(LPad->getType(), 2, "lpad.phi", LPad);
+  PN->addIncoming(Clone1, NewBB1);
+  PN->addIncoming(Clone2, NewBB2);
+  LPad->replaceAllUsesWith(PN);
+  LPad->eraseFromParent();
+}
+
 /// FindFunctionBackedges - Analyze the specified function to find all of the
 /// loop backedges in the function and return them.  This is a relatively cheap
 /// (compared to computing dominators and loop info) analysis.





More information about the llvm-commits mailing list