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"
25using namespace llvm;
26
27#define DEBUG_TYPE "lowerinvoke"
28
29STATISTIC(NumInvokes, "Number of invokes replaced");
30
31namespace {
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
42char LowerInvokeLegacyPass::ID = 0;
43INITIALIZE_PASS(LowerInvokeLegacyPass, "lowerinvoke",
44                "Lower invoke and unwind, for unwindless code generators",
45                false, false)
46
47static 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
79bool LowerInvokeLegacyPass::runOnFunction(Function &F) {
80  return runImpl(F);
81}
82
83namespace llvm {
84char &LowerInvokePassID = LowerInvokeLegacyPass::ID;
85
86// Public Interface To the LowerInvoke pass.
87FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); }
88
89PreservedAnalyses 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