LLVM API Documentation
00001 //===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H 00011 #define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H 00012 00013 #include "X86Subtarget.h" 00014 #include "llvm/CodeGen/AsmPrinter.h" 00015 #include "llvm/CodeGen/StackMaps.h" 00016 #include "llvm/Target/TargetMachine.h" 00017 00018 // Implemented in X86MCInstLower.cpp 00019 namespace { 00020 class X86MCInstLower; 00021 } 00022 00023 namespace llvm { 00024 class MCStreamer; 00025 class MCSymbol; 00026 00027 class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { 00028 const X86Subtarget *Subtarget; 00029 StackMaps SM; 00030 00031 void GenerateExportDirective(const MCSymbol *Sym, bool IsData); 00032 00033 // This utility class tracks the length of a stackmap instruction's 'shadow'. 00034 // It is used by the X86AsmPrinter to ensure that the stackmap shadow 00035 // invariants (i.e. no other stackmaps, patchpoints, or control flow within 00036 // the shadow) are met, while outputting a minimal number of NOPs for padding. 00037 // 00038 // To minimise the number of NOPs used, the shadow tracker counts the number 00039 // of instruction bytes output since the last stackmap. Only if there are too 00040 // few instruction bytes to cover the shadow are NOPs used for padding. 00041 class StackMapShadowTracker { 00042 public: 00043 StackMapShadowTracker(TargetMachine &TM); 00044 ~StackMapShadowTracker(); 00045 void startFunction(MachineFunction &MF); 00046 void count(MCInst &Inst, const MCSubtargetInfo &STI); 00047 00048 // Called to signal the start of a shadow of RequiredSize bytes. 00049 void reset(unsigned RequiredSize) { 00050 RequiredShadowSize = RequiredSize; 00051 CurrentShadowSize = 0; 00052 InShadow = true; 00053 } 00054 00055 // Called before every stackmap/patchpoint, and at the end of basic blocks, 00056 // to emit any necessary padding-NOPs. 00057 void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI); 00058 private: 00059 TargetMachine &TM; 00060 std::unique_ptr<MCCodeEmitter> CodeEmitter; 00061 bool InShadow; 00062 00063 // RequiredShadowSize holds the length of the shadow specified in the most 00064 // recently encountered STACKMAP instruction. 00065 // CurrentShadowSize counts the number of bytes encoded since the most 00066 // recently encountered STACKMAP, stopping when that number is greater than 00067 // or equal to RequiredShadowSize. 00068 unsigned RequiredShadowSize, CurrentShadowSize; 00069 }; 00070 00071 StackMapShadowTracker SMShadowTracker; 00072 00073 // All instructions emitted by the X86AsmPrinter should use this helper 00074 // method. 00075 // 00076 // This helper function invokes the SMShadowTracker on each instruction before 00077 // outputting it to the OutStream. This allows the shadow tracker to minimise 00078 // the number of NOPs used for stackmap padding. 00079 void EmitAndCountInstruction(MCInst &Inst); 00080 00081 void InsertStackMapShadows(MachineFunction &MF); 00082 void LowerSTACKMAP(const MachineInstr &MI); 00083 void LowerPATCHPOINT(const MachineInstr &MI); 00084 00085 void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI); 00086 00087 public: 00088 explicit X86AsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 00089 : AsmPrinter(TM, Streamer), SM(*this), SMShadowTracker(TM) { 00090 Subtarget = &TM.getSubtarget<X86Subtarget>(); 00091 } 00092 00093 const char *getPassName() const override { 00094 return "X86 Assembly / Object Emitter"; 00095 } 00096 00097 const X86Subtarget &getSubtarget() const { return *Subtarget; } 00098 00099 void EmitStartOfAsmFile(Module &M) override; 00100 00101 void EmitEndOfAsmFile(Module &M) override; 00102 00103 void EmitInstruction(const MachineInstr *MI) override; 00104 00105 void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override { 00106 SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); 00107 } 00108 00109 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00110 unsigned AsmVariant, const char *ExtraCode, 00111 raw_ostream &OS) override; 00112 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 00113 unsigned AsmVariant, const char *ExtraCode, 00114 raw_ostream &OS) override; 00115 00116 /// \brief Return the symbol for the specified constant pool entry. 00117 MCSymbol *GetCPISymbol(unsigned CPID) const override; 00118 00119 bool doInitialization(Module &M) override { 00120 SMShadowTracker.reset(0); 00121 SM.reset(); 00122 return AsmPrinter::doInitialization(M); 00123 } 00124 00125 bool runOnMachineFunction(MachineFunction &F) override; 00126 }; 00127 00128 } // end namespace llvm 00129 00130 #endif