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