Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Transforms/Utils/LowerInvoke.cpp
Line
Count
Source (jump to first uncovered line)
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/Pass.h"
23
#include "llvm/Transforms/Utils.h"
24
using namespace llvm;
25
26
#define DEBUG_TYPE "lowerinvoke"
27
28
STATISTIC(NumInvokes, "Number of invokes replaced");
29
30
namespace {
31
  class LowerInvokeLegacyPass : public FunctionPass {
32
  public:
33
    static char ID; // Pass identification, replacement for typeid
34
3.89k
    explicit LowerInvokeLegacyPass() : FunctionPass(ID) {
35
3.89k
      initializeLowerInvokeLegacyPassPass(*PassRegistry::getPassRegistry());
36
3.89k
    }
37
    bool runOnFunction(Function &F) override;
38
  };
39
}
40
41
char LowerInvokeLegacyPass::ID = 0;
42
INITIALIZE_PASS(LowerInvokeLegacyPass, "lowerinvoke",
43
                "Lower invoke and unwind, for unwindless code generators",
44
                false, false)
45
46
38.3k
static bool runImpl(Function &F) {
47
38.3k
  bool Changed = false;
48
38.3k
  for (BasicBlock &BB : F)
49
42.2k
    if (InvokeInst *II = dyn_cast<InvokeInst>(BB.getTerminator())) {
50
9
      SmallVector<Value *, 16> CallArgs(II->arg_begin(), II->arg_end());
51
9
      SmallVector<OperandBundleDef, 1> OpBundles;
52
9
      II->getOperandBundlesAsDefs(OpBundles);
53
9
      // Insert a normal call instruction...
54
9
      CallInst *NewCall =
55
9
          CallInst::Create(II->getFunctionType(), II->getCalledValue(),
56
9
                           CallArgs, OpBundles, "", II);
57
9
      NewCall->takeName(II);
58
9
      NewCall->setCallingConv(II->getCallingConv());
59
9
      NewCall->setAttributes(II->getAttributes());
60
9
      NewCall->setDebugLoc(II->getDebugLoc());
61
9
      II->replaceAllUsesWith(NewCall);
62
9
63
9
      // Insert an unconditional branch to the normal destination.
64
9
      BranchInst::Create(II->getNormalDest(), II);
65
9
66
9
      // Remove any PHI node entries from the exception destination.
67
9
      II->getUnwindDest()->removePredecessor(&BB);
68
9
69
9
      // Remove the invoke instruction now.
70
9
      BB.getInstList().erase(II);
71
9
72
9
      ++NumInvokes;
73
9
      Changed = true;
74
9
    }
75
38.3k
  return Changed;
76
38.3k
}
77
78
38.3k
bool LowerInvokeLegacyPass::runOnFunction(Function &F) {
79
38.3k
  return runImpl(F);
80
38.3k
}
81
82
namespace llvm {
83
char &LowerInvokePassID = LowerInvokeLegacyPass::ID;
84
85
// Public Interface To the LowerInvoke pass.
86
3.89k
FunctionPass *createLowerInvokePass() { return new LowerInvokeLegacyPass(); }
87
88
PreservedAnalyses LowerInvokePass::run(Function &F,
89
1
                                       FunctionAnalysisManager &AM) {
90
1
  bool Changed = runImpl(F);
91
1
  if (!Changed)
92
0
    return PreservedAnalyses::all();
93
1
94
1
  return PreservedAnalyses::none();
95
1
}
96
}