From 0906a7c46cfc71e7c09dd6362df4310e72fdbc6b Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 17 Aug 2011 21:20:43 +0000 Subject: Don't optimize the landing pad exit block. 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 | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'lib/Transforms/Utils/LoopSimplify.cpp') diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp index 6a9976930c..b019684021 100644 --- a/lib/Transforms/Utils/LoopSimplify.cpp +++ b/lib/Transforms/Utils/LoopSimplify.cpp @@ -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 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 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((ExitingBlocks[i])->getTerminator())) { HasIndBrExiting = true; break; } - assert(HasIndBrExiting && + if (const InvokeInst *II = + dyn_cast(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; } } -- cgit v1.2.3-18-g5258