1 //===- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains a class to be used as the base class for target specific 11 // asm writers. This class primarily handles common functionality used by 12 // all asm writers. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CODEGEN_ASMPRINTER_H 17 #define LLVM_CODEGEN_ASMPRINTER_H 18 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/StringRef.h" 22 #include "llvm/ADT/Twine.h" 23 #include "llvm/CodeGen/DwarfStringPoolEntry.h" 24 #include "llvm/CodeGen/MachineFunctionPass.h" 25 #include "llvm/IR/InlineAsm.h" 26 #include "llvm/IR/LLVMContext.h" 27 #include "llvm/Support/ErrorHandling.h" 28 #include "llvm/Support/SourceMgr.h" 29 #include <cstdint> 30 #include <memory> 31 #include <utility> 32 #include <vector> 33 34 namespace llvm { 35 36 class AsmPrinterHandler; 37 class BasicBlock; 38 class BlockAddress; 39 class Constant; 40 class ConstantArray; 41 class DataLayout; 42 class DIE; 43 class DIEAbbrev; 44 class DwarfDebug; 45 class GCMetadataPrinter; 46 class GCStrategy; 47 class GlobalIndirectSymbol; 48 class GlobalObject; 49 class GlobalValue; 50 class GlobalVariable; 51 class MachineBasicBlock; 52 class MachineConstantPoolValue; 53 class MachineDominatorTree; 54 class MachineFunction; 55 class MachineInstr; 56 class MachineJumpTableInfo; 57 class MachineLoopInfo; 58 class MachineModuleInfo; 59 class MachineOptimizationRemarkEmitter; 60 class MCAsmInfo; 61 class MCCFIInstruction; 62 struct MCCodePaddingContext; 63 class MCContext; 64 class MCExpr; 65 class MCInst; 66 class MCSection; 67 class MCStreamer; 68 class MCSubtargetInfo; 69 class MCSymbol; 70 class MCTargetOptions; 71 class MDNode; 72 class Module; 73 class raw_ostream; 74 class TargetLoweringObjectFile; 75 class TargetMachine; 76 77 /// This class is intended to be used as a driving class for all asm writers. 78 class AsmPrinter : public MachineFunctionPass { 79 public: 80 /// Target machine description. 81 TargetMachine &TM; 82 83 /// Target Asm Printer information. 84 const MCAsmInfo *MAI; 85 86 /// This is the context for the output file that we are streaming. This owns 87 /// all of the global MC-related objects for the generated translation unit. 88 MCContext &OutContext; 89 90 /// This is the MCStreamer object for the file we are generating. This 91 /// contains the transient state for the current translation unit that we are 92 /// generating (such as the current section etc). 93 std::unique_ptr<MCStreamer> OutStreamer; 94 95 /// The current machine function. 96 MachineFunction *MF = nullptr; 97 98 /// This is a pointer to the current MachineModuleInfo. 99 MachineModuleInfo *MMI = nullptr; 100 101 /// This is a pointer to the current MachineLoopInfo. 102 MachineDominatorTree *MDT = nullptr; 103 104 /// This is a pointer to the current MachineLoopInfo. 105 MachineLoopInfo *MLI = nullptr; 106 107 /// Optimization remark emitter. 108 MachineOptimizationRemarkEmitter *ORE; 109 110 /// The symbol for the current function. This is recalculated at the beginning 111 /// of each call to runOnMachineFunction(). 112 MCSymbol *CurrentFnSym = nullptr; 113 114 /// The symbol used to represent the start of the current function for the 115 /// purpose of calculating its size (e.g. using the .size directive). By 116 /// default, this is equal to CurrentFnSym. 117 MCSymbol *CurrentFnSymForSize = nullptr; 118 119 /// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of 120 /// its number of uses by other globals. 121 using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>; 122 MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; 123 124 /// Enable print [latency:throughput] in output. 125 bool EnablePrintSchedInfo = false; 126 127 private: 128 MCSymbol *CurrentFnBegin = nullptr; 129 MCSymbol *CurrentFnEnd = nullptr; 130 MCSymbol *CurExceptionSym = nullptr; 131 132 // The garbage collection metadata printer table. 133 void *GCMetadataPrinters = nullptr; // Really a DenseMap. 134 135 /// Emit comments in assembly output if this is true. 136 bool VerboseAsm; 137 138 static char ID; 139 140 struct HandlerInfo { 141 AsmPrinterHandler *Handler; 142 const char *TimerName; 143 const char *TimerDescription; 144 const char *TimerGroupName; 145 const char *TimerGroupDescription; 146 HandlerInfoHandlerInfo147 HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName, 148 const char *TimerDescription, const char *TimerGroupName, 149 const char *TimerGroupDescription) 150 : Handler(Handler), TimerName(TimerName), 151 TimerDescription(TimerDescription), TimerGroupName(TimerGroupName), 152 TimerGroupDescription(TimerGroupDescription) {} 153 }; 154 155 /// A vector of all debug/EH info emitters we should use. This vector 156 /// maintains ownership of the emitters. 157 SmallVector<HandlerInfo, 1> Handlers; 158 159 public: 160 struct SrcMgrDiagInfo { 161 SourceMgr SrcMgr; 162 std::vector<const MDNode *> LocInfos; 163 LLVMContext::InlineAsmDiagHandlerTy DiagHandler; 164 void *DiagContext; 165 }; 166 167 private: 168 /// If generated on the fly this own the instance. 169 std::unique_ptr<MachineDominatorTree> OwnedMDT; 170 171 /// If generated on the fly this own the instance. 172 std::unique_ptr<MachineLoopInfo> OwnedMLI; 173 174 /// Structure for generating diagnostics for inline assembly. Only initialised 175 /// when necessary. 176 mutable std::unique_ptr<SrcMgrDiagInfo> DiagInfo; 177 178 /// If the target supports dwarf debug info, this pointer is non-null. 179 DwarfDebug *DD = nullptr; 180 181 /// If the current module uses dwarf CFI annotations strictly for debugging. 182 bool isCFIMoveForDebugging = false; 183 184 protected: 185 explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer); 186 187 public: 188 ~AsmPrinter() override; 189 getDwarfDebug()190 DwarfDebug *getDwarfDebug() { return DD; } getDwarfDebug()191 DwarfDebug *getDwarfDebug() const { return DD; } 192 193 uint16_t getDwarfVersion() const; 194 void setDwarfVersion(uint16_t Version); 195 196 bool isPositionIndependent() const; 197 198 /// Return true if assembly output should contain comments. isVerbose()199 bool isVerbose() const { return VerboseAsm; } 200 201 /// Return a unique ID for the current function. 202 unsigned getFunctionNumber() const; 203 204 /// Return symbol for the function pseudo stack if the stack frame is not a 205 /// register based. getFunctionFrameSymbol()206 virtual const MCSymbol *getFunctionFrameSymbol() const { return nullptr; } 207 getFunctionBegin()208 MCSymbol *getFunctionBegin() const { return CurrentFnBegin; } getFunctionEnd()209 MCSymbol *getFunctionEnd() const { return CurrentFnEnd; } 210 MCSymbol *getCurExceptionSym(); 211 212 /// Return information about object file lowering. 213 const TargetLoweringObjectFile &getObjFileLowering() const; 214 215 /// Return information about data layout. 216 const DataLayout &getDataLayout() const; 217 218 /// Return the pointer size from the TargetMachine 219 unsigned getPointerSize() const; 220 221 /// Return information about subtarget. 222 const MCSubtargetInfo &getSubtargetInfo() const; 223 224 void EmitToStreamer(MCStreamer &S, const MCInst &Inst); 225 226 /// Return the current section we are emitting to. 227 const MCSection *getCurrentSection() const; 228 229 void getNameWithPrefix(SmallVectorImpl<char> &Name, 230 const GlobalValue *GV) const; 231 232 MCSymbol *getSymbol(const GlobalValue *GV) const; 233 234 //===------------------------------------------------------------------===// 235 // XRay instrumentation implementation. 236 //===------------------------------------------------------------------===// 237 public: 238 // This describes the kind of sled we're storing in the XRay table. 239 enum class SledKind : uint8_t { 240 FUNCTION_ENTER = 0, 241 FUNCTION_EXIT = 1, 242 TAIL_CALL = 2, 243 LOG_ARGS_ENTER = 3, 244 CUSTOM_EVENT = 4, 245 TYPED_EVENT = 5, 246 }; 247 248 // The table will contain these structs that point to the sled, the function 249 // containing the sled, and what kind of sled (and whether they should always 250 // be instrumented). We also use a version identifier that the runtime can use 251 // to decide what to do with the sled, depending on the version of the sled. 252 struct XRayFunctionEntry { 253 const MCSymbol *Sled; 254 const MCSymbol *Function; 255 SledKind Kind; 256 bool AlwaysInstrument; 257 const class Function *Fn; 258 uint8_t Version; 259 260 void emit(int, MCStreamer *, const MCSymbol *) const; 261 }; 262 263 // All the sleds to be emitted. 264 SmallVector<XRayFunctionEntry, 4> Sleds; 265 266 // A unique ID used for ELF sections associated with a particular function. 267 unsigned XRayFnUniqueID = 0; 268 269 // Helper function to record a given XRay sled. 270 void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, 271 uint8_t Version = 0); 272 273 /// Emit a table with all XRay instrumentation points. 274 void emitXRayTable(); 275 276 //===------------------------------------------------------------------===// 277 // MachineFunctionPass Implementation. 278 //===------------------------------------------------------------------===// 279 280 /// Record analysis usage. 281 void getAnalysisUsage(AnalysisUsage &AU) const override; 282 283 /// Set up the AsmPrinter when we are working on a new module. If your pass 284 /// overrides this, it must make sure to explicitly call this implementation. 285 bool doInitialization(Module &M) override; 286 287 /// Shut down the asmprinter. If you override this in your pass, you must make 288 /// sure to call it explicitly. 289 bool doFinalization(Module &M) override; 290 291 /// Emit the specified function out to the OutStreamer. runOnMachineFunction(MachineFunction & MF)292 bool runOnMachineFunction(MachineFunction &MF) override { 293 SetupMachineFunction(MF); 294 EmitFunctionBody(); 295 return false; 296 } 297 298 //===------------------------------------------------------------------===// 299 // Coarse grained IR lowering routines. 300 //===------------------------------------------------------------------===// 301 302 /// This should be called when a new MachineFunction is being processed from 303 /// runOnMachineFunction. 304 void SetupMachineFunction(MachineFunction &MF); 305 306 /// This method emits the body and trailer for a function. 307 void EmitFunctionBody(); 308 309 void emitCFIInstruction(const MachineInstr &MI); 310 311 void emitFrameAlloc(const MachineInstr &MI); 312 313 void emitStackSizeSection(const MachineFunction &MF); 314 315 enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug }; 316 CFIMoveType needsCFIMoves() const; 317 318 /// Returns false if needsCFIMoves() == CFI_M_EH for any function 319 /// in the module. needsOnlyDebugCFIMoves()320 bool needsOnlyDebugCFIMoves() const { return isCFIMoveForDebugging; } 321 322 bool needsSEHMoves(); 323 324 /// Print to the current output stream assembly representations of the 325 /// constants in the constant pool MCP. This is used to print out constants 326 /// which have been "spilled to memory" by the code generator. 327 virtual void EmitConstantPool(); 328 329 /// Print assembly representations of the jump tables used by the current 330 /// function to the current output stream. 331 virtual void EmitJumpTableInfo(); 332 333 /// Emit the specified global variable to the .s file. 334 virtual void EmitGlobalVariable(const GlobalVariable *GV); 335 336 /// Check to see if the specified global is a special global used by LLVM. If 337 /// so, emit it and return true, otherwise do nothing and return false. 338 bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); 339 340 /// Emit an alignment directive to the specified power of two boundary. For 341 /// example, if you pass in 3 here, you will get an 8 byte alignment. If a 342 /// global value is specified, and if that global has an explicit alignment 343 /// requested, it will override the alignment request if required for 344 /// correctness. 345 void EmitAlignment(unsigned NumBits, const GlobalObject *GV = nullptr) const; 346 347 /// Lower the specified LLVM Constant to an MCExpr. 348 virtual const MCExpr *lowerConstant(const Constant *CV); 349 350 /// Print a general LLVM constant to the .s file. 351 void EmitGlobalConstant(const DataLayout &DL, const Constant *CV); 352 353 /// Unnamed constant global variables solely contaning a pointer to 354 /// another globals variable act like a global variable "proxy", or GOT 355 /// equivalents, i.e., it's only used to hold the address of the latter. One 356 /// optimization is to replace accesses to these proxies by using the GOT 357 /// entry for the final global instead. Hence, we select GOT equivalent 358 /// candidates among all the module global variables, avoid emitting them 359 /// unnecessarily and finally replace references to them by pc relative 360 /// accesses to GOT entries. 361 void computeGlobalGOTEquivs(Module &M); 362 363 /// Constant expressions using GOT equivalent globals may not be 364 /// eligible for PC relative GOT entry conversion, in such cases we need to 365 /// emit the proxies we previously omitted in EmitGlobalVariable. 366 void emitGlobalGOTEquivs(); 367 368 //===------------------------------------------------------------------===// 369 // Overridable Hooks 370 //===------------------------------------------------------------------===// 371 372 // Targets can, or in the case of EmitInstruction, must implement these to 373 // customize output. 374 375 /// This virtual method can be overridden by targets that want to emit 376 /// something at the start of their file. EmitStartOfAsmFile(Module &)377 virtual void EmitStartOfAsmFile(Module &) {} 378 379 /// This virtual method can be overridden by targets that want to emit 380 /// something at the end of their file. EmitEndOfAsmFile(Module &)381 virtual void EmitEndOfAsmFile(Module &) {} 382 383 /// Targets can override this to emit stuff before the first basic block in 384 /// the function. EmitFunctionBodyStart()385 virtual void EmitFunctionBodyStart() {} 386 387 /// Targets can override this to emit stuff after the last basic block in the 388 /// function. EmitFunctionBodyEnd()389 virtual void EmitFunctionBodyEnd() {} 390 391 /// Targets can override this to emit stuff at the start of a basic block. 392 /// By default, this method prints the label for the specified 393 /// MachineBasicBlock, an alignment (if present) and a comment describing it 394 /// if appropriate. 395 virtual void EmitBasicBlockStart(const MachineBasicBlock &MBB) const; 396 397 /// Targets can override this to emit stuff at the end of a basic block. 398 virtual void EmitBasicBlockEnd(const MachineBasicBlock &MBB); 399 400 /// Targets should implement this to emit instructions. EmitInstruction(const MachineInstr *)401 virtual void EmitInstruction(const MachineInstr *) { 402 llvm_unreachable("EmitInstruction not implemented"); 403 } 404 405 /// Return the symbol for the specified constant pool entry. 406 virtual MCSymbol *GetCPISymbol(unsigned CPID) const; 407 408 virtual void EmitFunctionEntryLabel(); 409 410 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); 411 412 /// Targets can override this to change how global constants that are part of 413 /// a C++ static/global constructor list are emitted. EmitXXStructor(const DataLayout & DL,const Constant * CV)414 virtual void EmitXXStructor(const DataLayout &DL, const Constant *CV) { 415 EmitGlobalConstant(DL, CV); 416 } 417 418 /// Return true if the basic block has exactly one predecessor and the control 419 /// transfer mechanism between the predecessor and this block is a 420 /// fall-through. 421 virtual bool 422 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; 423 424 /// Targets can override this to customize the output of IMPLICIT_DEF 425 /// instructions in verbose mode. 426 virtual void emitImplicitDef(const MachineInstr *MI) const; 427 428 //===------------------------------------------------------------------===// 429 // Symbol Lowering Routines. 430 //===------------------------------------------------------------------===// 431 432 MCSymbol *createTempSymbol(const Twine &Name) const; 433 434 /// Return the MCSymbol for a private symbol with global value name as its 435 /// base, with the specified suffix. 436 MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV, 437 StringRef Suffix) const; 438 439 /// Return the MCSymbol for the specified ExternalSymbol. 440 MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; 441 442 /// Return the symbol for the specified jump table entry. 443 MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; 444 445 /// Return the symbol for the specified jump table .set 446 /// FIXME: privatize to AsmPrinter. 447 MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const; 448 449 /// Return the MCSymbol used to satisfy BlockAddress uses of the specified 450 /// basic block. 451 MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; 452 MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const; 453 454 //===------------------------------------------------------------------===// 455 // Emission Helper Routines. 456 //===------------------------------------------------------------------===// 457 458 /// This is just convenient handler for printing offsets. 459 void printOffset(int64_t Offset, raw_ostream &OS) const; 460 461 /// Emit a byte directive and value. 462 void emitInt8(int Value) const; 463 464 /// Emit a short directive and value. 465 void emitInt16(int Value) const; 466 467 /// Emit a long directive and value. 468 void emitInt32(int Value) const; 469 470 /// Emit a long long directive and value. 471 void emitInt64(uint64_t Value) const; 472 473 /// Emit something like ".long Hi-Lo" where the size in bytes of the directive 474 /// is specified by Size and Hi/Lo specify the labels. This implicitly uses 475 /// .set if it is available. 476 void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 477 unsigned Size) const; 478 479 /// Emit something like ".uleb128 Hi-Lo". 480 void EmitLabelDifferenceAsULEB128(const MCSymbol *Hi, 481 const MCSymbol *Lo) const; 482 483 /// Emit something like ".long Label+Offset" where the size in bytes of the 484 /// directive is specified by Size and Label specifies the label. This 485 /// implicitly uses .set if it is available. 486 void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, 487 unsigned Size, bool IsSectionRelative = false) const; 488 489 /// Emit something like ".long Label" where the size in bytes of the directive 490 /// is specified by Size and Label specifies the label. 491 void EmitLabelReference(const MCSymbol *Label, unsigned Size, 492 bool IsSectionRelative = false) const { 493 EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative); 494 } 495 496 /// Emit something like ".long Label + Offset". 497 void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const; 498 499 //===------------------------------------------------------------------===// 500 // Dwarf Emission Helper Routines 501 //===------------------------------------------------------------------===// 502 503 /// Emit the specified signed leb128 value. 504 void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const; 505 506 /// Emit the specified unsigned leb128 value. 507 void EmitULEB128(uint64_t Value, const char *Desc = nullptr) const; 508 509 /// Emit a .byte 42 directive that corresponds to an encoding. If verbose 510 /// assembly output is enabled, we output comments describing the encoding. 511 /// Desc is a string saying what the encoding is specifying (e.g. "LSDA"). 512 void EmitEncodingByte(unsigned Val, const char *Desc = nullptr) const; 513 514 /// Return the size of the encoding in bytes. 515 unsigned GetSizeOfEncodedValue(unsigned Encoding) const; 516 517 /// Emit reference to a ttype global with a specified encoding. 518 void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const; 519 520 /// Emit a reference to a symbol for use in dwarf. Different object formats 521 /// represent this in different ways. Some use a relocation others encode 522 /// the label offset in its section. 523 void emitDwarfSymbolReference(const MCSymbol *Label, 524 bool ForceOffset = false) const; 525 526 /// Emit the 4-byte offset of a string from the start of its section. 527 /// 528 /// When possible, emit a DwarfStringPool section offset without any 529 /// relocations, and without using the symbol. Otherwise, defers to \a 530 /// emitDwarfSymbolReference(). 531 void emitDwarfStringOffset(DwarfStringPoolEntry S) const; 532 533 /// Emit the 4-byte offset of a string from the start of its section. emitDwarfStringOffset(DwarfStringPoolEntryRef S)534 void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const { 535 emitDwarfStringOffset(S.getEntry()); 536 } 537 538 /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. getISAEncoding()539 virtual unsigned getISAEncoding() { return 0; } 540 541 /// Emit the directive and value for debug thread local expression 542 /// 543 /// \p Value - The value to emit. 544 /// \p Size - The size of the integer (in bytes) to emit. 545 virtual void EmitDebugThreadLocal(const MCExpr *Value, unsigned Size) const; 546 547 //===------------------------------------------------------------------===// 548 // Dwarf Lowering Routines 549 //===------------------------------------------------------------------===// 550 551 /// Emit frame instruction to describe the layout of the frame. 552 void emitCFIInstruction(const MCCFIInstruction &Inst) const; 553 554 /// Emit Dwarf abbreviation table. emitDwarfAbbrevs(const T & Abbrevs)555 template <typename T> void emitDwarfAbbrevs(const T &Abbrevs) const { 556 // For each abbreviation. 557 for (const auto &Abbrev : Abbrevs) 558 emitDwarfAbbrev(*Abbrev); 559 560 // Mark end of abbreviations. 561 EmitULEB128(0, "EOM(3)"); 562 } 563 564 void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const; 565 566 /// Recursively emit Dwarf DIE tree. 567 void emitDwarfDIE(const DIE &Die) const; 568 569 //===------------------------------------------------------------------===// 570 // Inline Asm Support 571 //===------------------------------------------------------------------===// 572 573 // These are hooks that targets can override to implement inline asm 574 // support. These should probably be moved out of AsmPrinter someday. 575 576 /// Print information related to the specified machine instr that is 577 /// independent of the operand, and may be independent of the instr itself. 578 /// This can be useful for portably encoding the comment character or other 579 /// bits of target-specific knowledge into the asmstrings. The syntax used is 580 /// ${:comment}. Targets can override this to add support for their own 581 /// strange codes. 582 virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, 583 const char *Code) const; 584 585 /// Print the specified operand of MI, an INLINEASM instruction, using the 586 /// specified assembler variant. Targets should override this to format as 587 /// appropriate. This method can return true if the operand is erroneous. 588 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 589 unsigned AsmVariant, const char *ExtraCode, 590 raw_ostream &OS); 591 592 /// Print the specified operand of MI, an INLINEASM instruction, using the 593 /// specified assembler variant as an address. Targets should override this to 594 /// format as appropriate. This method can return true if the operand is 595 /// erroneous. 596 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 597 unsigned AsmVariant, const char *ExtraCode, 598 raw_ostream &OS); 599 600 /// Let the target do anything it needs to do before emitting inlineasm. 601 /// \p StartInfo - the subtarget info before parsing inline asm 602 virtual void emitInlineAsmStart() const; 603 604 /// Let the target do anything it needs to do after emitting inlineasm. 605 /// This callback can be used restore the original mode in case the 606 /// inlineasm contains directives to switch modes. 607 /// \p StartInfo - the original subtarget info before inline asm 608 /// \p EndInfo - the final subtarget info after parsing the inline asm, 609 /// or NULL if the value is unknown. 610 virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 611 const MCSubtargetInfo *EndInfo) const; 612 613 private: 614 /// Private state for PrintSpecial() 615 // Assign a unique ID to this machine instruction. 616 mutable const MachineInstr *LastMI = nullptr; 617 mutable unsigned LastFn = 0; 618 mutable unsigned Counter = ~0U; 619 620 /// This method emits the header for the current function. 621 virtual void EmitFunctionHeader(); 622 623 /// Emit a blob of inline asm to the output streamer. 624 void 625 EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, 626 const MCTargetOptions &MCOptions, 627 const MDNode *LocMDNode = nullptr, 628 InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const; 629 630 /// This method formats and emits the specified machine instruction that is an 631 /// inline asm. 632 void EmitInlineAsm(const MachineInstr *MI) const; 633 634 //===------------------------------------------------------------------===// 635 // Internal Implementation Details 636 //===------------------------------------------------------------------===// 637 638 /// This emits visibility information about symbol, if this is supported by 639 /// the target. 640 void EmitVisibility(MCSymbol *Sym, unsigned Visibility, 641 bool IsDefinition = true) const; 642 643 void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const; 644 645 void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, 646 const MachineBasicBlock *MBB, unsigned uid) const; 647 void EmitLLVMUsedList(const ConstantArray *InitList); 648 /// Emit llvm.ident metadata in an '.ident' directive. 649 void EmitModuleIdents(Module &M); 650 void EmitXXStructorList(const DataLayout &DL, const Constant *List, 651 bool isCtor); 652 653 GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S); 654 /// Emit GlobalAlias or GlobalIFunc. 655 void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS); 656 void setupCodePaddingContext(const MachineBasicBlock &MBB, 657 MCCodePaddingContext &Context) const; 658 }; 659 660 } // end namespace llvm 661 662 #endif // LLVM_CODEGEN_ASMPRINTER_H 663