From c0d025f54f96ff719ae99d57d7c413aee35b6cbc Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sun, 9 Mar 2008 04:55:16 +0000 Subject: [PATCH] Prune the unwind_to labels on BBs that don't need them. Another step in the removal of invoke, PR1269. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48084 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/PruneEH.cpp | 19 ++++++++++++++++--- test/Transforms/PruneEH/unwindto.ll | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 test/Transforms/PruneEH/unwindto.ll diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp index 4e621dc2f93..fa8b95a2ade 100644 --- a/lib/Transforms/IPO/PruneEH.cpp +++ b/lib/Transforms/IPO/PruneEH.cpp @@ -32,6 +32,7 @@ using namespace llvm; STATISTIC(NumRemoved, "Number of invokes removed"); STATISTIC(NumUnreach, "Number of noreturn calls optimized"); +STATISTIC(NumBBUnwind, "Number of unwind_to removed from blocks"); namespace { struct VISIBILITY_HIDDEN PruneEH : public CallGraphSCCPass { @@ -153,6 +154,8 @@ bool PruneEH::runOnSCC(const std::vector &SCC) { bool PruneEH::SimplifyFunction(Function *F) { bool MadeChange = false; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + bool couldUnwind = false; + if (InvokeInst *II = dyn_cast(BB->getTerminator())) if (II->doesNotThrow()) { SmallVector Args(II->op_begin()+3, II->op_end()); @@ -182,10 +185,11 @@ bool PruneEH::SimplifyFunction(Function *F) { ++NumRemoved; MadeChange = true; - } + } else + couldUnwind = true; for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) - if (CallInst *CI = dyn_cast(I++)) + if (CallInst *CI = dyn_cast(I++)) { if (CI->doesNotReturn() && !isa(I)) { // This call calls a function that cannot return. Insert an // unreachable instruction after it and simplify the code. Do this @@ -201,8 +205,17 @@ bool PruneEH::SimplifyFunction(Function *F) { MadeChange = true; ++NumUnreach; break; - } + } else if (!CI->doesNotThrow()) + couldUnwind = true; + } + // Strip 'unwindTo' off of BBs that have no calls/invokes without nounwind. + if (!couldUnwind && BB->getUnwindDest()) { + MadeChange = true; + ++NumBBUnwind; + BB->getUnwindDest()->removePredecessor(BB, false, true); + BB->setUnwindDest(NULL); + } } return MadeChange; } diff --git a/test/Transforms/PruneEH/unwindto.ll b/test/Transforms/PruneEH/unwindto.ll new file mode 100644 index 00000000000..8e5ac25ec86 --- /dev/null +++ b/test/Transforms/PruneEH/unwindto.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -prune-eh | llvm-dis | not grep unwind_to + +define i8 @test7(i1 %b) { +entry: unwind_to %cleanup + br i1 %b, label %cond_true, label %cond_false +cond_true: unwind_to %cleanup + br label %cleanup +cond_false: unwind_to %cleanup + br label %cleanup +cleanup: + %x = phi i8 [0, %entry], [1, %cond_true], [1, %cond_true], + [2, %cond_false], [2, %cond_false] + ret i8 %x +} + -- 2.11.0