Second half of the fix for Transforms/Inline/inline_cleanup.ll
authorChris Lattner <sabre@nondot.org>
Wed, 13 Sep 2006 21:27:00 +0000 (21:27 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 13 Sep 2006 21:27:00 +0000 (21:27 +0000)
This folds unconditional branches that are often produced by code
specialization.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30307 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/CloneFunction.cpp

index a7ef06d684f7524f4111a56bcc198dd87bc67119..f80b1530f89795b629ee09cf7a49d643583d53c9 100644 (file)
@@ -449,6 +449,32 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
       }
     }
   }
-}
-
+  
+  // Now that the inlined function body has been fully constructed, go through
+  // and zap unconditional fall-through branches.  This happen all the time when
+  // specializing code: code specialization turns conditional branches into
+  // uncond branches, and this code folds them.
+  Function::iterator I = cast<BasicBlock>(ValueMap[&OldFunc->getEntryBlock()]);
+  while (I != NewFunc->end()) {
+    BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
+    if (!BI || BI->isConditional()) { ++I; continue; }
+    
+    BasicBlock *Dest = BI->getSuccessor(0);
+    if (!Dest->getSinglePredecessor()) { ++I; continue; }
+    
+    // We know all single-entry PHI nodes in the inlined function have been
+    // removed, so we just need to splice the blocks.
+    BI->eraseFromParent();
+    
+    // Move all the instructions in the succ to the pred.
+    I->getInstList().splice(I->end(), Dest->getInstList());
+    
+    // Make all PHI nodes that referred to Dest now refer to I as their source.
+    Dest->replaceAllUsesWith(I);
 
+    // Remove the dest block.
+    Dest->eraseFromParent();
+    
+    // Do not increment I, iteratively merge all things this block branches to.
+  }
+}