blob: afb4b0a7e174e162222ce13e106d7279ec3d80df [file] [log] [blame]
Sanjoy Das15132852016-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
Sanjoy Das15132852016-04-19 05:24:47 +000015#include "llvm/CodeGen/MachineFunction.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
Charles Davisd77fdcb2016-08-08 21:20:15 +000017#include "llvm/CodeGen/MachineInstrBuilder.h"
Chandler Carruthe3e43d92017-06-06 11:49:48 +000018#include "llvm/CodeGen/Passes.h"
David Blaikie803f8272017-11-03 22:32:11 +000019#include "llvm/CodeGen/TargetFrameLowering.h"
David Blaikie48319232017-11-08 01:01:31 +000020#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikiee3a9b4c2017-11-17 01:07:10 +000021#include "llvm/CodeGen/TargetSubtargetInfo.h"
Sanjoy Das15132852016-04-19 05:24:47 +000022
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;
Charles Davisd77fdcb2016-08-08 21:20:15 +000033 MachineFunctionProperties getRequiredProperties() const override {
Sanjoy Das15132852016-04-19 05:24:47 +000034 return MachineFunctionProperties().set(
Matthias Braun690a3cb2016-08-25 01:27:13 +000035 MachineFunctionProperties::Property::NoVRegs);
Sanjoy Das15132852016-04-19 05:24:47 +000036 }
37};
38}
39
Matthias Braune01c0962016-07-13 16:37:29 +000040/// Returns true if instruction \p MI will not result in actual machine code
41/// instructions.
42static bool doesNotGeneratecode(const MachineInstr &MI) {
43 // TODO: Introduce an MCInstrDesc flag for this
44 switch (MI.getOpcode()) {
45 default: return false;
46 case TargetOpcode::IMPLICIT_DEF:
47 case TargetOpcode::KILL:
48 case TargetOpcode::CFI_INSTRUCTION:
49 case TargetOpcode::EH_LABEL:
50 case TargetOpcode::GC_LABEL:
51 case TargetOpcode::DBG_VALUE:
Shiva Chen08534222018-05-09 02:41:08 +000052 case TargetOpcode::DBG_LABEL:
Matthias Braune01c0962016-07-13 16:37:29 +000053 return true;
54 }
55}
56
Sanjoy Das15132852016-04-19 05:24:47 +000057bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
Matthias Braund3181392017-12-15 22:22:58 +000058 if (!MF.getFunction().hasFnAttribute("patchable-function"))
Sanjoy Das15132852016-04-19 05:24:47 +000059 return false;
60
Charles Davisd77fdcb2016-08-08 21:20:15 +000061#ifndef NDEBUG
Matthias Braund3181392017-12-15 22:22:58 +000062 Attribute PatchAttr = MF.getFunction().getFnAttribute("patchable-function");
Sanjoy Das15132852016-04-19 05:24:47 +000063 StringRef PatchType = PatchAttr.getValueAsString();
Charles Davisd77fdcb2016-08-08 21:20:15 +000064 assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
65#endif
Sanjoy Das15132852016-04-19 05:24:47 +000066
67 auto &FirstMBB = *MF.begin();
Matthias Braune01c0962016-07-13 16:37:29 +000068 MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
69 for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
70 assert(FirstActualI != FirstMBB.end());
Sanjoy Das15132852016-04-19 05:24:47 +000071
Charles Davisd77fdcb2016-08-08 21:20:15 +000072 auto *TII = MF.getSubtarget().getInstrInfo();
73 auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
74 TII->get(TargetOpcode::PATCHABLE_OP))
75 .addImm(2)
76 .addImm(FirstActualI->getOpcode());
Sanjoy Das15132852016-04-19 05:24:47 +000077
Charles Davisd77fdcb2016-08-08 21:20:15 +000078 for (auto &MO : FirstActualI->operands())
Diana Picus8a478102017-01-13 09:58:52 +000079 MIB.add(MO);
Charles Davisd77fdcb2016-08-08 21:20:15 +000080
81 FirstActualI->eraseFromParent();
Sanjoy Das15132852016-04-19 05:24:47 +000082 MF.ensureAlignment(4);
83 return true;
84}
85
86char PatchableFunction::ID = 0;
87char &llvm::PatchableFunctionID = PatchableFunction::ID;
Sanjoy Dasa1ff4a62016-04-19 06:25:02 +000088INITIALIZE_PASS(PatchableFunction, "patchable-function",
89 "Implement the 'patchable-function' attribute", false, false)