diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp | |
parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp b/contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp index 0f9da0637ced..9449f143366f 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp @@ -37,23 +37,6 @@ struct PatchableFunction : public MachineFunctionPass { }; } -/// Returns true if instruction \p MI will not result in actual machine code -/// instructions. -static bool doesNotGeneratecode(const MachineInstr &MI) { - // TODO: Introduce an MCInstrDesc flag for this - switch (MI.getOpcode()) { - default: return false; - case TargetOpcode::IMPLICIT_DEF: - case TargetOpcode::KILL: - case TargetOpcode::CFI_INSTRUCTION: - case TargetOpcode::EH_LABEL: - case TargetOpcode::GC_LABEL: - case TargetOpcode::DBG_VALUE: - case TargetOpcode::DBG_LABEL: - return true; - } -} - bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) { if (MF.getFunction().hasFnAttribute("patchable-function-entry")) { MachineBasicBlock &FirstMBB = *MF.begin(); @@ -74,11 +57,28 @@ bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) { #endif auto &FirstMBB = *MF.begin(); - MachineBasicBlock::iterator FirstActualI = FirstMBB.begin(); - for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI) - assert(FirstActualI != FirstMBB.end()); - auto *TII = MF.getSubtarget().getInstrInfo(); + + MachineBasicBlock::iterator FirstActualI = llvm::find_if( + FirstMBB, [](const MachineInstr &MI) { return !MI.isMetaInstruction(); }); + + if (FirstActualI == FirstMBB.end()) { + // As of Microsoft documentation on /hotpatch feature, we must ensure that + // "the first instruction of each function is at least two bytes, and no + // jump within the function goes to the first instruction" + + // When the first MBB is empty, insert a patchable no-op. This ensures the + // first instruction is patchable in two special cases: + // - the function is empty (e.g. unreachable) + // - the function jumps back to the first instruction, which is in a + // successor MBB. + BuildMI(&FirstMBB, DebugLoc(), TII->get(TargetOpcode::PATCHABLE_OP)) + .addImm(2) + .addImm(TargetOpcode::PATCHABLE_OP); + MF.ensureAlignment(Align(16)); + return true; + } + auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(), TII->get(TargetOpcode::PATCHABLE_OP)) .addImm(2) |