xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Utils/LowerInvoke.cpp (revision 37f1f2684f2670b204080ef2d6c303becd28545f)
1  //===- LowerInvoke.cpp - Eliminate Invoke instructions --------------------===//
2  //
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
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This transformation is designed for use by code generators which do not yet
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).
13  //
14  //===----------------------------------------------------------------------===//
15  
16  #include "llvm/Transforms/Utils/LowerInvoke.h"
17  #include "llvm/ADT/SmallVector.h"
18  #include "llvm/ADT/Statistic.h"
19  #include "llvm/IR/Instructions.h"
20  #include "llvm/IR/LLVMContext.h"
21  #include "llvm/IR/Module.h"
22  #include "llvm/InitializePasses.h"
23  #include "llvm/Pass.h"
24  #include "llvm/Transforms/Utils.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      explicit LowerInvokeLegacyPass() : FunctionPass(ID) {
36        initializeLowerInvokeLegacyPassPass(*PassRegistry::getPassRegistry());
37      }
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  static bool runImpl(Function &F) {
48    bool Changed = false;
49    for (BasicBlock &BB : F)
50      if (InvokeInst *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
51        SmallVector<Value *, 16> CallArgs(II->arg_begin(), II->arg_end());
52        SmallVector<OperandBundleDef, 1> OpBundles;
53        II->getOperandBundlesAsDefs(OpBundles);
54        // Insert a normal call instruction...
55        CallInst *NewCall =
56            CallInst::Create(II->getFunctionType(), II->getCalledValue(),
57                             CallArgs, OpBundles, "", II);
58        NewCall->takeName(II);
59        NewCall->setCallingConv(II->getCallingConv());
60        NewCall->setAttributes(II->getAttributes());
61        NewCall->setDebugLoc(II->getDebugLoc());
62        II->replaceAllUsesWith(NewCall);
63  
64        // Insert an unconditional branch to the normal destination.
65        BranchInst::Create(II->getNormalDest(), II);
66  
67        // Remove any PHI node entries from the exception destination.
68        II->getUnwindDest()->removePredecessor(&BB);
69  
70        // Remove the invoke instruction now.
71        BB.getInstList().erase(II);
72  
73        ++NumInvokes;
74        Changed = true;
75      }
76    return Changed;
77  }
78  
79  bool LowerInvokeLegacyPass::runOnFunction(Function &F) {
80    return runImpl(F);
81  }
82  
83  namespace llvm {
84  char &LowerInvokePassID = LowerInvokeLegacyPass::ID;
85  
86  // Public Interface To the LowerInvoke pass.
87  FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); }
88  
89  PreservedAnalyses LowerInvokePass::run(Function &F,
90                                         FunctionAnalysisManager &AM) {
91    bool Changed = runImpl(F);
92    if (!Changed)
93      return PreservedAnalyses::all();
94  
95    return PreservedAnalyses::none();
96  }
97  }
98