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