blob: 84dbebfd2b6fea1ea7dd4f2817cc4315cfbf1e83 [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
Sanjoy Dasc0441c22016-04-19 05:24:47 +000015#include "llvm/CodeGen/MachineFunction.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
Charles Davise9c32c72016-08-08 21:20:15 +000017#include "llvm/CodeGen/MachineInstrBuilder.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000018#include "llvm/CodeGen/Passes.h"
David Blaikie1be62f02017-11-03 22:32:11 +000019#include "llvm/CodeGen/TargetFrameLowering.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000020#include "llvm/CodeGen/TargetInstrInfo.h"
Charles Davise9c32c72016-08-08 21:20:15 +000021#include "llvm/Target/TargetSubtargetInfo.h"
Sanjoy Dasc0441c22016-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 Davise9c32c72016-08-08 21:20:15 +000033 MachineFunctionProperties getRequiredProperties() const override {
Sanjoy Dasc0441c22016-04-19 05:24:47 +000034 return MachineFunctionProperties().set(
Matthias Braun1eb47362016-08-25 01:27:13 +000035 MachineFunctionProperties::Property::NoVRegs);
Sanjoy Dasc0441c22016-04-19 05:24:47 +000036 }
37};
38}
39
Matthias Braun512424f2016-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:
52 return true;
53 }
54}
55
Sanjoy Dasc0441c22016-04-19 05:24:47 +000056bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
57 if (!MF.getFunction()->hasFnAttribute("patchable-function"))
58 return false;
59
Charles Davise9c32c72016-08-08 21:20:15 +000060#ifndef NDEBUG
Sanjoy Dasc0441c22016-04-19 05:24:47 +000061 Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
62 StringRef PatchType = PatchAttr.getValueAsString();
Charles Davise9c32c72016-08-08 21:20:15 +000063 assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
64#endif
Sanjoy Dasc0441c22016-04-19 05:24:47 +000065
66 auto &FirstMBB = *MF.begin();
Matthias Braun512424f2016-07-13 16:37:29 +000067 MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
68 for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
69 assert(FirstActualI != FirstMBB.end());
Sanjoy Dasc0441c22016-04-19 05:24:47 +000070
Charles Davise9c32c72016-08-08 21:20:15 +000071 auto *TII = MF.getSubtarget().getInstrInfo();
72 auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
73 TII->get(TargetOpcode::PATCHABLE_OP))
74 .addImm(2)
75 .addImm(FirstActualI->getOpcode());
Sanjoy Dasc0441c22016-04-19 05:24:47 +000076
Charles Davise9c32c72016-08-08 21:20:15 +000077 for (auto &MO : FirstActualI->operands())
Diana Picus116bbab2017-01-13 09:58:52 +000078 MIB.add(MO);
Charles Davise9c32c72016-08-08 21:20:15 +000079
80 FirstActualI->eraseFromParent();
Sanjoy Dasc0441c22016-04-19 05:24:47 +000081 MF.ensureAlignment(4);
82 return true;
83}
84
85char PatchableFunction::ID = 0;
86char &llvm::PatchableFunctionID = PatchableFunction::ID;
Sanjoy Das4519ff72016-04-19 06:25:02 +000087INITIALIZE_PASS(PatchableFunction, "patchable-function",
88 "Implement the 'patchable-function' attribute", false, false)