blob: 6fd9954ddae6f1bfdfc2af49b9103486a37aaa41 [file] [log] [blame]
Sanjoy Dasc0441c22016-04-19 05:24:47 +00001//===-- PatchableFunction.cpp - Patchable prologues for LLVM -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements edits function bodies in place to support the
11// "patchable-function" attribute.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/CodeGen/Passes.h"
16#include "llvm/CodeGen/Analysis.h"
17#include "llvm/CodeGen/MachineFunction.h"
18#include "llvm/CodeGen/MachineFunctionPass.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/Target/TargetFrameLowering.h"
21#include "llvm/Target/TargetInstrInfo.h"
22#include "llvm/Target/TargetSubtargetInfo.h"
23
24using namespace llvm;
25
26namespace {
27struct PatchableFunction : public MachineFunctionPass {
28 static char ID; // Pass identification, replacement for typeid
29 PatchableFunction() : MachineFunctionPass(ID) {
30 initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
31 }
32
33 bool runOnMachineFunction(MachineFunction &F) override;
34 MachineFunctionProperties getRequiredProperties() const override {
35 return MachineFunctionProperties().set(
36 MachineFunctionProperties::Property::AllVRegsAllocated);
37 }
38};
39}
40
41bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
42 if (!MF.getFunction()->hasFnAttribute("patchable-function"))
43 return false;
44
45#ifndef NDEBUG
46 Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
47 StringRef PatchType = PatchAttr.getValueAsString();
48 assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
49#endif
50
51 auto &FirstMBB = *MF.begin();
52 auto &FirstMI = *FirstMBB.begin();
53
54 auto *TII = MF.getSubtarget().getInstrInfo();
55 auto MIB = BuildMI(FirstMBB, FirstMBB.begin(), FirstMI.getDebugLoc(),
56 TII->get(TargetOpcode::PATCHABLE_OP))
57 .addImm(2)
58 .addImm(FirstMI.getOpcode());
59
60 for (auto &MO : FirstMI.operands())
61 MIB.addOperand(MO);
62
63 FirstMI.eraseFromParent();
64 MF.ensureAlignment(4);
65 return true;
66}
67
68char PatchableFunction::ID = 0;
69char &llvm::PatchableFunctionID = PatchableFunction::ID;
Sanjoy Das4519ff72016-04-19 06:25:02 +000070INITIALIZE_PASS(PatchableFunction, "patchable-function",
71 "Implement the 'patchable-function' attribute", false, false)