summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-08-24 18:36:16 +0000
committerChris Lattner <sabre@nondot.org>2003-08-24 18:36:16 +0000
commitdc3602bf0d27aac80e08ef8823967850acd05a14 (patch)
tree9c8a8a0de05da7ea63187b45c36f2ca039fd3f1b /lib/Transforms
parentcd98c72561fde5f9cad0910c3a24318a02d3ba87 (diff)
downloadllvm-dc3602bf0d27aac80e08ef8823967850acd05a14.tar.gz
llvm-dc3602bf0d27aac80e08ef8823967850acd05a14.tar.bz2
llvm-dc3602bf0d27aac80e08ef8823967850acd05a14.tar.xz
Implement SimplifyCFG/InvokeEliminate.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8126 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index ed0d45be26..f47c840518 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -6,7 +6,10 @@
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constant.h"
+#include "llvm/Intrinsics.h"
#include "llvm/iPHINode.h"
+#include "llvm/iTerminators.h"
+#include "llvm/iOther.h"
#include "llvm/Support/CFG.h"
#include <algorithm>
#include <functional>
@@ -87,12 +90,44 @@ static bool PropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
// WARNING: The entry node of a function may not be simplified.
//
bool SimplifyCFG(BasicBlock *BB) {
+ bool Changed = false;
Function *M = BB->getParent();
assert(BB && BB->getParent() && "Block not embedded in function!");
assert(BB->getTerminator() && "Degenerate basic block encountered!");
assert(&BB->getParent()->front() != BB && "Can't Simplify entry block!");
+ // Check to see if the first instruction in this block is just an
+ // 'llvm.unwind'. If so, replace any invoke instructions which use this as an
+ // exception destination with call instructions.
+ //
+ if (CallInst *CI = dyn_cast<CallInst>(&BB->front()))
+ if (Function *F = CI->getCalledFunction())
+ if (F->getIntrinsicID() == LLVMIntrinsic::unwind) {
+ std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB));
+ while (!Preds.empty()) {
+ BasicBlock *Pred = Preds.back();
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
+ if (II->getExceptionalDest() == BB) {
+ // Insert a new branch instruction before the invoke, because this
+ // is now a fall through...
+ BranchInst *BI = new BranchInst(II->getNormalDest(), II);
+ Pred->getInstList().remove(II); // Take out of symbol table
+
+ // Insert the call now...
+ std::vector<Value*> Args(II->op_begin()+3, II->op_end());
+ CallInst *CI = new CallInst(II->getCalledValue(), Args,
+ II->getName(), BI);
+ // If the invoke produced a value, the Call now does instead
+ II->replaceAllUsesWith(CI);
+ delete II;
+ Changed = true;
+ }
+
+ Preds.pop_back();
+ }
+ }
+
// Remove basic blocks that have no predecessors... which are unreachable.
if (pred_begin(BB) == pred_end(BB) &&
!BB->hasConstantReferences()) {
@@ -123,7 +158,7 @@ bool SimplifyCFG(BasicBlock *BB) {
// Check to see if we can constant propagate this terminator instruction
// away...
- bool Changed = ConstantFoldTerminator(BB);
+ Changed |= ConstantFoldTerminator(BB);
// Check to see if this block has no non-phi instructions and only a single
// successor. If so, replace references to this basic block with references