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