LLVM 17.0.0git
PatchableFunction.cpp
Go to the documentation of this file.
1//===-- PatchableFunction.cpp - Patchable prologues for LLVM -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements edits function bodies in place to support the
10// "patchable-function" attribute.
11//
12//===----------------------------------------------------------------------===//
13
20#include "llvm/Pass.h"
21#include "llvm/PassRegistry.h"
22
23using namespace llvm;
24
25namespace {
26struct PatchableFunction : public MachineFunctionPass {
27 static char ID; // Pass identification, replacement for typeid
28 PatchableFunction() : MachineFunctionPass(ID) {
30 }
31
35 MachineFunctionProperties::Property::NoVRegs);
36 }
37};
38}
39
40bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
41 if (MF.getFunction().hasFnAttribute("patchable-function-entry")) {
42 MachineBasicBlock &FirstMBB = *MF.begin();
44 // The initial .loc covers PATCHABLE_FUNCTION_ENTER.
45 BuildMI(FirstMBB, FirstMBB.begin(), DebugLoc(),
46 TII->get(TargetOpcode::PATCHABLE_FUNCTION_ENTER));
47 return true;
48 }
49
50 if (!MF.getFunction().hasFnAttribute("patchable-function"))
51 return false;
52
53#ifndef NDEBUG
54 Attribute PatchAttr = MF.getFunction().getFnAttribute("patchable-function");
55 StringRef PatchType = PatchAttr.getValueAsString();
56 assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
57#endif
58
59 auto &FirstMBB = *MF.begin();
60 auto *TII = MF.getSubtarget().getInstrInfo();
61
63 FirstMBB, [](const MachineInstr &MI) { return !MI.isMetaInstruction(); });
64
65 if (FirstActualI == FirstMBB.end()) {
66 // As of Microsoft documentation on /hotpatch feature, we must ensure that
67 // "the first instruction of each function is at least two bytes, and no
68 // jump within the function goes to the first instruction"
69
70 // When the first MBB is empty, insert a patchable no-op. This ensures the
71 // first instruction is patchable in two special cases:
72 // - the function is empty (e.g. unreachable)
73 // - the function jumps back to the first instruction, which is in a
74 // successor MBB.
75 BuildMI(&FirstMBB, DebugLoc(), TII->get(TargetOpcode::PATCHABLE_OP))
76 .addImm(2)
77 .addImm(TargetOpcode::PATCHABLE_OP);
78 MF.ensureAlignment(Align(16));
79 return true;
80 }
81
82 auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
83 TII->get(TargetOpcode::PATCHABLE_OP))
84 .addImm(2)
85 .addImm(FirstActualI->getOpcode());
86
87 for (auto &MO : FirstActualI->operands())
88 MIB.add(MO);
89
90 FirstActualI->eraseFromParent();
91 MF.ensureAlignment(Align(16));
92 return true;
93}
94
95char PatchableFunction::ID = 0;
96char &llvm::PatchableFunctionID = PatchableFunction::ID;
97INITIALIZE_PASS(PatchableFunction, "patchable-function",
98 "Implement the 'patchable-function' attribute", false, false)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:317
A debug info location.
Definition: DebugLoc.h:33
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:670
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:644
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void ensureAlignment(Align A)
ensureAlignment - Make sure the function is at least A bytes aligned.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
void initializePatchableFunctionPass(PassRegistry &)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1846
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39