1 //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
11 #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H
13 #include "X86Subtarget.h"
14 #include "llvm/CodeGen/AsmPrinter.h"
15 #include "llvm/CodeGen/FaultMaps.h"
16 #include "llvm/CodeGen/StackMaps.h"
17 #include "llvm/Target/TargetMachine.h"
19 // Implemented in X86MCInstLower.cpp
28 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {
29 const X86Subtarget *Subtarget;
32 std::unique_ptr<MCCodeEmitter> CodeEmitter;
34 // This utility class tracks the length of a stackmap instruction's 'shadow'.
35 // It is used by the X86AsmPrinter to ensure that the stackmap shadow
36 // invariants (i.e. no other stackmaps, patchpoints, or control flow within
37 // the shadow) are met, while outputting a minimal number of NOPs for padding.
39 // To minimise the number of NOPs used, the shadow tracker counts the number
40 // of instruction bytes output since the last stackmap. Only if there are too
41 // few instruction bytes to cover the shadow are NOPs used for padding.
42 class StackMapShadowTracker {
44 void startFunction(MachineFunction &MF) {
47 void count(MCInst &Inst, const MCSubtargetInfo &STI,
48 MCCodeEmitter *CodeEmitter);
50 // Called to signal the start of a shadow of RequiredSize bytes.
51 void reset(unsigned RequiredSize) {
52 RequiredShadowSize = RequiredSize;
53 CurrentShadowSize = 0;
57 // Called before every stackmap/patchpoint, and at the end of basic blocks,
58 // to emit any necessary padding-NOPs.
59 void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);
61 const MachineFunction *MF;
62 bool InShadow = false;
64 // RequiredShadowSize holds the length of the shadow specified in the most
65 // recently encountered STACKMAP instruction.
66 // CurrentShadowSize counts the number of bytes encoded since the most
67 // recently encountered STACKMAP, stopping when that number is greater than
68 // or equal to RequiredShadowSize.
69 unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;
72 StackMapShadowTracker SMShadowTracker;
74 // This describes the kind of sled we're storing in the XRay table.
75 enum class SledKind : uint8_t {
81 // The table will contain these structs that point to the sled, the function
82 // containing the sled, and what kind of sled (and whether they should always
84 struct XRayFunctionEntry {
86 const MCSymbol *Function;
88 bool AlwaysInstrument;
89 const class Function *Fn;
92 // All the sleds to be emitted.
93 std::vector<XRayFunctionEntry> Sleds;
95 // All instructions emitted by the X86AsmPrinter should use this helper
98 // This helper function invokes the SMShadowTracker on each instruction before
99 // outputting it to the OutStream. This allows the shadow tracker to minimise
100 // the number of NOPs used for stackmap padding.
101 void EmitAndCountInstruction(MCInst &Inst);
102 void LowerSTACKMAP(const MachineInstr &MI);
103 void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
104 void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);
105 void LowerFAULTING_LOAD_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
106 void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);
108 void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);
110 // XRay-specific lowering for X86.
111 void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,
112 X86MCInstLower &MCIL);
113 void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);
114 void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);
116 // Helper function that emits the XRay sleds we've collected for a particular
118 void EmitXRayTable();
120 // Helper function to record a given XRay sled.
121 void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind);
123 explicit X86AsmPrinter(TargetMachine &TM,
124 std::unique_ptr<MCStreamer> Streamer)
125 : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {}
127 const char *getPassName() const override {
128 return "X86 Assembly / Object Emitter";
131 const X86Subtarget &getSubtarget() const { return *Subtarget; }
133 void EmitStartOfAsmFile(Module &M) override;
135 void EmitEndOfAsmFile(Module &M) override;
137 void EmitInstruction(const MachineInstr *MI) override;
139 void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override {
140 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
143 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
144 unsigned AsmVariant, const char *ExtraCode,
145 raw_ostream &OS) override;
146 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
147 unsigned AsmVariant, const char *ExtraCode,
148 raw_ostream &OS) override;
150 /// \brief Return the symbol for the specified constant pool entry.
151 MCSymbol *GetCPISymbol(unsigned CPID) const override;
153 bool doInitialization(Module &M) override {
154 SMShadowTracker.reset(0);
156 return AsmPrinter::doInitialization(M);
159 bool runOnMachineFunction(MachineFunction &F) override;
162 } // end namespace llvm