Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/PatchableFunction.cpp
Line
Count
Source
1
//===-- PatchableFunction.cpp - Patchable prologues for LLVM -------------===//
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 file implements edits function bodies in place to support the
10
// "patchable-function" attribute.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/CodeGen/MachineFunction.h"
15
#include "llvm/CodeGen/MachineFunctionPass.h"
16
#include "llvm/CodeGen/MachineInstrBuilder.h"
17
#include "llvm/CodeGen/Passes.h"
18
#include "llvm/CodeGen/TargetFrameLowering.h"
19
#include "llvm/CodeGen/TargetInstrInfo.h"
20
#include "llvm/CodeGen/TargetSubtargetInfo.h"
21
22
using namespace llvm;
23
24
namespace {
25
struct PatchableFunction : public MachineFunctionPass {
26
  static char ID; // Pass identification, replacement for typeid
27
32.9k
  PatchableFunction() : MachineFunctionPass(ID) {
28
32.9k
    initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
29
32.9k
  }
30
31
  bool runOnMachineFunction(MachineFunction &F) override;
32
32.6k
   MachineFunctionProperties getRequiredProperties() const override {
33
32.6k
    return MachineFunctionProperties().set(
34
32.6k
        MachineFunctionProperties::Property::NoVRegs);
35
32.6k
  }
36
};
37
}
38
39
/// Returns true if instruction \p MI will not result in actual machine code
40
/// instructions.
41
12
static bool doesNotGeneratecode(const MachineInstr &MI) {
42
12
  // TODO: Introduce an MCInstrDesc flag for this
43
12
  switch (MI.getOpcode()) {
44
12
  
default: return false10
;
45
12
  case TargetOpcode::IMPLICIT_DEF:
46
2
  case TargetOpcode::KILL:
47
2
  case TargetOpcode::CFI_INSTRUCTION:
48
2
  case TargetOpcode::EH_LABEL:
49
2
  case TargetOpcode::GC_LABEL:
50
2
  case TargetOpcode::DBG_VALUE:
51
2
  case TargetOpcode::DBG_LABEL:
52
2
    return true;
53
12
  }
54
12
}
55
56
464k
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
57
464k
  if (!MF.getFunction().hasFnAttribute("patchable-function"))
58
464k
    return false;
59
11
60
#ifndef NDEBUG
61
  Attribute PatchAttr = MF.getFunction().getFnAttribute("patchable-function");
62
  StringRef PatchType = PatchAttr.getValueAsString();
63
  assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
64
#endif
65
66
11
  auto &FirstMBB = *MF.begin();
67
11
  MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
68
13
  for (; doesNotGeneratecode(*FirstActualI); 
++FirstActualI2
)
69
11
    assert(FirstActualI != FirstMBB.end());
70
11
71
11
  auto *TII = MF.getSubtarget().getInstrInfo();
72
11
  auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
73
11
                     TII->get(TargetOpcode::PATCHABLE_OP))
74
11
                 .addImm(2)
75
11
                 .addImm(FirstActualI->getOpcode());
76
11
77
11
  for (auto &MO : FirstActualI->operands())
78
28
    MIB.add(MO);
79
11
80
11
  FirstActualI->eraseFromParent();
81
11
  MF.ensureAlignment(4);
82
11
  return true;
83
11
}
84
85
char PatchableFunction::ID = 0;
86
char &llvm::PatchableFunctionID = PatchableFunction::ID;
87
INITIALIZE_PASS(PatchableFunction, "patchable-function",
88
                "Implement the 'patchable-function' attribute", false, false)