LLVM API Documentation

X86AsmPrinter.h
Go to the documentation of this file.
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