Mark Seaborn | b6118c5 | 2014-03-20 19:54:47 +0000 | [diff] [blame] | 1 | //===- LowerInvoke.cpp - Eliminate Invoke instructions --------------------===// |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 6 | // |
John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 7 | //===----------------------------------------------------------------------===// |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 8 | // |
| 9 | // This transformation is designed for use by code generators which do not yet |
Mark Seaborn | b6118c5 | 2014-03-20 19:54:47 +0000 | [diff] [blame] | 10 | // support stack unwinding. This pass converts 'invoke' instructions to 'call' |
| 11 | // instructions, so that any exception-handling 'landingpad' blocks become dead |
| 12 | // code (which can be removed by running the '-simplifycfg' pass afterwards). |
Chris Lattner | 61fab14 | 2004-03-31 22:00:30 +0000 | [diff] [blame] | 13 | // |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 14 | //===----------------------------------------------------------------------===// |
| 15 | |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 16 | #include "llvm/Transforms/Utils/LowerInvoke.h" |
Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/SmallVector.h" |
| 18 | #include "llvm/ADT/Statistic.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 19 | #include "llvm/IR/Instructions.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 20 | #include "llvm/IR/LLVMContext.h" |
| 21 | #include "llvm/IR/Module.h" |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 22 | #include "llvm/Pass.h" |
David Blaikie | a373d18 | 2018-03-28 17:44:36 +0000 | [diff] [blame] | 23 | #include "llvm/Transforms/Utils.h" |
Chris Lattner | 7e5bd59 | 2003-12-10 20:22:42 +0000 | [diff] [blame] | 24 | using namespace llvm; |
Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 25 | |
Chandler Carruth | 964daaa | 2014-04-22 02:55:47 +0000 | [diff] [blame] | 26 | #define DEBUG_TYPE "lowerinvoke" |
| 27 | |
Chris Lattner | 45f966d | 2006-12-19 22:17:40 +0000 | [diff] [blame] | 28 | STATISTIC(NumInvokes, "Number of invokes replaced"); |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 29 | |
Chris Lattner | 45f966d | 2006-12-19 22:17:40 +0000 | [diff] [blame] | 30 | namespace { |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 31 | class LowerInvokeLegacyPass : public FunctionPass { |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 32 | public: |
Nick Lewycky | e7da2d6 | 2007-05-06 13:37:16 +0000 | [diff] [blame] | 33 | static char ID; // Pass identification, replacement for typeid |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 34 | explicit LowerInvokeLegacyPass() : FunctionPass(ID) { |
| 35 | initializeLowerInvokeLegacyPassPass(*PassRegistry::getPassRegistry()); |
Owen Anderson | 6c18d1a | 2010-10-19 17:21:58 +0000 | [diff] [blame] | 36 | } |
Craig Topper | 3e4c697 | 2014-03-05 09:10:37 +0000 | [diff] [blame] | 37 | bool runOnFunction(Function &F) override; |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 38 | }; |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 39 | } |
| 40 | |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 41 | char LowerInvokeLegacyPass::ID = 0; |
| 42 | INITIALIZE_PASS(LowerInvokeLegacyPass, "lowerinvoke", |
Owen Anderson | d31d82d | 2010-08-23 17:52:01 +0000 | [diff] [blame] | 43 | "Lower invoke and unwind, for unwindless code generators", |
Owen Anderson | df7a4f2 | 2010-10-07 22:25:06 +0000 | [diff] [blame] | 44 | false, false) |
Dan Gohman | d78c400 | 2008-05-13 00:00:25 +0000 | [diff] [blame] | 45 | |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 46 | static bool runImpl(Function &F) { |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 47 | bool Changed = false; |
Benjamin Kramer | 135f735 | 2016-06-26 12:28:59 +0000 | [diff] [blame] | 48 | for (BasicBlock &BB : F) |
| 49 | if (InvokeInst *II = dyn_cast<InvokeInst>(BB.getTerminator())) { |
Heejin Ahn | bf77169 | 2018-05-09 00:53:50 +0000 | [diff] [blame] | 50 | SmallVector<Value *, 16> CallArgs(II->arg_begin(), II->arg_end()); |
| 51 | SmallVector<OperandBundleDef, 1> OpBundles; |
| 52 | II->getOperandBundlesAsDefs(OpBundles); |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 53 | // Insert a normal call instruction... |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 54 | CallInst *NewCall = |
James Y Knight | 7976eb5 | 2019-02-01 20:43:25 +0000 | [diff] [blame^] | 55 | CallInst::Create(II->getFunctionType(), II->getCalledValue(), |
| 56 | CallArgs, OpBundles, "", II); |
Chris Lattner | 8dd4cae | 2007-02-11 01:37:51 +0000 | [diff] [blame] | 57 | NewCall->takeName(II); |
Chris Lattner | ca96839 | 2005-05-13 06:27:02 +0000 | [diff] [blame] | 58 | NewCall->setCallingConv(II->getCallingConv()); |
Devang Patel | 4c758ea | 2008-09-25 21:00:45 +0000 | [diff] [blame] | 59 | NewCall->setAttributes(II->getAttributes()); |
Devang Patel | 218f320 | 2010-10-18 18:53:44 +0000 | [diff] [blame] | 60 | NewCall->setDebugLoc(II->getDebugLoc()); |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 61 | II->replaceAllUsesWith(NewCall); |
Misha Brukman | b1c9317 | 2005-04-21 23:48:37 +0000 | [diff] [blame] | 62 | |
Chris Lattner | 7e5bd59 | 2003-12-10 20:22:42 +0000 | [diff] [blame] | 63 | // Insert an unconditional branch to the normal destination. |
Gabor Greif | e9ecc68 | 2008-04-06 20:25:17 +0000 | [diff] [blame] | 64 | BranchInst::Create(II->getNormalDest(), II); |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 65 | |
Chris Lattner | 7e5bd59 | 2003-12-10 20:22:42 +0000 | [diff] [blame] | 66 | // Remove any PHI node entries from the exception destination. |
Benjamin Kramer | 135f735 | 2016-06-26 12:28:59 +0000 | [diff] [blame] | 67 | II->getUnwindDest()->removePredecessor(&BB); |
Chris Lattner | 7e5bd59 | 2003-12-10 20:22:42 +0000 | [diff] [blame] | 68 | |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 69 | // Remove the invoke instruction now. |
Benjamin Kramer | 135f735 | 2016-06-26 12:28:59 +0000 | [diff] [blame] | 70 | BB.getInstList().erase(II); |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 71 | |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 72 | ++NumInvokes; |
| 73 | Changed = true; |
Chris Lattner | a43b8f4 | 2003-10-05 19:14:42 +0000 | [diff] [blame] | 74 | } |
| 75 | return Changed; |
| 76 | } |
Michael Kuperstein | 31b8399 | 2016-08-12 17:28:27 +0000 | [diff] [blame] | 77 | |
| 78 | bool LowerInvokeLegacyPass::runOnFunction(Function &F) { |
| 79 | return runImpl(F); |
| 80 | } |
| 81 | |
| 82 | namespace llvm { |
| 83 | char &LowerInvokePassID = LowerInvokeLegacyPass::ID; |
| 84 | |
| 85 | // Public Interface To the LowerInvoke pass. |
| 86 | FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); } |
| 87 | |
| 88 | PreservedAnalyses LowerInvokePass::run(Function &F, |
| 89 | FunctionAnalysisManager &AM) { |
| 90 | bool Changed = runImpl(F); |
| 91 | if (!Changed) |
| 92 | return PreservedAnalyses::all(); |
| 93 | |
| 94 | return PreservedAnalyses::none(); |
| 95 | } |
| 96 | } |