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