OSDN Git Service

Don't optimize the landing pad exit block.
authorBill Wendling <isanbard@gmail.com>
Wed, 17 Aug 2011 21:20:43 +0000 (21:20 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 17 Aug 2011 21:20:43 +0000 (21:20 +0000)
One way to exit the loop is through an unwind edge. However, that may involve
splitting the critical edge of the landing pad, which is non-trivial. Prevent
the transformation from rewriting the landing pad exit loop block.

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

lib/Transforms/Utils/LoopSimplify.cpp

index 6a99769..b019684 100644 (file)
@@ -398,6 +398,9 @@ BasicBlock *LoopSimplify::InsertPreheaderForLoop(Loop *L) {
 /// blocks.  This method is used to split exit blocks that have predecessors
 /// outside of the loop.
 BasicBlock *LoopSimplify::RewriteLoopExitBlock(Loop *L, BasicBlock *Exit) {
+  // Don't split a landing pad block.
+  if (Exit->isLandingPad()) return 0;
+
   SmallVector<BasicBlock*, 8> LoopBlocks;
   for (pred_iterator I = pred_begin(Exit), E = pred_end(Exit); I != E; ++I) {
     BasicBlock *P = *I;
@@ -746,18 +749,29 @@ void LoopSimplify::verifyAnalysis() const {
     (void)HasIndBrPred;
   }
 
-  // Indirectbr can interfere with exit block canonicalization.
+  // Indirectbr and LandingPad can interfere with exit block canonicalization.
   if (!L->hasDedicatedExits()) {
     bool HasIndBrExiting = false;
+    bool HasLPadExiting = false;
     SmallVector<BasicBlock*, 8> ExitingBlocks;
     L->getExitingBlocks(ExitingBlocks);
-    for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i)
+    for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) {
       if (isa<IndirectBrInst>((ExitingBlocks[i])->getTerminator())) {
         HasIndBrExiting = true;
         break;
       }
-    assert(HasIndBrExiting &&
+      if (const InvokeInst *II =
+          dyn_cast<InvokeInst>(ExitingBlocks[i]->getTerminator())) {
+        if (L->contains(II->getNormalDest()) &&
+            !L->contains(II->getUnwindDest())) {
+          HasLPadExiting = true;
+          break;
+        }
+      }
+    }
+
+    assert((HasIndBrExiting || HasLPadExiting) &&
            "LoopSimplify has no excuse for missing exit block info!");
-    (void)HasIndBrExiting;
+    (void)HasIndBrExiting; (void)HasLPadExiting;
   }
 }