/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- AMDGPUTargetStreamer.cpp - Mips Target Streamer Methods -----------===// |
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 provides AMDGPU specific target streamer methods. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "AMDGPUTargetStreamer.h" |
15 | | #include "AMDGPU.h" |
16 | | #include "SIDefines.h" |
17 | | #include "Utils/AMDGPUBaseInfo.h" |
18 | | #include "Utils/AMDKernelCodeTUtils.h" |
19 | | #include "llvm/ADT/Twine.h" |
20 | | #include "llvm/BinaryFormat/ELF.h" |
21 | | #include "llvm/IR/Constants.h" |
22 | | #include "llvm/IR/Function.h" |
23 | | #include "llvm/IR/Metadata.h" |
24 | | #include "llvm/IR/Module.h" |
25 | | #include "llvm/MC/MCContext.h" |
26 | | #include "llvm/MC/MCELFStreamer.h" |
27 | | #include "llvm/MC/MCObjectFileInfo.h" |
28 | | #include "llvm/MC/MCSectionELF.h" |
29 | | #include "llvm/Support/FormattedStream.h" |
30 | | |
31 | | namespace llvm { |
32 | | #include "AMDGPUPTNote.h" |
33 | | } |
34 | | |
35 | | using namespace llvm; |
36 | | using namespace llvm::AMDGPU; |
37 | | |
38 | | //===----------------------------------------------------------------------===// |
39 | | // AMDGPUTargetStreamer |
40 | | //===----------------------------------------------------------------------===// |
41 | | |
42 | | AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S) |
43 | 1.77k | : MCTargetStreamer(S) {} |
44 | | |
45 | 240 | void AMDGPUTargetStreamer::EmitStartOfCodeObjectMetadata(const Module &Mod) { |
46 | 240 | CodeObjectMetadataStreamer.begin(Mod); |
47 | 240 | } |
48 | | |
49 | | void AMDGPUTargetStreamer::EmitKernelCodeObjectMetadata( |
50 | 1.66k | const Function &Func, const amd_kernel_code_t &KernelCode) { |
51 | 1.66k | CodeObjectMetadataStreamer.emitKernel(Func, KernelCode); |
52 | 1.66k | } |
53 | | |
54 | 240 | void AMDGPUTargetStreamer::EmitEndOfCodeObjectMetadata() { |
55 | 240 | CodeObjectMetadataStreamer.end(); |
56 | 240 | EmitCodeObjectMetadata(CodeObjectMetadataStreamer.toYamlString().get()); |
57 | 240 | } |
58 | | |
59 | | //===----------------------------------------------------------------------===// |
60 | | // AMDGPUTargetAsmStreamer |
61 | | //===----------------------------------------------------------------------===// |
62 | | |
63 | | AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S, |
64 | | formatted_raw_ostream &OS) |
65 | 1.72k | : AMDGPUTargetStreamer(S), OS(OS) { } |
66 | | |
67 | | void |
68 | | AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, |
69 | 216 | uint32_t Minor) { |
70 | 216 | OS << "\t.hsa_code_object_version " << |
71 | 216 | Twine(Major) << "," << Twine(Minor) << '\n'; |
72 | 216 | } |
73 | | |
74 | | void |
75 | | AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, |
76 | | uint32_t Minor, |
77 | | uint32_t Stepping, |
78 | | StringRef VendorName, |
79 | 219 | StringRef ArchName) { |
80 | 219 | OS << "\t.hsa_code_object_isa " << |
81 | 219 | Twine(Major) << "," << Twine(Minor) << "," << Twine(Stepping) << |
82 | 219 | ",\"" << VendorName << "\",\"" << ArchName << "\"\n"; |
83 | 219 | |
84 | 219 | } |
85 | | |
86 | | void |
87 | 1.54k | AMDGPUTargetAsmStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { |
88 | 1.54k | OS << "\t.amd_kernel_code_t\n"; |
89 | 1.54k | dumpAmdKernelCode(&Header, OS, "\t\t"); |
90 | 1.54k | OS << "\t.end_amd_kernel_code_t\n"; |
91 | 1.54k | } |
92 | | |
93 | | void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, |
94 | 1.54k | unsigned Type) { |
95 | 1.54k | switch (Type) { |
96 | 0 | default: 0 llvm_unreachable0 ("Invalid AMDGPU symbol type"); |
97 | 1.54k | case ELF::STT_AMDGPU_HSA_KERNEL: |
98 | 1.54k | OS << "\t.amdgpu_hsa_kernel " << SymbolName << '\n' ; |
99 | 1.54k | break; |
100 | 1.54k | } |
101 | 1.54k | } |
102 | | |
103 | 226 | bool AMDGPUTargetAsmStreamer::EmitCodeObjectMetadata(StringRef YamlString) { |
104 | 226 | auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString); |
105 | 226 | if (!VerifiedYamlString) |
106 | 3 | return false; |
107 | 223 | |
108 | 223 | OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveBegin << '\n'; |
109 | 223 | OS << VerifiedYamlString.get(); |
110 | 223 | OS << '\t' << AMDGPU::CodeObject::MetadataAssemblerDirectiveEnd << '\n'; |
111 | 223 | |
112 | 223 | return true; |
113 | 223 | } |
114 | | |
115 | | //===----------------------------------------------------------------------===// |
116 | | // AMDGPUTargetELFStreamer |
117 | | //===----------------------------------------------------------------------===// |
118 | | |
119 | | AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S) |
120 | 58 | : AMDGPUTargetStreamer(S), Streamer(S) {} |
121 | | |
122 | 549 | MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() { |
123 | 549 | return static_cast<MCELFStreamer &>(Streamer); |
124 | 549 | } |
125 | | |
126 | | void AMDGPUTargetELFStreamer::EmitAMDGPUNote( |
127 | | const MCExpr *DescSZ, ElfNote::NoteType Type, |
128 | 114 | function_ref<void(MCELFStreamer &)> EmitDesc) { |
129 | 114 | auto &S = getStreamer(); |
130 | 114 | auto &Context = S.getContext(); |
131 | 114 | |
132 | 114 | auto NameSZ = sizeof(ElfNote::NoteName); |
133 | 114 | |
134 | 114 | S.PushSection(); |
135 | 114 | S.SwitchSection(Context.getELFSection( |
136 | 114 | ElfNote::SectionName, ELF::SHT_NOTE, ELF::SHF_ALLOC)); |
137 | 114 | S.EmitIntValue(NameSZ, 4); // namesz |
138 | 114 | S.EmitValue(DescSZ, 4); // descz |
139 | 114 | S.EmitIntValue(Type, 4); // type |
140 | 114 | S.EmitBytes(StringRef(ElfNote::NoteName, NameSZ)); // name |
141 | 114 | S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 |
142 | 114 | EmitDesc(S); // desc |
143 | 114 | S.EmitValueToAlignment(4, 0, 1, 0); // padding 0 |
144 | 114 | S.PopSection(); |
145 | 114 | } |
146 | | |
147 | | void |
148 | | AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major, |
149 | 39 | uint32_t Minor) { |
150 | 39 | |
151 | 39 | EmitAMDGPUNote( |
152 | 39 | MCConstantExpr::create(8, getContext()), |
153 | 39 | ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_VERSION, |
154 | 39 | [&](MCELFStreamer &OS){ |
155 | 39 | OS.EmitIntValue(Major, 4); |
156 | 39 | OS.EmitIntValue(Minor, 4); |
157 | 39 | } |
158 | 39 | ); |
159 | 39 | } |
160 | | |
161 | | void |
162 | | AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectISA(uint32_t Major, |
163 | | uint32_t Minor, |
164 | | uint32_t Stepping, |
165 | | StringRef VendorName, |
166 | 42 | StringRef ArchName) { |
167 | 42 | uint16_t VendorNameSize = VendorName.size() + 1; |
168 | 42 | uint16_t ArchNameSize = ArchName.size() + 1; |
169 | 42 | |
170 | 42 | unsigned DescSZ = sizeof(VendorNameSize) + sizeof(ArchNameSize) + |
171 | 42 | sizeof(Major) + sizeof(Minor) + sizeof(Stepping) + |
172 | 42 | VendorNameSize + ArchNameSize; |
173 | 42 | |
174 | 42 | EmitAMDGPUNote( |
175 | 42 | MCConstantExpr::create(DescSZ, getContext()), |
176 | 42 | ElfNote::NT_AMDGPU_HSA_ISA, |
177 | 42 | [&](MCELFStreamer &OS) { |
178 | 42 | OS.EmitIntValue(VendorNameSize, 2); |
179 | 42 | OS.EmitIntValue(ArchNameSize, 2); |
180 | 42 | OS.EmitIntValue(Major, 4); |
181 | 42 | OS.EmitIntValue(Minor, 4); |
182 | 42 | OS.EmitIntValue(Stepping, 4); |
183 | 42 | OS.EmitBytes(VendorName); |
184 | 42 | OS.EmitIntValue(0, 1); // NULL terminate VendorName |
185 | 42 | OS.EmitBytes(ArchName); |
186 | 42 | OS.EmitIntValue(0, 1); // NULL terminte ArchName |
187 | 42 | } |
188 | 42 | ); |
189 | 42 | } |
190 | | |
191 | | void |
192 | 217 | AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) { |
193 | 217 | |
194 | 217 | MCStreamer &OS = getStreamer(); |
195 | 217 | OS.PushSection(); |
196 | 217 | OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header))); |
197 | 217 | OS.PopSection(); |
198 | 217 | } |
199 | | |
200 | | void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, |
201 | 218 | unsigned Type) { |
202 | 218 | MCSymbolELF *Symbol = cast<MCSymbolELF>( |
203 | 218 | getStreamer().getContext().getOrCreateSymbol(SymbolName)); |
204 | 218 | Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL); |
205 | 218 | } |
206 | | |
207 | 36 | bool AMDGPUTargetELFStreamer::EmitCodeObjectMetadata(StringRef YamlString) { |
208 | 36 | auto VerifiedYamlString = CodeObjectMetadataStreamer.toYamlString(YamlString); |
209 | 36 | if (!VerifiedYamlString) |
210 | 3 | return false; |
211 | 33 | |
212 | 33 | // Create two labels to mark the beginning and end of the desc field |
213 | 33 | // and a MCExpr to calculate the size of the desc field. |
214 | 33 | auto &Context = getContext(); |
215 | 33 | auto *DescBegin = Context.createTempSymbol(); |
216 | 33 | auto *DescEnd = Context.createTempSymbol(); |
217 | 33 | auto *DescSZ = MCBinaryExpr::createSub( |
218 | 33 | MCSymbolRefExpr::create(DescEnd, Context), |
219 | 33 | MCSymbolRefExpr::create(DescBegin, Context), Context); |
220 | 33 | |
221 | 33 | EmitAMDGPUNote( |
222 | 33 | DescSZ, |
223 | 33 | ElfNote::NT_AMDGPU_HSA_CODE_OBJECT_METADATA, |
224 | 33 | [&](MCELFStreamer &OS) { |
225 | 33 | OS.EmitLabel(DescBegin); |
226 | 33 | OS.EmitBytes(VerifiedYamlString.get()); |
227 | 33 | OS.EmitLabel(DescEnd); |
228 | 33 | } |
229 | 36 | ); |
230 | 36 | |
231 | 36 | return true; |
232 | 36 | } |