1 //===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains a class to be used as the base class for target specific 11 // asm writers. This class primarily handles common functionality used by 12 // all asm writers. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_CODEGEN_ASMPRINTER_H 17 #define LLVM_CODEGEN_ASMPRINTER_H 18 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/IR/InlineAsm.h" 22 #include "llvm/Support/DataTypes.h" 23 #include "llvm/Support/ErrorHandling.h" 24 25 namespace llvm { 26 class AsmPrinterHandler; 27 class BlockAddress; 28 class ByteStreamer; 29 class GCStrategy; 30 class Constant; 31 class ConstantArray; 32 class GCMetadataPrinter; 33 class GlobalValue; 34 class GlobalVariable; 35 class MachineBasicBlock; 36 class MachineFunction; 37 class MachineInstr; 38 class MachineLocation; 39 class MachineLoopInfo; 40 class MachineLoop; 41 class MachineConstantPoolValue; 42 class MachineJumpTableInfo; 43 class MachineModuleInfo; 44 class MCAsmInfo; 45 class MCCFIInstruction; 46 class MCContext; 47 class MCInst; 48 class MCInstrInfo; 49 class MCSection; 50 class MCStreamer; 51 class MCSubtargetInfo; 52 class MCSymbol; 53 class MDNode; 54 class DwarfDebug; 55 class Mangler; 56 class TargetLoweringObjectFile; 57 class DataLayout; 58 class TargetMachine; 59 60 /// This class is intended to be used as a driving class for all asm writers. 61 class AsmPrinter : public MachineFunctionPass { 62 public: 63 /// Target machine description. 64 /// 65 TargetMachine &TM; 66 67 /// Target Asm Printer information. 68 /// 69 const MCAsmInfo *MAI; 70 71 const MCInstrInfo *MII; 72 /// This is the context for the output file that we are streaming. This owns 73 /// all of the global MC-related objects for the generated translation unit. 74 MCContext &OutContext; 75 76 /// This is the MCStreamer object for the file we are generating. This 77 /// contains the transient state for the current translation unit that we are 78 /// generating (such as the current section etc). 79 MCStreamer &OutStreamer; 80 81 /// The current machine function. 82 const MachineFunction *MF; 83 84 /// This is a pointer to the current MachineModuleInfo. 85 MachineModuleInfo *MMI; 86 87 /// Name-mangler for global names. 88 /// 89 Mangler *Mang; 90 91 /// The symbol for the current function. This is recalculated at the beginning 92 /// of each call to runOnMachineFunction(). 93 /// 94 MCSymbol *CurrentFnSym; 95 96 /// The symbol used to represent the start of the current function for the 97 /// purpose of calculating its size (e.g. using the .size directive). By 98 /// default, this is equal to CurrentFnSym. 99 MCSymbol *CurrentFnSymForSize; 100 101 private: 102 // The garbage collection metadata printer table. 103 void *GCMetadataPrinters; // Really a DenseMap. 104 105 /// Emit comments in assembly output if this is true. 106 /// 107 bool VerboseAsm; 108 static char ID; 109 110 /// If VerboseAsm is set, a pointer to the loop info for this function. 111 MachineLoopInfo *LI; 112 113 struct HandlerInfo { 114 AsmPrinterHandler *Handler; 115 const char *TimerName, *TimerGroupName; HandlerInfoHandlerInfo116 HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName, 117 const char *TimerGroupName) 118 : Handler(Handler), TimerName(TimerName), 119 TimerGroupName(TimerGroupName) {} 120 }; 121 /// A vector of all debug/EH info emitters we should use. This vector 122 /// maintains ownership of the emitters. 123 SmallVector<HandlerInfo, 1> Handlers; 124 125 /// If the target supports dwarf debug info, this pointer is non-null. 126 DwarfDebug *DD; 127 128 protected: 129 explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer); 130 131 public: 132 virtual ~AsmPrinter(); 133 getDwarfDebug()134 DwarfDebug *getDwarfDebug() { return DD; } 135 136 /// Return true if assembly output should contain comments. 137 /// isVerbose()138 bool isVerbose() const { return VerboseAsm; } 139 140 /// Return a unique ID for the current function. 141 /// 142 unsigned getFunctionNumber() const; 143 144 /// Return information about object file lowering. 145 const TargetLoweringObjectFile &getObjFileLowering() const; 146 147 /// Return information about data layout. 148 const DataLayout &getDataLayout() const; 149 150 /// Return information about subtarget. 151 const MCSubtargetInfo &getSubtargetInfo() const; 152 153 void EmitToStreamer(MCStreamer &S, const MCInst &Inst); 154 155 /// Return the target triple string. 156 StringRef getTargetTriple() const; 157 158 /// Return the current section we are emitting to. 159 const MCSection *getCurrentSection() const; 160 161 void getNameWithPrefix(SmallVectorImpl<char> &Name, 162 const GlobalValue *GV) const; 163 164 MCSymbol *getSymbol(const GlobalValue *GV) const; 165 166 //===------------------------------------------------------------------===// 167 // MachineFunctionPass Implementation. 168 //===------------------------------------------------------------------===// 169 170 /// Record analysis usage. 171 /// 172 void getAnalysisUsage(AnalysisUsage &AU) const override; 173 174 /// Set up the AsmPrinter when we are working on a new module. If your pass 175 /// overrides this, it must make sure to explicitly call this implementation. 176 bool doInitialization(Module &M) override; 177 178 /// Shut down the asmprinter. If you override this in your pass, you must make 179 /// sure to call it explicitly. 180 bool doFinalization(Module &M) override; 181 182 /// Emit the specified function out to the OutStreamer. runOnMachineFunction(MachineFunction & MF)183 bool runOnMachineFunction(MachineFunction &MF) override { 184 SetupMachineFunction(MF); 185 EmitFunctionHeader(); 186 EmitFunctionBody(); 187 return false; 188 } 189 190 //===------------------------------------------------------------------===// 191 // Coarse grained IR lowering routines. 192 //===------------------------------------------------------------------===// 193 194 /// This should be called when a new MachineFunction is being processed from 195 /// runOnMachineFunction. 196 void SetupMachineFunction(MachineFunction &MF); 197 198 /// This method emits the header for the current function. 199 void EmitFunctionHeader(); 200 201 /// This method emits the body and trailer for a function. 202 void EmitFunctionBody(); 203 204 void emitCFIInstruction(const MachineInstr &MI); 205 206 enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug }; 207 CFIMoveType needsCFIMoves(); 208 209 bool needsSEHMoves(); 210 211 /// Print to the current output stream assembly representations of the 212 /// constants in the constant pool MCP. This is used to print out constants 213 /// which have been "spilled to memory" by the code generator. 214 /// 215 virtual void EmitConstantPool(); 216 217 /// Print assembly representations of the jump tables used by the current 218 /// function to the current output stream. 219 /// 220 void EmitJumpTableInfo(); 221 222 /// Emit the specified global variable to the .s file. 223 virtual void EmitGlobalVariable(const GlobalVariable *GV); 224 225 /// Check to see if the specified global is a special global used by LLVM. If 226 /// so, emit it and return true, otherwise do nothing and return false. 227 bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); 228 229 /// Emit an alignment directive to the specified power of two boundary. For 230 /// example, if you pass in 3 here, you will get an 8 byte alignment. If a 231 /// global value is specified, and if that global has an explicit alignment 232 /// requested, it will override the alignment request if required for 233 /// correctness. 234 /// 235 void EmitAlignment(unsigned NumBits, const GlobalObject *GO = nullptr) const; 236 237 /// This method prints the label for the specified MachineBasicBlock, an 238 /// alignment (if present) and a comment describing it if appropriate. 239 void EmitBasicBlockStart(const MachineBasicBlock &MBB) const; 240 241 /// \brief Print a general LLVM constant to the .s file. 242 void EmitGlobalConstant(const Constant *CV); 243 244 //===------------------------------------------------------------------===// 245 // Overridable Hooks 246 //===------------------------------------------------------------------===// 247 248 // Targets can, or in the case of EmitInstruction, must implement these to 249 // customize output. 250 251 /// This virtual method can be overridden by targets that want to emit 252 /// something at the start of their file. EmitStartOfAsmFile(Module &)253 virtual void EmitStartOfAsmFile(Module &) {} 254 255 /// This virtual method can be overridden by targets that want to emit 256 /// something at the end of their file. EmitEndOfAsmFile(Module &)257 virtual void EmitEndOfAsmFile(Module &) {} 258 259 /// Targets can override this to emit stuff before the first basic block in 260 /// the function. EmitFunctionBodyStart()261 virtual void EmitFunctionBodyStart() {} 262 263 /// Targets can override this to emit stuff after the last basic block in the 264 /// function. EmitFunctionBodyEnd()265 virtual void EmitFunctionBodyEnd() {} 266 267 /// Targets should implement this to emit instructions. EmitInstruction(const MachineInstr *)268 virtual void EmitInstruction(const MachineInstr *) { 269 llvm_unreachable("EmitInstruction not implemented"); 270 } 271 272 /// Return the symbol for the specified constant pool entry. 273 virtual MCSymbol *GetCPISymbol(unsigned CPID) const; 274 275 virtual void EmitFunctionEntryLabel(); 276 277 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); 278 279 /// Targets can override this to change how global constants that are part of 280 /// a C++ static/global constructor list are emitted. EmitXXStructor(const Constant * CV)281 virtual void EmitXXStructor(const Constant *CV) { EmitGlobalConstant(CV); } 282 283 /// Return true if the basic block has exactly one predecessor and the control 284 /// transfer mechanism between the predecessor and this block is a 285 /// fall-through. 286 virtual bool 287 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const; 288 289 /// Targets can override this to customize the output of IMPLICIT_DEF 290 /// instructions in verbose mode. 291 virtual void emitImplicitDef(const MachineInstr *MI) const; 292 293 //===------------------------------------------------------------------===// 294 // Symbol Lowering Routines. 295 //===------------------------------------------------------------------===// 296 public: 297 /// Return the MCSymbol corresponding to the assembler temporary label with 298 /// the specified stem and unique ID. 299 MCSymbol *GetTempSymbol(Twine Name, unsigned ID) const; 300 301 /// Return an assembler temporary label with the specified stem. 302 MCSymbol *GetTempSymbol(Twine Name) const; 303 304 /// Return the MCSymbol for a private symbol with global value name as its 305 /// base, with the specified suffix. 306 MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV, 307 StringRef Suffix) const; 308 309 /// Return the MCSymbol for the specified ExternalSymbol. 310 MCSymbol *GetExternalSymbolSymbol(StringRef Sym) const; 311 312 /// Return the symbol for the specified jump table entry. 313 MCSymbol *GetJTISymbol(unsigned JTID, bool isLinkerPrivate = false) const; 314 315 /// Return the symbol for the specified jump table .set 316 /// FIXME: privatize to AsmPrinter. 317 MCSymbol *GetJTSetSymbol(unsigned UID, unsigned MBBID) const; 318 319 /// Return the MCSymbol used to satisfy BlockAddress uses of the specified 320 /// basic block. 321 MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; 322 MCSymbol *GetBlockAddressSymbol(const BasicBlock *BB) const; 323 324 //===------------------------------------------------------------------===// 325 // Emission Helper Routines. 326 //===------------------------------------------------------------------===// 327 public: 328 /// This is just convenient handler for printing offsets. 329 void printOffset(int64_t Offset, raw_ostream &OS) const; 330 331 /// Emit a byte directive and value. 332 /// 333 void EmitInt8(int Value) const; 334 335 /// Emit a short directive and value. 336 /// 337 void EmitInt16(int Value) const; 338 339 /// Emit a long directive and value. 340 /// 341 void EmitInt32(int Value) const; 342 343 /// Emit something like ".long Hi-Lo" where the size in bytes of the directive 344 /// is specified by Size and Hi/Lo specify the labels. This implicitly uses 345 /// .set if it is available. 346 void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, 347 unsigned Size) const; 348 349 /// Emit something like ".long Hi+Offset-Lo" where the size in bytes of the 350 /// directive is specified by Size and Hi/Lo specify the labels. This 351 /// implicitly uses .set if it is available. 352 void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset, 353 const MCSymbol *Lo, unsigned Size) const; 354 355 /// Emit something like ".long Label+Offset" where the size in bytes of the 356 /// directive is specified by Size and Label specifies the label. This 357 /// implicitly uses .set if it is available. 358 void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, 359 unsigned Size, bool IsSectionRelative = false) const; 360 361 /// Emit something like ".long Label" where the size in bytes of the directive 362 /// is specified by Size and Label specifies the label. 363 void EmitLabelReference(const MCSymbol *Label, unsigned Size, 364 bool IsSectionRelative = false) const { 365 EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative); 366 } 367 368 //===------------------------------------------------------------------===// 369 // Dwarf Emission Helper Routines 370 //===------------------------------------------------------------------===// 371 372 /// Emit the specified signed leb128 value. 373 void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const; 374 375 /// Emit the specified unsigned leb128 value. 376 void EmitULEB128(uint64_t Value, const char *Desc = nullptr, 377 unsigned PadTo = 0) const; 378 379 /// Emit a .byte 42 directive for a DW_CFA_xxx value. 380 void EmitCFAByte(unsigned Val) const; 381 382 /// Emit a .byte 42 directive that corresponds to an encoding. If verbose 383 /// assembly output is enabled, we output comments describing the encoding. 384 /// Desc is a string saying what the encoding is specifying (e.g. "LSDA"). 385 void EmitEncodingByte(unsigned Val, const char *Desc = nullptr) const; 386 387 /// Return the size of the encoding in bytes. 388 unsigned GetSizeOfEncodedValue(unsigned Encoding) const; 389 390 /// Emit reference to a ttype global with a specified encoding. 391 void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const; 392 393 /// Emit the 4-byte offset of Label from the start of its section. This can 394 /// be done with a special directive if the target supports it (e.g. cygwin) 395 /// or by emitting it as an offset from a label at the start of the section. 396 /// 397 /// SectionLabel is a temporary label emitted at the start of the section 398 /// that Label lives in. 399 void EmitSectionOffset(const MCSymbol *Label, 400 const MCSymbol *SectionLabel) const; 401 402 /// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified. getISAEncoding()403 virtual unsigned getISAEncoding() { return 0; } 404 405 /// \brief Emit a partial DWARF register operation. 406 /// \param MLoc the register 407 /// \param PieceSize size and 408 /// \param PieceOffset offset of the piece in bits, if this is one 409 /// piece of an aggregate value. 410 /// 411 /// If size and offset is zero an operation for the entire 412 /// register is emitted: Some targets do not provide a DWARF 413 /// register number for every register. If this is the case, this 414 /// function will attempt to emit a DWARF register by emitting a 415 /// piece of a super-register or by piecing together multiple 416 /// subregisters that alias the register. 417 void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc, 418 unsigned PieceSize = 0, 419 unsigned PieceOffset = 0) const; 420 421 /// Emit dwarf register operation. 422 /// \param Indirect whether this is a register-indirect address 423 virtual void EmitDwarfRegOp(ByteStreamer &BS, const MachineLocation &MLoc, 424 bool Indirect) const; 425 426 //===------------------------------------------------------------------===// 427 // Dwarf Lowering Routines 428 //===------------------------------------------------------------------===// 429 430 /// \brief Emit frame instruction to describe the layout of the frame. 431 void emitCFIInstruction(const MCCFIInstruction &Inst) const; 432 433 //===------------------------------------------------------------------===// 434 // Inline Asm Support 435 //===------------------------------------------------------------------===// 436 public: 437 // These are hooks that targets can override to implement inline asm 438 // support. These should probably be moved out of AsmPrinter someday. 439 440 /// Print information related to the specified machine instr that is 441 /// independent of the operand, and may be independent of the instr itself. 442 /// This can be useful for portably encoding the comment character or other 443 /// bits of target-specific knowledge into the asmstrings. The syntax used is 444 /// ${:comment}. Targets can override this to add support for their own 445 /// strange codes. 446 virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, 447 const char *Code) const; 448 449 /// Print the specified operand of MI, an INLINEASM instruction, using the 450 /// specified assembler variant. Targets should override this to format as 451 /// appropriate. This method can return true if the operand is erroneous. 452 virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 453 unsigned AsmVariant, const char *ExtraCode, 454 raw_ostream &OS); 455 456 /// Print the specified operand of MI, an INLINEASM instruction, using the 457 /// specified assembler variant as an address. Targets should override this to 458 /// format as appropriate. This method can return true if the operand is 459 /// erroneous. 460 virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 461 unsigned AsmVariant, const char *ExtraCode, 462 raw_ostream &OS); 463 464 /// Let the target do anything it needs to do after emitting inlineasm. 465 /// This callback can be used restore the original mode in case the 466 /// inlineasm contains directives to switch modes. 467 /// \p StartInfo - the original subtarget info before inline asm 468 /// \p EndInfo - the final subtarget info after parsing the inline asm, 469 /// or NULL if the value is unknown. 470 virtual void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, 471 const MCSubtargetInfo *EndInfo) const; 472 473 private: 474 /// Private state for PrintSpecial() 475 // Assign a unique ID to this machine instruction. 476 mutable const MachineInstr *LastMI; 477 mutable unsigned LastFn; 478 mutable unsigned Counter; 479 mutable unsigned SetCounter; 480 481 /// Emit a blob of inline asm to the output streamer. 482 void 483 EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr, 484 InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const; 485 486 /// This method formats and emits the specified machine instruction that is an 487 /// inline asm. 488 void EmitInlineAsm(const MachineInstr *MI) const; 489 490 //===------------------------------------------------------------------===// 491 // Internal Implementation Details 492 //===------------------------------------------------------------------===// 493 494 /// This emits visibility information about symbol, if this is suported by the 495 /// target. 496 void EmitVisibility(MCSymbol *Sym, unsigned Visibility, 497 bool IsDefinition = true) const; 498 499 void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const; 500 501 void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, 502 const MachineBasicBlock *MBB, unsigned uid) const; 503 void EmitLLVMUsedList(const ConstantArray *InitList); 504 /// Emit llvm.ident metadata in an '.ident' directive. 505 void EmitModuleIdents(Module &M); 506 void EmitXXStructorList(const Constant *List, bool isCtor); 507 GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C); 508 }; 509 } 510 511 #endif 512