blob: 71a727ecb052eed2b5ed8d84f21c2017ed3ad771 [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"
Sanjoy Dasc0441c22016-04-19 05:24:47 +000016#include "llvm/CodeGen/MachineFunction.h"
17#include "llvm/CodeGen/MachineFunctionPass.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19#include "llvm/Target/TargetFrameLowering.h"
20#include "llvm/Target/TargetInstrInfo.h"
21#include "llvm/Target/TargetSubtargetInfo.h"
22
23using namespace llvm;
24
25namespace {
26struct PatchableFunction : public MachineFunctionPass {
27 static char ID; // Pass identification, replacement for typeid
28 PatchableFunction() : MachineFunctionPass(ID) {
29 initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
30 }
31
32 bool runOnMachineFunction(MachineFunction &F) override;
33 MachineFunctionProperties getRequiredProperties() const override {
34 return MachineFunctionProperties().set(
35 MachineFunctionProperties::Property::AllVRegsAllocated);
36 }
37};
38}
39
40bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
41 if (!MF.getFunction()->hasFnAttribute("patchable-function"))
42 return false;
43
44#ifndef NDEBUG
45 Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
46 StringRef PatchType = PatchAttr.getValueAsString();
47 assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
48#endif
49
50 auto &FirstMBB = *MF.begin();
51 auto &FirstMI = *FirstMBB.begin();
52
53 auto *TII = MF.getSubtarget().getInstrInfo();
54 auto MIB = BuildMI(FirstMBB, FirstMBB.begin(), FirstMI.getDebugLoc(),
55 TII->get(TargetOpcode::PATCHABLE_OP))
56 .addImm(2)
57 .addImm(FirstMI.getOpcode());
58
59 for (auto &MO : FirstMI.operands())
60 MIB.addOperand(MO);
61
62 FirstMI.eraseFromParent();
63 MF.ensureAlignment(4);
64 return true;
65}
66
67char PatchableFunction::ID = 0;
68char &llvm::PatchableFunctionID = PatchableFunction::ID;
Sanjoy Das4519ff72016-04-19 06:25:02 +000069INITIALIZE_PASS(PatchableFunction, "patchable-function",
70 "Implement the 'patchable-function' attribute", false, false)