From ec7c1ab1dafa0fdb383d0e6df4726cecb4c88c70 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 16 Oct 2004 18:21:33 +0000 Subject: [PATCH] Add support for unreachable git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17056 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/PostDominators.cpp | 3 +-- lib/ExecutionEngine/Interpreter/Execution.cpp | 5 +++++ lib/ExecutionEngine/Interpreter/Interpreter.h | 1 + lib/Transforms/Utils/UnifyFunctionExitNodes.cpp | 26 ++++++++++++++++++++++--- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index 08822949c62..4f9d1d16069 100644 --- a/lib/Analysis/PostDominators.cpp +++ b/lib/Analysis/PostDominators.cpp @@ -40,8 +40,7 @@ bool PostDominatorSet::runOnFunction(Function &F) { for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { Doms[I]; // Initialize to empty - if (isa(I->getTerminator()) || - isa(I->getTerminator())) + if (succ_begin(I) == succ_end(I)) Roots.push_back(I); } diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 589ac7f99dc..8616656360f 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -616,6 +616,11 @@ void Interpreter::visitUnwindInst(UnwindInst &I) { SwitchToNewBasicBlock(cast(Inst)->getUnwindDest(), InvokingSF); } +void Interpreter::visitUnreachableInst(UnreachableInst &I) { + std::cerr << "ERROR: Program executed an 'unreachable' instruction!\n"; + abort(); +} + void Interpreter::visitBranchInst(BranchInst &I) { ExecutionContext &SF = ECStack.back(); BasicBlock *Dest; diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index d6e590d7357..e146135cf5f 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -145,6 +145,7 @@ public: void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); } void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); } void visitUnwindInst(UnwindInst &I); + void visitUnreachableInst(UnreachableInst &I); void visitShl(ShiftInst &I); void visitShr(ShiftInst &I); diff --git a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp index 5c87a5b1596..977616378d0 100644 --- a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp +++ b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp @@ -46,13 +46,16 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) { // std::vector ReturningBlocks; std::vector UnwindingBlocks; + std::vector UnreachableBlocks; for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I) if (isa(I->getTerminator())) ReturningBlocks.push_back(I); else if (isa(I->getTerminator())) UnwindingBlocks.push_back(I); + else if (isa(I->getTerminator())) + UnreachableBlocks.push_back(I); - // Handle unwinding blocks first... + // Handle unwinding blocks first. if (UnwindingBlocks.empty()) { UnwindBlock = 0; } else if (UnwindingBlocks.size() == 1) { @@ -64,12 +67,29 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) { for (std::vector::iterator I = UnwindingBlocks.begin(), E = UnwindingBlocks.end(); I != E; ++I) { BasicBlock *BB = *I; - BB->getInstList().pop_back(); // Remove the return insn + BB->getInstList().pop_back(); // Remove the unwind insn new BranchInst(UnwindBlock, BB); } } - // Now handle return blocks... + // Then unreachable blocks. + if (UnreachableBlocks.empty()) { + UnreachableBlock = 0; + } else if (UnreachableBlocks.size() == 1) { + UnreachableBlock = UnreachableBlocks.front(); + } else { + UnreachableBlock = new BasicBlock("UnifiedUnreachableBlock", &F); + new UnreachableInst(UnreachableBlock); + + for (std::vector::iterator I = UnreachableBlocks.begin(), + E = UnreachableBlocks.end(); I != E; ++I) { + BasicBlock *BB = *I; + BB->getInstList().pop_back(); // Remove the unreachable inst. + new BranchInst(UnreachableBlock, BB); + } + } + + // Now handle return blocks. if (ReturningBlocks.empty()) { ReturnBlock = 0; return false; // No blocks return -- 2.11.0