/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/Utils/LowerInvoke.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- LowerInvoke.cpp - Eliminate Invoke instructions --------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This transformation is designed for use by code generators which do not yet |
11 | | // support stack unwinding. This pass converts 'invoke' instructions to 'call' |
12 | | // instructions, so that any exception-handling 'landingpad' blocks become dead |
13 | | // code (which can be removed by running the '-simplifycfg' pass afterwards). |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | #include "llvm/Transforms/Utils/LowerInvoke.h" |
18 | | #include "llvm/ADT/SmallVector.h" |
19 | | #include "llvm/ADT/Statistic.h" |
20 | | #include "llvm/IR/Instructions.h" |
21 | | #include "llvm/IR/LLVMContext.h" |
22 | | #include "llvm/IR/Module.h" |
23 | | #include "llvm/Pass.h" |
24 | | #include "llvm/Transforms/Scalar.h" |
25 | | using namespace llvm; |
26 | | |
27 | | #define DEBUG_TYPE "lowerinvoke" |
28 | | |
29 | | STATISTIC(NumInvokes, "Number of invokes replaced"); |
30 | | |
31 | | namespace { |
32 | | class LowerInvokeLegacyPass : public FunctionPass { |
33 | | public: |
34 | | static char ID; // Pass identification, replacement for typeid |
35 | 2.08k | explicit LowerInvokeLegacyPass() : FunctionPass(ID) { |
36 | 2.08k | initializeLowerInvokeLegacyPassPass(*PassRegistry::getPassRegistry()); |
37 | 2.08k | } |
38 | | bool runOnFunction(Function &F) override; |
39 | | }; |
40 | | } |
41 | | |
42 | | char LowerInvokeLegacyPass::ID = 0; |
43 | | INITIALIZE_PASS(LowerInvokeLegacyPass, "lowerinvoke", |
44 | | "Lower invoke and unwind, for unwindless code generators", |
45 | | false, false) |
46 | | |
47 | 18.8k | static bool runImpl(Function &F) { |
48 | 18.8k | bool Changed = false; |
49 | 18.8k | for (BasicBlock &BB : F) |
50 | 21.1k | if (InvokeInst *21.1k II21.1k = dyn_cast<InvokeInst>(BB.getTerminator())) { |
51 | 5 | SmallVector<Value *, 16> CallArgs(II->op_begin(), II->op_end() - 3); |
52 | 5 | // Insert a normal call instruction... |
53 | 5 | CallInst *NewCall = |
54 | 5 | CallInst::Create(II->getCalledValue(), CallArgs, "", II); |
55 | 5 | NewCall->takeName(II); |
56 | 5 | NewCall->setCallingConv(II->getCallingConv()); |
57 | 5 | NewCall->setAttributes(II->getAttributes()); |
58 | 5 | NewCall->setDebugLoc(II->getDebugLoc()); |
59 | 5 | II->replaceAllUsesWith(NewCall); |
60 | 5 | |
61 | 5 | // Insert an unconditional branch to the normal destination. |
62 | 5 | BranchInst::Create(II->getNormalDest(), II); |
63 | 5 | |
64 | 5 | // Remove any PHI node entries from the exception destination. |
65 | 5 | II->getUnwindDest()->removePredecessor(&BB); |
66 | 5 | |
67 | 5 | // Remove the invoke instruction now. |
68 | 5 | BB.getInstList().erase(II); |
69 | 5 | |
70 | 5 | ++NumInvokes; |
71 | 5 | Changed = true; |
72 | 5 | } |
73 | 18.8k | return Changed; |
74 | 18.8k | } |
75 | | |
76 | 18.8k | bool LowerInvokeLegacyPass::runOnFunction(Function &F) { |
77 | 18.8k | return runImpl(F); |
78 | 18.8k | } |
79 | | |
80 | | namespace llvm { |
81 | | char &LowerInvokePassID = LowerInvokeLegacyPass::ID; |
82 | | |
83 | | // Public Interface To the LowerInvoke pass. |
84 | 2.08k | FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); } |
85 | | |
86 | | PreservedAnalyses LowerInvokePass::run(Function &F, |
87 | 1 | FunctionAnalysisManager &AM) { |
88 | 1 | bool Changed = runImpl(F); |
89 | 1 | if (!Changed) |
90 | 0 | return PreservedAnalyses::all(); |
91 | 1 | |
92 | 1 | return PreservedAnalyses::none(); |
93 | 1 | } |
94 | | } |