xref: /llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h (revision 2e5c2982819625d84e0b61aea0ec00de859f0e95)
1 //===-- AMDGPUTargetStreamer.h - AMDGPU Target Streamer --------*- 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 #ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
10 #define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUTARGETSTREAMER_H
11 
12 #include "Utils/AMDGPUBaseInfo.h"
13 #include "Utils/AMDGPUPALMetadata.h"
14 #include "llvm/MC/MCStreamer.h"
15 
16 namespace llvm {
17 
18 class MCELFStreamer;
19 class MCSymbol;
20 class formatted_raw_ostream;
21 
22 namespace AMDGPU {
23 
24 struct AMDGPUMCKernelCodeT;
25 struct MCKernelDescriptor;
26 namespace HSAMD {
27 struct Metadata;
28 }
29 } // namespace AMDGPU
30 
31 class AMDGPUTargetStreamer : public MCTargetStreamer {
32   AMDGPUPALMetadata PALMetadata;
33 
34 protected:
35   // TODO: Move HSAMetadataStream to AMDGPUTargetStreamer.
36   std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> TargetID;
37   unsigned CodeObjectVersion;
38 
39   MCContext &getContext() const { return Streamer.getContext(); }
40 
41 public:
42   AMDGPUTargetStreamer(MCStreamer &S)
43       : MCTargetStreamer(S),
44         // Assume the default COV for now, EmitDirectiveAMDHSACodeObjectVersion
45         // will update this if it is encountered.
46         CodeObjectVersion(AMDGPU::getDefaultAMDHSACodeObjectVersion()) {}
47 
48   AMDGPUPALMetadata *getPALMetadata() { return &PALMetadata; }
49 
50   virtual void EmitDirectiveAMDGCNTarget(){};
51 
52   virtual void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) {
53     CodeObjectVersion = COV;
54   }
55 
56   virtual void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) {};
57 
58   virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type){};
59 
60   virtual void emitAMDGPULDS(MCSymbol *Symbol, unsigned Size, Align Alignment) {
61   }
62 
63   virtual void EmitMCResourceInfo(
64       const MCSymbol *NumVGPR, const MCSymbol *NumAGPR,
65       const MCSymbol *NumExplicitSGPR, const MCSymbol *PrivateSegmentSize,
66       const MCSymbol *UsesVCC, const MCSymbol *UsesFlatScratch,
67       const MCSymbol *HasDynamicallySizedStack, const MCSymbol *HasRecursion,
68       const MCSymbol *HasIndirectCall) {};
69 
70   virtual void EmitMCResourceMaximums(const MCSymbol *MaxVGPR,
71                                       const MCSymbol *MaxAGPR,
72                                       const MCSymbol *MaxSGPR) {};
73 
74   /// \returns True on success, false on failure.
75   virtual bool EmitISAVersion() { return true; }
76 
77   /// \returns True on success, false on failure.
78   virtual bool EmitHSAMetadataV3(StringRef HSAMetadataString);
79 
80   /// Emit HSA Metadata
81   ///
82   /// When \p Strict is true, known metadata elements must already be
83   /// well-typed. When \p Strict is false, known types are inferred and
84   /// the \p HSAMetadata structure is updated with the correct types.
85   ///
86   /// \returns True on success, false on failure.
87   virtual bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) {
88     return true;
89   }
90 
91   /// \returns True on success, false on failure.
92   virtual bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) {
93     return true;
94   }
95 
96   /// \returns True on success, false on failure.
97   virtual bool EmitCodeEnd(const MCSubtargetInfo &STI) { return true; }
98 
99   virtual void
100   EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
101                              const AMDGPU::MCKernelDescriptor &KernelDescriptor,
102                              const MCExpr *NextVGPR, const MCExpr *NextSGPR,
103                              const MCExpr *ReserveVCC,
104                              const MCExpr *ReserveFlatScr) {}
105 
106   static StringRef getArchNameFromElfMach(unsigned ElfMach);
107   static unsigned getElfMach(StringRef GPU);
108 
109   const std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() const {
110     return TargetID;
111   }
112   std::optional<AMDGPU::IsaInfo::AMDGPUTargetID> &getTargetID() {
113     return TargetID;
114   }
115   void initializeTargetID(const MCSubtargetInfo &STI) {
116     assert(TargetID == std::nullopt && "TargetID can only be initialized once");
117     TargetID.emplace(STI);
118   }
119   void initializeTargetID(const MCSubtargetInfo &STI, StringRef FeatureString) {
120     initializeTargetID(STI);
121 
122     assert(getTargetID() != std::nullopt && "TargetID is None");
123     getTargetID()->setTargetIDFromFeaturesString(FeatureString);
124   }
125 };
126 
127 class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer {
128   formatted_raw_ostream &OS;
129 public:
130   AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
131 
132   void finish() override;
133 
134   void EmitDirectiveAMDGCNTarget() override;
135 
136   void EmitDirectiveAMDHSACodeObjectVersion(unsigned COV) override;
137 
138   void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
139 
140   void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
141 
142   void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
143 
144   void EmitMCResourceInfo(const MCSymbol *NumVGPR, const MCSymbol *NumAGPR,
145                           const MCSymbol *NumExplicitSGPR,
146                           const MCSymbol *PrivateSegmentSize,
147                           const MCSymbol *UsesVCC,
148                           const MCSymbol *UsesFlatScratch,
149                           const MCSymbol *HasDynamicallySizedStack,
150                           const MCSymbol *HasRecursion,
151                           const MCSymbol *HasIndirectCall) override;
152 
153   void EmitMCResourceMaximums(const MCSymbol *MaxVGPR, const MCSymbol *MaxAGPR,
154                               const MCSymbol *MaxSGPR) override;
155 
156   /// \returns True on success, false on failure.
157   bool EmitISAVersion() override;
158 
159   /// \returns True on success, false on failure.
160   bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
161 
162   /// \returns True on success, false on failure.
163   bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
164 
165   void
166   EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
167                              const AMDGPU::MCKernelDescriptor &KernelDescriptor,
168                              const MCExpr *NextVGPR, const MCExpr *NextSGPR,
169                              const MCExpr *ReserveVCC,
170                              const MCExpr *ReserveFlatScr) override;
171 };
172 
173 class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer {
174   const MCSubtargetInfo &STI;
175   MCStreamer &Streamer;
176 
177   void EmitNote(StringRef Name, const MCExpr *DescSize, unsigned NoteType,
178                 function_ref<void(MCELFStreamer &)> EmitDesc);
179 
180   unsigned getEFlags();
181 
182   unsigned getEFlagsR600();
183   unsigned getEFlagsAMDGCN();
184 
185   unsigned getEFlagsUnknownOS();
186   unsigned getEFlagsAMDHSA();
187   unsigned getEFlagsAMDPAL();
188   unsigned getEFlagsMesa3D();
189 
190   unsigned getEFlagsV3();
191   unsigned getEFlagsV4();
192   unsigned getEFlagsV6();
193 
194 public:
195   AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
196 
197   MCELFStreamer &getStreamer();
198 
199   void finish() override;
200 
201   void EmitDirectiveAMDGCNTarget() override;
202 
203   void EmitAMDKernelCodeT(AMDGPU::AMDGPUMCKernelCodeT &Header) override;
204 
205   void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override;
206 
207   void emitAMDGPULDS(MCSymbol *Sym, unsigned Size, Align Alignment) override;
208 
209   /// \returns True on success, false on failure.
210   bool EmitISAVersion() override;
211 
212   /// \returns True on success, false on failure.
213   bool EmitHSAMetadata(msgpack::Document &HSAMetadata, bool Strict) override;
214 
215   /// \returns True on success, false on failure.
216   bool EmitCodeEnd(const MCSubtargetInfo &STI) override;
217 
218   void
219   EmitAmdhsaKernelDescriptor(const MCSubtargetInfo &STI, StringRef KernelName,
220                              const AMDGPU::MCKernelDescriptor &KernelDescriptor,
221                              const MCExpr *NextVGPR, const MCExpr *NextSGPR,
222                              const MCExpr *ReserveVCC,
223                              const MCExpr *ReserveFlatScr) override;
224 };
225 }
226 #endif
227