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