|
|
|||
File indexing completed on 2026-05-10 08:43:26
0001 //===- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework ---------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file contains a class to be used as the base class for target specific 0010 // asm writers. This class primarily handles common functionality used by 0011 // all asm writers. 0012 // 0013 //===----------------------------------------------------------------------===// 0014 0015 #ifndef LLVM_CODEGEN_ASMPRINTER_H 0016 #define LLVM_CODEGEN_ASMPRINTER_H 0017 0018 #include "llvm/ADT/DenseMap.h" 0019 #include "llvm/ADT/MapVector.h" 0020 #include "llvm/ADT/SmallVector.h" 0021 #include "llvm/BinaryFormat/Dwarf.h" 0022 #include "llvm/CodeGen/DwarfStringPoolEntry.h" 0023 #include "llvm/CodeGen/MachineFunctionPass.h" 0024 #include "llvm/CodeGen/StackMaps.h" 0025 #include "llvm/DebugInfo/CodeView/CodeView.h" 0026 #include "llvm/IR/InlineAsm.h" 0027 #include "llvm/Support/ErrorHandling.h" 0028 #include <cstdint> 0029 #include <memory> 0030 #include <utility> 0031 #include <vector> 0032 0033 namespace llvm { 0034 0035 class AddrLabelMap; 0036 class AsmPrinterHandler; 0037 class BasicBlock; 0038 class BlockAddress; 0039 class Constant; 0040 class ConstantArray; 0041 class ConstantPtrAuth; 0042 class DataLayout; 0043 class DebugHandlerBase; 0044 class DIE; 0045 class DIEAbbrev; 0046 class DwarfDebug; 0047 class EHStreamer; 0048 class GCMetadataPrinter; 0049 class GCStrategy; 0050 class GlobalAlias; 0051 class GlobalObject; 0052 class GlobalValue; 0053 class GlobalVariable; 0054 class MachineBasicBlock; 0055 class MachineConstantPoolValue; 0056 class MachineDominatorTree; 0057 class MachineFunction; 0058 class MachineInstr; 0059 class MachineJumpTableInfo; 0060 class MachineLoopInfo; 0061 class MachineModuleInfo; 0062 class MachineOptimizationRemarkEmitter; 0063 class MCAsmInfo; 0064 class MCCFIInstruction; 0065 class MCContext; 0066 class MCExpr; 0067 class MCInst; 0068 class MCSection; 0069 class MCStreamer; 0070 class MCSubtargetInfo; 0071 class MCSymbol; 0072 class MCTargetOptions; 0073 class MDNode; 0074 class Module; 0075 class PseudoProbeHandler; 0076 class raw_ostream; 0077 class StringRef; 0078 class TargetLoweringObjectFile; 0079 class TargetMachine; 0080 class Twine; 0081 0082 namespace remarks { 0083 class RemarkStreamer; 0084 } 0085 0086 /// This class is intended to be used as a driving class for all asm writers. 0087 class AsmPrinter : public MachineFunctionPass { 0088 public: 0089 /// Target machine description. 0090 TargetMachine &TM; 0091 0092 /// Target Asm Printer information. 0093 const MCAsmInfo *MAI = nullptr; 0094 0095 /// This is the context for the output file that we are streaming. This owns 0096 /// all of the global MC-related objects for the generated translation unit. 0097 MCContext &OutContext; 0098 0099 /// This is the MCStreamer object for the file we are generating. This 0100 /// contains the transient state for the current translation unit that we are 0101 /// generating (such as the current section etc). 0102 std::unique_ptr<MCStreamer> OutStreamer; 0103 0104 /// The current machine function. 0105 MachineFunction *MF = nullptr; 0106 0107 /// This is a pointer to the current MachineModuleInfo. 0108 MachineModuleInfo *MMI = nullptr; 0109 0110 /// This is a pointer to the current MachineDominatorTree. 0111 MachineDominatorTree *MDT = nullptr; 0112 0113 /// This is a pointer to the current MachineLoopInfo. 0114 MachineLoopInfo *MLI = nullptr; 0115 0116 /// Optimization remark emitter. 0117 MachineOptimizationRemarkEmitter *ORE = nullptr; 0118 0119 /// The symbol for the entry in __patchable_function_entires. 0120 MCSymbol *CurrentPatchableFunctionEntrySym = nullptr; 0121 0122 /// The symbol for the current function. This is recalculated at the beginning 0123 /// of each call to runOnMachineFunction(). 0124 MCSymbol *CurrentFnSym = nullptr; 0125 0126 /// The symbol for the current function descriptor on AIX. This is created 0127 /// at the beginning of each call to SetupMachineFunction(). 0128 MCSymbol *CurrentFnDescSym = nullptr; 0129 0130 /// The symbol used to represent the start of the current function for the 0131 /// purpose of calculating its size (e.g. using the .size directive). By 0132 /// default, this is equal to CurrentFnSym. 0133 MCSymbol *CurrentFnSymForSize = nullptr; 0134 0135 /// Map a basic block section ID to the begin and end symbols of that section 0136 /// which determine the section's range. 0137 struct MBBSectionRange { 0138 MCSymbol *BeginLabel, *EndLabel; 0139 }; 0140 0141 MapVector<MBBSectionID, MBBSectionRange> MBBSectionRanges; 0142 0143 /// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of 0144 /// its number of uses by other globals. 0145 using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>; 0146 MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; 0147 0148 // Flags representing which CFI section is required for a function/module. 0149 enum class CFISection : unsigned { 0150 None = 0, ///< Do not emit either .eh_frame or .debug_frame 0151 EH = 1, ///< Emit .eh_frame 0152 Debug = 2 ///< Emit .debug_frame 0153 }; 0154 0155 private: 0156 MCSymbol *CurrentFnEnd = nullptr; 0157 0158 /// Map a basic block section ID to the exception symbol associated with that 0159 /// section. Map entries are assigned and looked up via 0160 /// AsmPrinter::getMBBExceptionSym. 0161 DenseMap<MBBSectionID, MCSymbol *> MBBSectionExceptionSyms; 0162 0163 // The symbol used to represent the start of the current BB section of the 0164 // function. This is used to calculate the size of the BB section. 0165 MCSymbol *CurrentSectionBeginSym = nullptr; 0166 0167 /// This map keeps track of which symbol is being used for the specified basic 0168 /// block's address of label. 0169 std::unique_ptr<AddrLabelMap> AddrLabelSymbols; 0170 0171 /// The garbage collection metadata printer table. 0172 DenseMap<GCStrategy *, std::unique_ptr<GCMetadataPrinter>> GCMetadataPrinters; 0173 0174 /// Emit comments in assembly output if this is true. 0175 bool VerboseAsm; 0176 0177 /// Output stream for the stack usage file (i.e., .su file). 0178 std::unique_ptr<raw_fd_ostream> StackUsageStream; 0179 0180 /// List of symbols to be inserted into PC sections. 0181 DenseMap<const MDNode *, SmallVector<const MCSymbol *>> PCSectionsSymbols; 0182 0183 static char ID; 0184 0185 protected: 0186 MCSymbol *CurrentFnBegin = nullptr; 0187 0188 /// For dso_local functions, the current $local alias for the function. 0189 MCSymbol *CurrentFnBeginLocal = nullptr; 0190 0191 /// A handle to the EH info emitter (if present). 0192 // Only for EHStreamer subtypes, but some C++ compilers will incorrectly warn 0193 // us if we declare that directly. 0194 SmallVector<std::unique_ptr<AsmPrinterHandler>, 1> EHHandlers; 0195 0196 // A vector of all Debuginfo emitters we should use. Protected so that 0197 // targets can add their own. This vector maintains ownership of the 0198 // emitters. 0199 SmallVector<std::unique_ptr<AsmPrinterHandler>, 2> Handlers; 0200 size_t NumUserHandlers = 0; 0201 0202 StackMaps SM; 0203 0204 private: 0205 /// If generated on the fly this own the instance. 0206 std::unique_ptr<MachineDominatorTree> OwnedMDT; 0207 0208 /// If generated on the fly this own the instance. 0209 std::unique_ptr<MachineLoopInfo> OwnedMLI; 0210 0211 /// If the target supports dwarf debug info, this pointer is non-null. 0212 DwarfDebug *DD = nullptr; 0213 0214 /// A handler that supports pseudo probe emission with embedded inline 0215 /// context. 0216 std::unique_ptr<PseudoProbeHandler> PP; 0217 0218 /// CFISection type the module needs i.e. either .eh_frame or .debug_frame. 0219 CFISection ModuleCFISection = CFISection::None; 0220 0221 /// True if the module contains split-stack functions. This is used to 0222 /// emit .note.GNU-split-stack section as required by the linker for 0223 /// special handling split-stack function calling no-split-stack function. 0224 bool HasSplitStack = false; 0225 0226 /// True if the module contains no-split-stack functions. This is used to emit 0227 /// .note.GNU-no-split-stack section when it also contains functions without a 0228 /// split stack prologue. 0229 bool HasNoSplitStack = false; 0230 0231 /// True if debugging information is available in this module. 0232 bool DbgInfoAvailable = false; 0233 0234 protected: 0235 explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer); 0236 0237 public: 0238 ~AsmPrinter() override; 0239 0240 DwarfDebug *getDwarfDebug() { return DD; } 0241 DwarfDebug *getDwarfDebug() const { return DD; } 0242 0243 uint16_t getDwarfVersion() const; 0244 void setDwarfVersion(uint16_t Version); 0245 0246 bool isDwarf64() const; 0247 0248 /// Returns 4 for DWARF32 and 8 for DWARF64. 0249 unsigned int getDwarfOffsetByteSize() const; 0250 0251 /// Returns 4 for DWARF32 and 12 for DWARF64. 0252 unsigned int getUnitLengthFieldByteSize() const; 0253 0254 /// Returns information about the byte size of DW_FORM values. 0255 dwarf::FormParams getDwarfFormParams() const; 0256 0257 bool isPositionIndependent() const; 0258 0259 /// Return true if assembly output should contain comments. 0260 bool isVerbose() const { return VerboseAsm; } 0261 0262 /// Return a unique ID for the current function. 0263 unsigned getFunctionNumber() const; 0264 0265 /// Return symbol for the function pseudo stack if the stack frame is not a 0266 /// register based. 0267 virtual const MCSymbol *getFunctionFrameSymbol() const { return nullptr; } 0268 0269 MCSymbol *getFunctionBegin() const { return CurrentFnBegin; } 0270 MCSymbol *getFunctionEnd() const { return CurrentFnEnd; } 0271 0272 // Return the exception symbol associated with the MBB section containing a 0273 // given basic block. 0274 MCSymbol *getMBBExceptionSym(const MachineBasicBlock &MBB); 0275 0276 /// Return the symbol to be used for the specified basic block when its 0277 /// address is taken. This cannot be its normal LBB label because the block 0278 /// may be accessed outside its containing function. 0279 MCSymbol *getAddrLabelSymbol(const BasicBlock *BB) { 0280 return getAddrLabelSymbolToEmit(BB).front(); 0281 } 0282 0283 /// Return the symbol to be used for the specified basic block when its 0284 /// address is taken. If other blocks were RAUW'd to this one, we may have 0285 /// to emit them as well, return the whole set. 0286 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB); 0287 0288 /// If the specified function has had any references to address-taken blocks 0289 /// generated, but the block got deleted, return the symbol now so we can 0290 /// emit it. This prevents emitting a reference to a symbol that has no 0291 /// definition. 0292 void takeDeletedSymbolsForFunction(const Function *F, 0293 std::vector<MCSymbol *> &Result); 0294 0295 /// Return information about object file lowering. 0296 const TargetLoweringObjectFile &getObjFileLowering() const; 0297 0298 /// Return information about data layout. 0299 const DataLayout &getDataLayout() const; 0300 0301 /// Return the pointer size from the TargetMachine 0302 unsigned getPointerSize() const; 0303 0304 /// Return information about subtarget. 0305 const MCSubtargetInfo &getSubtargetInfo() const; 0306 0307 void EmitToStreamer(MCStreamer &S, const MCInst &Inst); 0308 0309 /// Emits inital debug location directive. 0310 void emitInitialRawDwarfLocDirective(const MachineFunction &MF); 0311 0312 /// Return the current section we are emitting to. 0313 const MCSection *getCurrentSection() const; 0314 0315 void getNameWithPrefix(SmallVectorImpl<char> &Name, 0316 const GlobalValue *GV) const; 0317 0318 MCSymbol *getSymbol(const GlobalValue *GV) const; 0319 0320 /// Similar to getSymbol() but preferred for references. On ELF, this uses a 0321 /// local symbol if a reference to GV is guaranteed to be resolved to the 0322 /// definition in the same module. 0323 MCSymbol *getSymbolPreferLocal(const GlobalValue &GV) const; 0324 0325 bool doesDwarfUseRelocationsAcrossSections() const { 0326 return DwarfUsesRelocationsAcrossSections; 0327 } 0328 0329 void setDwarfUsesRelocationsAcrossSections(bool Enable) { 0330 DwarfUsesRelocationsAcrossSections = Enable; 0331 } 0332 0333 //===------------------------------------------------------------------===// 0334 // XRay instrumentation implementation. 0335 //===------------------------------------------------------------------===// 0336 public: 0337 // This describes the kind of sled we're storing in the XRay table. 0338 enum class SledKind : uint8_t { 0339 FUNCTION_ENTER = 0, 0340 FUNCTION_EXIT = 1, 0341 TAIL_CALL = 2, 0342 LOG_ARGS_ENTER = 3, 0343 CUSTOM_EVENT = 4, 0344 TYPED_EVENT = 5, 0345 }; 0346 0347 // The table will contain these structs that point to the sled, the function 0348 // containing the sled, and what kind of sled (and whether they should always 0349 // be instrumented). We also use a version identifier that the runtime can use 0350 // to decide what to do with the sled, depending on the version of the sled. 0351 struct XRayFunctionEntry { 0352 const MCSymbol *Sled; 0353 const MCSymbol *Function; 0354 SledKind Kind; 0355 bool AlwaysInstrument; 0356 const class Function *Fn; 0357 uint8_t Version; 0358 0359 void emit(int, MCStreamer *) const; 0360 }; 0361 0362 // All the sleds to be emitted. 0363 SmallVector<XRayFunctionEntry, 4> Sleds; 0364 0365 // Helper function to record a given XRay sled. 0366 void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, 0367 uint8_t Version = 0); 0368 0369 /// Emit a table with all XRay instrumentation points. 0370 void emitXRayTable(); 0371 0372 void emitPatchableFunctionEntries(); 0373 0374 //===------------------------------------------------------------------===// 0375 // MachineFunctionPass Implementation. 0376 //===------------------------------------------------------------------===// 0377 0378 /// Record analysis usage. 0379 void getAnalysisUsage(AnalysisUsage &AU) const override; 0380 0381 /// Set up the AsmPrinter when we are working on a new module. If your pass 0382 /// overrides this, it must make sure to explicitly call this implementation. 0383 bool doInitialization(Module &M) override; 0384 0385 /// Shut down the asmprinter. If you override this in your pass, you must make 0386 /// sure to call it explicitly. 0387 bool doFinalization(Module &M) override; 0388 0389 /// Emit the specified function out to the OutStreamer. 0390 bool runOnMachineFunction(MachineFunction &MF) override { 0391 SetupMachineFunction(MF); 0392 emitFunctionBody(); 0393 return false; 0394 } 0395 0396 //===------------------------------------------------------------------===// 0397 // Coarse grained IR lowering routines. 0398 //===------------------------------------------------------------------===// 0399 0400 /// This should be called when a new MachineFunction is being processed from 0401 /// runOnMachineFunction. 0402 virtual void SetupMachineFunction(MachineFunction &MF); 0403 0404 /// This method emits the body and trailer for a function. 0405 void emitFunctionBody(); 0406 0407 void emitCFIInstruction(const MachineInstr &MI); 0408 0409 void emitFrameAlloc(const MachineInstr &MI); 0410 0411 void emitStackSizeSection(const MachineFunction &MF); 0412 0413 void emitStackUsage(const MachineFunction &MF); 0414 0415 void emitBBAddrMapSection(const MachineFunction &MF); 0416 0417 void emitKCFITrapEntry(const MachineFunction &MF, const MCSymbol *Symbol); 0418 virtual void emitKCFITypeId(const MachineFunction &MF); 0419 0420 void emitPseudoProbe(const MachineInstr &MI); 0421 0422 void emitRemarksSection(remarks::RemarkStreamer &RS); 0423 0424 /// Emits a label as reference for PC sections. 0425 void emitPCSectionsLabel(const MachineFunction &MF, const MDNode &MD); 0426 0427 /// Emits the PC sections collected from instructions. 0428 void emitPCSections(const MachineFunction &MF); 0429 0430 /// Get the CFISection type for a function. 0431 CFISection getFunctionCFISectionType(const Function &F) const; 0432 0433 /// Get the CFISection type for a function. 0434 CFISection getFunctionCFISectionType(const MachineFunction &MF) const; 0435 0436 /// Get the CFISection type for the module. 0437 CFISection getModuleCFISectionType() const { return ModuleCFISection; } 0438 0439 /// Returns true if valid debug info is present. 0440 bool hasDebugInfo() const { return DbgInfoAvailable; } 0441 0442 bool needsSEHMoves(); 0443 0444 /// Since emitting CFI unwind information is entangled with supporting the 0445 /// exceptions, this returns true for platforms which use CFI unwind 0446 /// information for other purposes (debugging, sanitizers, ...) when 0447 /// `MCAsmInfo::ExceptionsType == ExceptionHandling::None`. 0448 bool usesCFIWithoutEH() const; 0449 0450 /// Print to the current output stream assembly representations of the 0451 /// constants in the constant pool MCP. This is used to print out constants 0452 /// which have been "spilled to memory" by the code generator. 0453 virtual void emitConstantPool(); 0454 0455 /// Print assembly representations of the jump tables used by the current 0456 /// function to the current output stream. 0457 virtual void emitJumpTableInfo(); 0458 0459 /// Emit the specified global variable to the .s file. 0460 virtual void emitGlobalVariable(const GlobalVariable *GV); 0461 0462 /// Check to see if the specified global is a special global used by LLVM. If 0463 /// so, emit it and return true, otherwise do nothing and return false. 0464 bool emitSpecialLLVMGlobal(const GlobalVariable *GV); 0465 0466 /// `llvm.global_ctors` and `llvm.global_dtors` are arrays of Structor 0467 /// structs. 0468 /// 0469 /// Priority - init priority 0470 /// Func - global initialization or global clean-up function 0471 /// ComdatKey - associated data 0472 struct Structor { 0473 int Priority = 0; 0474 Constant *Func = nullptr; 0475 GlobalValue *ComdatKey = nullptr; 0476 0477 Structor() = default; 0478 }; 0479 0480 /// This method gathers an array of Structors and then sorts them out by 0481 /// Priority. 0482 /// @param List The initializer of `llvm.global_ctors` or `llvm.global_dtors` 0483 /// array. 0484 /// @param[out] Structors Sorted Structor structs by Priority. 0485 void preprocessXXStructorList(const DataLayout &DL, const Constant *List, 0486 SmallVector<Structor, 8> &Structors); 0487 0488 /// This method emits `llvm.global_ctors` or `llvm.global_dtors` list. 0489 virtual void emitXXStructorList(const DataLayout &DL, const Constant *List, 0490 bool IsCtor); 0491 0492 /// Emit an alignment directive to the specified power of two boundary. If a 0493 /// global value is specified, and if that global has an explicit alignment 0494 /// requested, it will override the alignment request if required for 0495 /// correctness. 0496 void emitAlignment(Align Alignment, const GlobalObject *GV = nullptr, 0497 unsigned MaxBytesToEmit = 0) const; 0498 0499 /// Lower the specified LLVM Constant to an MCExpr. 0500 virtual const MCExpr *lowerConstant(const Constant *CV); 0501 0502 /// Print a general LLVM constant to the .s file. 0503 /// On AIX, when an alias refers to a sub-element of a global variable, the 0504 /// label of that alias needs to be emitted before the corresponding element. 0505 using AliasMapTy = DenseMap<uint64_t, SmallVector<const GlobalAlias *, 1>>; 0506 void emitGlobalConstant(const DataLayout &DL, const Constant *CV, 0507 AliasMapTy *AliasList = nullptr); 0508 0509 /// Unnamed constant global variables solely contaning a pointer to 0510 /// another globals variable act like a global variable "proxy", or GOT 0511 /// equivalents, i.e., it's only used to hold the address of the latter. One 0512 /// optimization is to replace accesses to these proxies by using the GOT 0513 /// entry for the final global instead. Hence, we select GOT equivalent 0514 /// candidates among all the module global variables, avoid emitting them 0515 /// unnecessarily and finally replace references to them by pc relative 0516 /// accesses to GOT entries. 0517 void computeGlobalGOTEquivs(Module &M); 0518 0519 /// Constant expressions using GOT equivalent globals may not be 0520 /// eligible for PC relative GOT entry conversion, in such cases we need to 0521 /// emit the proxies we previously omitted in EmitGlobalVariable. 0522 void emitGlobalGOTEquivs(); 0523 0524 /// Emit the stack maps. 0525 void emitStackMaps(); 0526 0527 //===------------------------------------------------------------------===// 0528 // Overridable Hooks 0529 //===------------------------------------------------------------------===// 0530 0531 void addAsmPrinterHandler(std::unique_ptr<AsmPrinterHandler> Handler); 0532 0533 // Targets can, or in the case of EmitInstruction, must implement these to 0534 // customize output. 0535 0536 /// This virtual method can be overridden by targets that want to emit 0537 /// something at the start of their file. 0538 virtual void emitStartOfAsmFile(Module &) {} 0539 0540 /// This virtual method can be overridden by targets that want to emit 0541 /// something at the end of their file. 0542 virtual void emitEndOfAsmFile(Module &) {} 0543 0544 /// Targets can override this to emit stuff before the first basic block in 0545 /// the function. 0546 virtual void emitFunctionBodyStart() {} 0547 0548 /// Targets can override this to emit stuff after the last basic block in the 0549 /// function. 0550 virtual void emitFunctionBodyEnd() {} 0551 0552 /// Targets can override this to emit stuff at the start of a basic block. 0553 /// By default, this method prints the label for the specified 0554 /// MachineBasicBlock, an alignment (if present) and a comment describing it 0555 /// if appropriate. 0556 virtual void emitBasicBlockStart(const MachineBasicBlock &MBB); 0557 0558 /// Targets can override this to emit stuff at the end of a basic block. 0559 virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB); 0560 0561 /// Targets should implement this to emit instructions. 0562 virtual void emitInstruction(const MachineInstr *) { 0563 llvm_unreachable("EmitInstruction not implemented"); 0564 } 0565 0566 /// Return the symbol for the specified constant pool entry. 0567 virtual MCSymbol *GetCPISymbol(unsigned CPID) const; 0568 0569 virtual void emitFunctionEntryLabel(); 0570 0571 virtual void emitFunctionDescriptor() { 0572 llvm_unreachable("Function descriptor is target-specific."); 0573 } 0574 0575 virtual void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); 0576 0577 /// Targets can override this to change how global constants that are part of 0578 /// a C++ static/global constructor list are emitted. 0579 virtual void emitXXStructor(const DataLayout &DL, const Constant *CV) { 0580 emitGlobalConstant(DL, CV); 0581 } 0582 0583 virtual const MCExpr *lowerConstantPtrAuth(const ConstantPtrAuth &CPA) { 0584 report_fatal_error("ptrauth constant lowering not implemented"); 0585 } 0586 0587 /// Lower the specified BlockAddress to an MCExpr. 0588 virtual const MCExpr *lowerBlockAddressConstant(const BlockAddress &BA); 0589 0590 /// Return true if the basic block has exactly one predecessor and the control 0591 /// transfer mechanism between the predecessor and this block is a 0592 /// fall-through. 0593 virtual bool 0594 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; 0595 0596 /// Targets can override this to customize the output of IMPLICIT_DEF 0597 /// instructions in verbose mode. 0598 virtual void emitImplicitDef(const MachineInstr *MI) const; 0599 0600 /// getSubtargetInfo() cannot be used where this is needed because we don't 0601 /// have a MachineFunction when we're lowering a GlobalIFunc, and 0602 /// getSubtargetInfo requires one. Override the implementation in targets 0603 /// that support the Mach-O IFunc lowering. 0604 virtual const MCSubtargetInfo *getIFuncMCSubtargetInfo() const { 0605 return nullptr; 0606 } 0607 0608 virtual void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, 0609 MCSymbol *LazyPointer) { 0610 llvm_unreachable( 0611 "Mach-O IFunc lowering is not yet supported on this target"); 0612 } 0613 0614 virtual void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, 0615 MCSymbol *LazyPointer) { 0616 llvm_unreachable( 0617 "Mach-O IFunc lowering is not yet supported on this target"); 0618 } 0619 0620 /// Emit N NOP instructions. 0621 void emitNops(unsigned N); 0622 0623 //===------------------------------------------------------------------===// 0624 // Symbol Lowering Routines. 0625 //===------------------------------------------------------------------===// 0626 0627 MCSymbol *createTempSymbol(const Twine &Name) const; 0628 0629 /// Return the MCSymbol for a private symbol with global value name as its 0630 /// base, with the specified suffix. 0631 MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV, 0632 StringRef Suffix) const; 0633 0634 /// Return the MCSymbol for the specified ExternalSymbol. 0635 MCSymbol *GetExternalSymbolSymbol(Twine Sym) const; 0636 0637 /// Return the symbol for the specified jump table entry. 0638 MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; 0639 0640 /// Return the symbol for the specified jump table .set 0641 /// FIXME: privatize to AsmPrinter. 0642 MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const; 0643 0644 /// Return the MCSymbol used to satisfy BlockAddress uses of the specified 0645 /// basic block. 0646 MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; 0647 MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const; 0648 0649 //===------------------------------------------------------------------===// 0650 // Emission Helper Routines. 0651 //===------------------------------------------------------------------===// 0652 0653 /// This is just convenient handler for printing offsets. 0654 void printOffset(int64_t Offset, raw_ostream &OS) const; 0655 0656 /// Emit a byte directive and value. 0657 void emitInt8(int Value) const; 0658 0659 /// Emit a short directive and value. 0660 void emitInt16(int Value) const; 0661 0662 /// Emit a long directive and value. 0663 void emitInt32(int Value) const; 0664 0665 /// Emit a long long directive and value. 0666 void emitInt64(uint64_t Value) const; 0667 0668 /// Emit the specified signed leb128 value. 0669 void emitSLEB128(int64_t Value, const char *Desc = nullptr) const; 0670 0671 /// Emit the specified unsigned leb128 value. 0672 void emitULEB128(uint64_t Value, const char *Desc = nullptr, 0673 unsigned PadTo = 0) const; 0674 0675 /// Emit something like ".long Hi-Lo" where the size in bytes of the directive 0676 /// is specified by Size and Hi/Lo specify the labels. This implicitly uses 0677 /// .set if it is available. 0678 void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 0679 unsigned Size) const; 0680 0681 /// Emit something like ".uleb128 Hi-Lo". 0682 void emitLabelDifferenceAsULEB128(const MCSymbol *Hi, 0683 const MCSymbol *Lo) const; 0684 0685 /// Emit something like ".long Label+Offset" where the size in bytes of the 0686 /// directive is specified by Size and Label specifies the label. This 0687 /// implicitly uses .set if it is available. 0688 void emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, 0689 unsigned Size, bool IsSectionRelative = false) const; 0690 0691 /// Emit something like ".long Label" where the size in bytes of the directive 0692 /// is specified by Size and Label specifies the label. 0693 void emitLabelReference(const MCSymbol *Label, unsigned Size, 0694 bool IsSectionRelative = false) const { 0695 emitLabelPlusOffset(Label, 0, Size, IsSectionRelative); 0696 } 0697 0698 //===------------------------------------------------------------------===// 0699 // Dwarf Emission Helper Routines 0700 //===------------------------------------------------------------------===// 0701 0702 /// Emit a .byte 42 directive that corresponds to an encoding. If verbose 0703 /// assembly output is enabled, we output comments describing the encoding. 0704 /// Desc is a string saying what the encoding is specifying (e.g. "LSDA"). 0705 void emitEncodingByte(unsigned Val, const char *Desc = nullptr) const; 0706 0707 /// Return the size of the encoding in bytes. 0708 unsigned GetSizeOfEncodedValue(unsigned Encoding) const; 0709 0710 /// Emit reference to a ttype global with a specified encoding. 0711 virtual void emitTTypeReference(const GlobalValue *GV, unsigned Encoding); 0712 0713 /// Emit a reference to a symbol for use in dwarf. Different object formats 0714 /// represent this in different ways. Some use a relocation others encode 0715 /// the label offset in its section. 0716 void emitDwarfSymbolReference(const MCSymbol *Label, 0717 bool ForceOffset = false) const; 0718 0719 /// Emit the 4- or 8-byte offset of a string from the start of its section. 0720 /// 0721 /// When possible, emit a DwarfStringPool section offset without any 0722 /// relocations, and without using the symbol. Otherwise, defers to \a 0723 /// emitDwarfSymbolReference(). 0724 /// 0725 /// The length of the emitted value depends on the DWARF format. 0726 void emitDwarfStringOffset(DwarfStringPoolEntry S) const; 0727 0728 /// Emit the 4-or 8-byte offset of a string from the start of its section. 0729 void emitDwarfStringOffset(DwarfStringPoolEntryRef S) const { 0730 emitDwarfStringOffset(S.getEntry()); 0731 } 0732 0733 /// Emit something like ".long Label + Offset" or ".quad Label + Offset" 0734 /// depending on the DWARF format. 0735 void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const; 0736 0737 /// Emit 32- or 64-bit value depending on the DWARF format. 0738 void emitDwarfLengthOrOffset(uint64_t Value) const; 0739 0740 /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen 0741 /// according to the settings. 0742 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) const; 0743 0744 /// Emit a unit length field. The actual format, DWARF32 or DWARF64, is chosen 0745 /// according to the settings. 0746 /// Return the end symbol generated inside, the caller needs to emit it. 0747 MCSymbol *emitDwarfUnitLength(const Twine &Prefix, 0748 const Twine &Comment) const; 0749 0750 /// Emit reference to a call site with a specified encoding 0751 void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo, 0752 unsigned Encoding) const; 0753 /// Emit an integer value corresponding to the call site encoding 0754 void emitCallSiteValue(uint64_t Value, unsigned Encoding) const; 0755 0756 /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. 0757 virtual unsigned getISAEncoding() { return 0; } 0758 0759 /// Emit the directive and value for debug thread local expression 0760 /// 0761 /// \p Value - The value to emit. 0762 /// \p Size - The size of the integer (in bytes) to emit. 0763 virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const; 0764 0765 //===------------------------------------------------------------------===// 0766 // Dwarf Lowering Routines 0767 //===------------------------------------------------------------------===// 0768 0769 /// Emit frame instruction to describe the layout of the frame. 0770 void emitCFIInstruction(const MCCFIInstruction &Inst) const; 0771 0772 /// Emit Dwarf abbreviation table. 0773 template <typename T> void emitDwarfAbbrevs(const T &Abbrevs) const { 0774 // For each abbreviation. 0775 for (const auto &Abbrev : Abbrevs) 0776 emitDwarfAbbrev(*Abbrev); 0777 0778 // Mark end of abbreviations. 0779 emitULEB128(0, "EOM(3)"); 0780 } 0781 0782 void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const; 0783 0784 /// Recursively emit Dwarf DIE tree. 0785 void emitDwarfDIE(const DIE &Die) const; 0786 0787 //===------------------------------------------------------------------===// 0788 // CodeView Helper Routines 0789 //===------------------------------------------------------------------===// 0790 0791 /// Gets information required to create a CodeView debug symbol for a jump 0792 /// table. 0793 /// Return value is <Base Address, Base Offset, Branch Address, Entry Size> 0794 virtual std::tuple<const MCSymbol *, uint64_t, const MCSymbol *, 0795 codeview::JumpTableEntrySize> 0796 getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, 0797 const MCSymbol *BranchLabel) const; 0798 0799 //===------------------------------------------------------------------===// 0800 // Inline Asm Support 0801 //===------------------------------------------------------------------===// 0802 0803 // These are hooks that targets can override to implement inline asm 0804 // support. These should probably be moved out of AsmPrinter someday. 0805 0806 /// Print information related to the specified machine instr that is 0807 /// independent of the operand, and may be independent of the instr itself. 0808 /// This can be useful for portably encoding the comment character or other 0809 /// bits of target-specific knowledge into the asmstrings. The syntax used is 0810 /// ${:comment}. Targets can override this to add support for their own 0811 /// strange codes. 0812 virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, 0813 StringRef Code) const; 0814 0815 /// Print the MachineOperand as a symbol. Targets with complex handling of 0816 /// symbol references should override the base implementation. 0817 virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS); 0818 0819 /// Print the specified operand of MI, an INLINEASM instruction, using the 0820 /// specified assembler variant. Targets should override this to format as 0821 /// appropriate. This method can return true if the operand is erroneous. 0822 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 0823 const char *ExtraCode, raw_ostream &OS); 0824 0825 /// Print the specified operand of MI, an INLINEASM instruction, using the 0826 /// specified assembler variant as an address. Targets should override this to 0827 /// format as appropriate. This method can return true if the operand is 0828 /// erroneous. 0829 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 0830 const char *ExtraCode, raw_ostream &OS); 0831 0832 /// Let the target do anything it needs to do before emitting inlineasm. 0833 /// \p StartInfo - the subtarget info before parsing inline asm 0834 virtual void emitInlineAsmStart() const; 0835 0836 /// Let the target do anything it needs to do after emitting inlineasm. 0837 /// This callback can be used restore the original mode in case the 0838 /// inlineasm contains directives to switch modes. 0839 /// \p StartInfo - the original subtarget info before inline asm 0840 /// \p EndInfo - the final subtarget info after parsing the inline asm, 0841 /// or NULL if the value is unknown. 0842 virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 0843 const MCSubtargetInfo *EndInfo) const; 0844 0845 /// This emits visibility information about symbol, if this is supported by 0846 /// the target. 0847 void emitVisibility(MCSymbol *Sym, unsigned Visibility, 0848 bool IsDefinition = true) const; 0849 0850 /// This emits linkage information about \p GVSym based on \p GV, if this is 0851 /// supported by the target. 0852 virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const; 0853 0854 /// Return the alignment for the specified \p GV. 0855 static Align getGVAlignment(const GlobalObject *GV, const DataLayout &DL, 0856 Align InAlign = Align(1)); 0857 0858 private: 0859 /// Private state for PrintSpecial() 0860 // Assign a unique ID to this machine instruction. 0861 mutable const MachineInstr *LastMI = nullptr; 0862 mutable unsigned LastFn = 0; 0863 mutable unsigned Counter = ~0U; 0864 0865 bool DwarfUsesRelocationsAcrossSections = false; 0866 0867 /// This method emits the header for the current function. 0868 virtual void emitFunctionHeader(); 0869 0870 /// This method emits a comment next to header for the current function. 0871 virtual void emitFunctionHeaderComment(); 0872 0873 /// This method emits prefix-like data before the current function. 0874 void emitFunctionPrefix(ArrayRef<const Constant *> Prefix); 0875 0876 /// Emit a blob of inline asm to the output streamer. 0877 void 0878 emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI, 0879 const MCTargetOptions &MCOptions, 0880 const MDNode *LocMDNode = nullptr, 0881 InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const; 0882 0883 /// This method formats and emits the specified machine instruction that is an 0884 /// inline asm. 0885 void emitInlineAsm(const MachineInstr *MI) const; 0886 0887 /// Add inline assembly info to the diagnostics machinery, so we can 0888 /// emit file and position info. Returns SrcMgr memory buffer position. 0889 unsigned addInlineAsmDiagBuffer(StringRef AsmStr, 0890 const MDNode *LocMDNode) const; 0891 0892 //===------------------------------------------------------------------===// 0893 // Internal Implementation Details 0894 //===------------------------------------------------------------------===// 0895 0896 void emitJumpTableImpl(const MachineJumpTableInfo &MJTI, 0897 ArrayRef<unsigned> JumpTableIndices, 0898 bool JTInDiffSection); 0899 void emitJumpTableEntry(const MachineJumpTableInfo &MJTI, 0900 const MachineBasicBlock *MBB, unsigned uid) const; 0901 0902 void emitJumpTableSizesSection(const MachineJumpTableInfo &MJTI, 0903 const Function &F) const; 0904 0905 void emitLLVMUsedList(const ConstantArray *InitList); 0906 /// Emit llvm.ident metadata in an '.ident' directive. 0907 void emitModuleIdents(Module &M); 0908 /// Emit bytes for llvm.commandline metadata. 0909 virtual void emitModuleCommandLines(Module &M); 0910 0911 GCMetadataPrinter *getOrCreateGCPrinter(GCStrategy &S); 0912 void emitGlobalIFunc(Module &M, const GlobalIFunc &GI); 0913 0914 private: 0915 /// This method decides whether the specified basic block requires a label. 0916 bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const; 0917 0918 protected: 0919 virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA); 0920 virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const { 0921 return false; 0922 } 0923 }; 0924 0925 } // end namespace llvm 0926 0927 #endif // LLVM_CODEGEN_ASMPRINTER_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|