blob: 3686fc01f6eb646ced341759857dfd4e4e44172a [file] [log] [blame]
Chris Lattner86e44452003-10-05 19:14:42 +00001//===- LowerInvoke.cpp - Eliminate Invoke & Unwind instructions -----------===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Chris Lattner86e44452003-10-05 19:14:42 +00009//
10// This transformation is designed for use by code generators which do not yet
11// support stack unwinding. This pass gives them the ability to execute any
12// program which does not throw an exception, by turning 'invoke' instructions
13// into calls and by turning 'unwind' instructions into calls to abort().
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/Transforms/Scalar.h"
18#include "llvm/Pass.h"
19#include "llvm/iTerminators.h"
20#include "llvm/iOther.h"
21#include "llvm/Module.h"
22#include "llvm/Type.h"
23#include "llvm/Constant.h"
24#include "Support/Statistic.h"
Chris Lattnerdead9932003-12-10 20:22:42 +000025using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000026
Chris Lattner86e44452003-10-05 19:14:42 +000027namespace {
28 Statistic<> NumLowered("lowerinvoke", "Number of invoke & unwinds replaced");
29
30 class LowerInvoke : public FunctionPass {
31 Function *AbortFn;
32 public:
33 bool doInitialization(Module &M);
34 bool runOnFunction(Function &F);
35 };
36
37 RegisterOpt<LowerInvoke>
38 X("lowerinvoke", "Lower invoke and unwind, for unwindless code generators");
39}
40
Brian Gaeked0fde302003-11-11 22:41:34 +000041// Public Interface To the LowerInvoke pass.
Chris Lattnerdead9932003-12-10 20:22:42 +000042FunctionPass *llvm::createLowerInvokePass() { return new LowerInvoke(); }
Chris Lattner86e44452003-10-05 19:14:42 +000043
44// doInitialization - Make sure that there is a prototype for abort in the
45// current module.
46bool LowerInvoke::doInitialization(Module &M) {
47 AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0);
48 return true;
49}
50
51bool LowerInvoke::runOnFunction(Function &F) {
52 bool Changed = false;
Chris Lattnerdead9932003-12-10 20:22:42 +000053 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
54 if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) {
Chris Lattner86e44452003-10-05 19:14:42 +000055 // Insert a normal call instruction...
56 std::string Name = II->getName(); II->setName("");
57 Value *NewCall = new CallInst(II->getCalledValue(),
58 std::vector<Value*>(II->op_begin()+3,
59 II->op_end()), Name,II);
60 II->replaceAllUsesWith(NewCall);
61
Chris Lattnerdead9932003-12-10 20:22:42 +000062 // Insert an unconditional branch to the normal destination.
Chris Lattner86e44452003-10-05 19:14:42 +000063 new BranchInst(II->getNormalDest(), II);
64
Chris Lattnerdead9932003-12-10 20:22:42 +000065 // Remove any PHI node entries from the exception destination.
66 II->getExceptionalDest()->removePredecessor(BB);
67
Chris Lattner86e44452003-10-05 19:14:42 +000068 // Remove the invoke instruction now.
Chris Lattnerdead9932003-12-10 20:22:42 +000069 BB->getInstList().erase(II);
Chris Lattner86e44452003-10-05 19:14:42 +000070
71 ++NumLowered; Changed = true;
Chris Lattnerdead9932003-12-10 20:22:42 +000072 } else if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
Chris Lattner86e44452003-10-05 19:14:42 +000073 // Insert a call to abort()
74 new CallInst(AbortFn, std::vector<Value*>(), "", UI);
75
76 // Insert a return instruction.
77 new ReturnInst(F.getReturnType() == Type::VoidTy ? 0 :
78 Constant::getNullValue(F.getReturnType()), UI);
79
80 // Remove the unwind instruction now.
Chris Lattnerdead9932003-12-10 20:22:42 +000081 BB->getInstList().erase(UI);
Chris Lattner86e44452003-10-05 19:14:42 +000082
83 ++NumLowered; Changed = true;
84 }
85 return Changed;
86}