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