|
| 1 | +//===----------------------------------------------------------------------===// |
| 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 | +#ifndef LLVM_CODEGEN_CFIINSTREMITTERHELPER_H |
| 10 | +#define LLVM_CODEGEN_CFIINSTREMITTERHELPER_H |
| 11 | + |
| 12 | +#include "llvm/CodeGen/MachineInstrBuilder.h" |
| 13 | +#include "llvm/CodeGen/TargetInstrInfo.h" |
| 14 | +#include "llvm/CodeGen/TargetRegisterInfo.h" |
| 15 | +#include "llvm/MC/MCDwarf.h" |
| 16 | + |
| 17 | +namespace llvm { |
| 18 | + |
| 19 | +/// Helper class for emitting CFI instructions into Machine IR. |
| 20 | +class CFIInstEmitterHelper { |
| 21 | + MachineFunction &MF; |
| 22 | + MachineBasicBlock &MBB; |
| 23 | + MachineBasicBlock::iterator InsertPt; |
| 24 | + |
| 25 | + /// MIflag to set on a MachineInstr. Typically, FrameSetup or FrameDestroy. |
| 26 | + MachineInstr::MIFlag MIFlag; |
| 27 | + |
| 28 | + /// Selects DWARF register numbering: debug or exception handling. Should be |
| 29 | + /// consistent with the choice of the ELF section (.debug_frame or .eh_frame) |
| 30 | + /// where CFI will be encoded. |
| 31 | + bool IsEH; |
| 32 | + |
| 33 | + // Cache frequently used variables. |
| 34 | + const TargetRegisterInfo &TRI; |
| 35 | + const MCInstrDesc &CFIID; |
| 36 | + const MIMetadata MIMD; // Default-initialized, no debug location desired. |
| 37 | + |
| 38 | + void emitCFIInstr(const MCCFIInstruction &CFIInst) const { |
| 39 | + BuildMI(MBB, InsertPt, MIMD, CFIID) |
| 40 | + .addCFIIndex(MF.addFrameInst(CFIInst)) |
| 41 | + .setMIFlag(MIFlag); |
| 42 | + } |
| 43 | + |
| 44 | +public: |
| 45 | + CFIInstEmitterHelper(MachineBasicBlock &MBB, |
| 46 | + MachineBasicBlock::iterator InsertPt, |
| 47 | + MachineInstr::MIFlag MIFlag, bool IsEH = true) |
| 48 | + : MF(*MBB.getParent()), MBB(MBB), MIFlag(MIFlag), IsEH(IsEH), |
| 49 | + TRI(*MF.getSubtarget().getRegisterInfo()), |
| 50 | + CFIID(MF.getSubtarget().getInstrInfo()->get( |
| 51 | + TargetOpcode::CFI_INSTRUCTION)) { |
| 52 | + setInsertPoint(InsertPt); |
| 53 | + } |
| 54 | + |
| 55 | + void setInsertPoint(MachineBasicBlock::iterator IP) { InsertPt = IP; } |
| 56 | + |
| 57 | + void emitDefCFA(MCRegister Reg, int64_t Offset) const { |
| 58 | + emitCFIInstr(MCCFIInstruction::cfiDefCfa( |
| 59 | + nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset)); |
| 60 | + } |
| 61 | + |
| 62 | + void emitDefCFARegister(MCRegister Reg) const { |
| 63 | + emitCFIInstr(MCCFIInstruction::createDefCfaRegister( |
| 64 | + nullptr, TRI.getDwarfRegNum(Reg, IsEH))); |
| 65 | + } |
| 66 | + |
| 67 | + void emitDefCFAOffset(int64_t Offset) const { |
| 68 | + emitCFIInstr(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset)); |
| 69 | + } |
| 70 | + |
| 71 | + void emitOffset(MCRegister Reg, int64_t Offset) const { |
| 72 | + emitCFIInstr(MCCFIInstruction::createOffset( |
| 73 | + nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset)); |
| 74 | + } |
| 75 | + |
| 76 | + void emitRestore(MCRegister Reg) const { |
| 77 | + emitCFIInstr(MCCFIInstruction::createRestore( |
| 78 | + nullptr, TRI.getDwarfRegNum(Reg, IsEH))); |
| 79 | + } |
| 80 | + |
| 81 | + void emitEscape(StringRef Bytes) const { |
| 82 | + emitCFIInstr(MCCFIInstruction::createEscape(nullptr, Bytes)); |
| 83 | + } |
| 84 | +}; |
| 85 | + |
| 86 | +} // namespace llvm |
| 87 | + |
| 88 | +#endif // LLVM_CODEGEN_CFIINSTREMITTERHELPER_H |
0 commit comments