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