LLVM 22.0.0git
Utility.cpp
Go to the documentation of this file.
1//===- Utility.cpp ------ Collection of generic offloading utilities ------===//
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
13#include "llvm/IR/Constants.h"
14#include "llvm/IR/GlobalValue.h"
16#include "llvm/IR/Value.h"
22
23using namespace llvm;
24using namespace llvm::offloading;
25
27 LLVMContext &C = M.getContext();
29 StructType::getTypeByName(C, "struct.__tgt_offload_entry");
30 if (!EntryTy)
32 "struct.__tgt_offload_entry", Type::getInt64Ty(C), Type::getInt16Ty(C),
33 Type::getInt16Ty(C), Type::getInt32Ty(C), PointerType::getUnqual(C),
34 PointerType::getUnqual(C), Type::getInt64Ty(C), Type::getInt64Ty(C),
35 PointerType::getUnqual(C));
36 return EntryTy;
37}
38
39std::pair<Constant *, GlobalVariable *>
42 uint64_t Size, uint32_t Flags,
43 uint64_t Data, Constant *AuxAddr) {
44 const llvm::Triple &Triple = M.getTargetTriple();
45 Type *PtrTy = PointerType::getUnqual(M.getContext());
46 Type *Int64Ty = Type::getInt64Ty(M.getContext());
47 Type *Int32Ty = Type::getInt32Ty(M.getContext());
48 Type *Int16Ty = Type::getInt16Ty(M.getContext());
49
50 Constant *AddrName = ConstantDataArray::getString(M.getContext(), Name);
51
52 StringRef Prefix =
53 Triple.isNVPTX() ? "$offloading$entry_name" : ".offloading.entry_name";
54
55 // Create the constant string used to look up the symbol in the device.
56 auto *Str =
57 new GlobalVariable(M, AddrName->getType(), /*isConstant=*/true,
58 GlobalValue::InternalLinkage, AddrName, Prefix);
59 StringRef SectionName = ".llvm.rodata.offloading";
60 Str->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
61 Str->setSection(SectionName);
62 Str->setAlignment(Align(1));
63
64 // Make a metadata node for these constants so it can be queried from IR.
65 NamedMDNode *MD = M.getOrInsertNamedMetadata("llvm.offloading.symbols");
66 Metadata *MDVals[] = {ConstantAsMetadata::get(Str)};
67 MD->addOperand(llvm::MDNode::get(M.getContext(), MDVals));
68
69 // Construct the offloading entry.
70 Constant *EntryData[] = {
71 ConstantExpr::getNullValue(Int64Ty),
72 ConstantInt::get(Int16Ty, 1),
73 ConstantInt::get(Int16Ty, Kind),
74 ConstantInt::get(Int32Ty, Flags),
77 ConstantInt::get(Int64Ty, Size),
78 ConstantInt::get(Int64Ty, Data),
80 : ConstantExpr::getNullValue(PtrTy)};
81 Constant *EntryInitializer = ConstantStruct::get(getEntryTy(M), EntryData);
82 return {EntryInitializer, Str};
83}
84
87 uint64_t Size, uint32_t Flags,
88 uint64_t Data, Constant *AuxAddr,
90 const llvm::Triple &Triple = M.getTargetTriple();
91
92 auto [EntryInitializer, NameGV] = getOffloadingEntryInitializer(
93 M, Kind, Addr, Name, Size, Flags, Data, AuxAddr);
94
95 StringRef Prefix =
96 Triple.isNVPTX() ? "$offloading$entry$" : ".offloading.entry.";
97 auto *Entry = new GlobalVariable(
98 M, getEntryTy(M),
99 /*isConstant=*/true, GlobalValue::WeakAnyLinkage, EntryInitializer,
100 Prefix + Name, nullptr, GlobalValue::NotThreadLocal,
101 M.getDataLayout().getDefaultGlobalsAddressSpace());
102
103 // The entry has to be created in the section the linker expects it to be.
105 Entry->setSection((SectionName + "$OE").str());
106 else
107 Entry->setSection(SectionName);
108 Entry->setAlignment(Align(object::OffloadBinary::getAlignment()));
109}
110
111std::pair<GlobalVariable *, GlobalVariable *>
113 const llvm::Triple &Triple = M.getTargetTriple();
114
115 auto *ZeroInitilaizer =
116 ConstantAggregateZero::get(ArrayType::get(getEntryTy(M), 0u));
117 auto *EntryInit = Triple.isOSBinFormatCOFF() ? ZeroInitilaizer : nullptr;
118 auto *EntryType = ArrayType::get(getEntryTy(M), 0);
121
122 auto *EntriesB =
123 new GlobalVariable(M, EntryType, /*isConstant=*/true, Linkage, EntryInit,
124 "__start_" + SectionName);
125 EntriesB->setVisibility(GlobalValue::HiddenVisibility);
126 auto *EntriesE =
127 new GlobalVariable(M, EntryType, /*isConstant=*/true, Linkage, EntryInit,
128 "__stop_" + SectionName);
129 EntriesE->setVisibility(GlobalValue::HiddenVisibility);
130
131 if (Triple.isOSBinFormatELF()) {
132 // We assume that external begin/end symbols that we have created above will
133 // be defined by the linker. This is done whenever a section name with a
134 // valid C-identifier is present. We define a dummy variable here to force
135 // the linker to always provide these symbols.
136 auto *DummyEntry = new GlobalVariable(
137 M, ZeroInitilaizer->getType(), true, GlobalVariable::InternalLinkage,
138 ZeroInitilaizer, "__dummy." + SectionName);
139 DummyEntry->setSection(SectionName);
140 DummyEntry->setAlignment(Align(object::OffloadBinary::getAlignment()));
141 appendToCompilerUsed(M, DummyEntry);
142 } else {
143 // The COFF linker will merge sections containing a '$' together into a
144 // single section. The order of entries in this section will be sorted
145 // alphabetically by the characters following the '$' in the name. Set the
146 // sections here to ensure that the beginning and end symbols are sorted.
147 EntriesB->setSection((SectionName + "$OA").str());
148 EntriesE->setSection((SectionName + "$OZ").str());
149 }
150
151 return std::make_pair(EntriesB, EntriesE);
152}
153
155 uint32_t ImageFlags,
156 StringRef EnvTargetID) {
157 using namespace llvm::ELF;
158 StringRef EnvArch = EnvTargetID.split(":").first;
159
160 // Trivial check if the base processors match.
161 if (EnvArch != ImageArch)
162 return false;
163
164 // Check if the image is requesting xnack on or off.
165 switch (ImageFlags & EF_AMDGPU_FEATURE_XNACK_V4) {
166 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
167 // The image is 'xnack-' so the environment must be 'xnack-'.
168 if (!EnvTargetID.contains("xnack-"))
169 return false;
170 break;
171 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
172 // The image is 'xnack+' so the environment must be 'xnack+'.
173 if (!EnvTargetID.contains("xnack+"))
174 return false;
175 break;
176 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
177 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
178 default:
179 break;
180 }
181
182 // Check if the image is requesting sramecc on or off.
183 switch (ImageFlags & EF_AMDGPU_FEATURE_SRAMECC_V4) {
184 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
185 // The image is 'sramecc-' so the environment must be 'sramecc-'.
186 if (!EnvTargetID.contains("sramecc-"))
187 return false;
188 break;
189 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
190 // The image is 'sramecc+' so the environment must be 'sramecc+'.
191 if (!EnvTargetID.contains("sramecc+"))
192 return false;
193 break;
194 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
195 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
196 break;
197 }
198
199 return true;
200}
201
202namespace {
203/// Reads the AMDGPU specific per-kernel-metadata from an image.
204class KernelInfoReader {
205public:
207 : KernelInfoMap(KIM) {}
208
209 /// Process ELF note to read AMDGPU metadata from respective information
210 /// fields.
211 Error processNote(const llvm::object::ELF64LE::Note &Note, size_t Align) {
212 if (Note.getName() != "AMDGPU")
213 return Error::success(); // We are not interested in other things
214
215 assert(Note.getType() == ELF::NT_AMDGPU_METADATA &&
216 "Parse AMDGPU MetaData");
217 auto Desc = Note.getDesc(Align);
218 StringRef MsgPackString =
219 StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
220 msgpack::Document MsgPackDoc;
221 if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false))
222 return Error::success();
223
225 if (!Verifier.verify(MsgPackDoc.getRoot()))
226 return Error::success();
227
228 auto RootMap = MsgPackDoc.getRoot().getMap(true);
229
230 if (auto Err = iterateAMDKernels(RootMap))
231 return Err;
232
233 return Error::success();
234 }
235
236private:
237 /// Extracts the relevant information via simple string look-up in the msgpack
238 /// document elements.
239 Error
240 extractKernelData(msgpack::MapDocNode::MapTy::value_type V,
241 std::string &KernelName,
243 if (!V.first.isString())
244 return Error::success();
245
246 const auto IsKey = [](const msgpack::DocNode &DK, StringRef SK) {
247 return DK.getString() == SK;
248 };
249
250 const auto GetSequenceOfThreeInts = [](msgpack::DocNode &DN,
251 uint32_t *Vals) {
252 assert(DN.isArray() && "MsgPack DocNode is an array node");
253 auto DNA = DN.getArray();
254 assert(DNA.size() == 3 && "ArrayNode has at most three elements");
255
256 int I = 0;
257 for (auto DNABegin = DNA.begin(), DNAEnd = DNA.end(); DNABegin != DNAEnd;
258 ++DNABegin) {
259 Vals[I++] = DNABegin->getUInt();
260 }
261 };
262
263 if (IsKey(V.first, ".name")) {
264 KernelName = V.second.toString();
265 } else if (IsKey(V.first, ".sgpr_count")) {
266 KernelData.SGPRCount = V.second.getUInt();
267 } else if (IsKey(V.first, ".sgpr_spill_count")) {
268 KernelData.SGPRSpillCount = V.second.getUInt();
269 } else if (IsKey(V.first, ".vgpr_count")) {
270 KernelData.VGPRCount = V.second.getUInt();
271 } else if (IsKey(V.first, ".vgpr_spill_count")) {
272 KernelData.VGPRSpillCount = V.second.getUInt();
273 } else if (IsKey(V.first, ".agpr_count")) {
274 KernelData.AGPRCount = V.second.getUInt();
275 } else if (IsKey(V.first, ".private_segment_fixed_size")) {
276 KernelData.PrivateSegmentSize = V.second.getUInt();
277 } else if (IsKey(V.first, ".group_segment_fixed_size")) {
278 KernelData.GroupSegmentList = V.second.getUInt();
279 } else if (IsKey(V.first, ".reqd_workgroup_size")) {
280 GetSequenceOfThreeInts(V.second, KernelData.RequestedWorkgroupSize);
281 } else if (IsKey(V.first, ".workgroup_size_hint")) {
282 GetSequenceOfThreeInts(V.second, KernelData.WorkgroupSizeHint);
283 } else if (IsKey(V.first, ".wavefront_size")) {
284 KernelData.WavefrontSize = V.second.getUInt();
285 } else if (IsKey(V.first, ".max_flat_workgroup_size")) {
286 KernelData.MaxFlatWorkgroupSize = V.second.getUInt();
287 }
288
289 return Error::success();
290 }
291
292 /// Get the "amdhsa.kernels" element from the msgpack Document
294 auto Res = MDN.find("amdhsa.kernels");
295 if (Res == MDN.end())
297 "Could not find amdhsa.kernels key");
298
299 auto Pair = *Res;
300 assert(Pair.second.isArray() &&
301 "AMDGPU kernel entries are arrays of entries");
302
303 return Pair.second.getArray();
304 }
305
306 /// Iterate all entries for one "amdhsa.kernels" entry. Each entry is a
307 /// MapDocNode that either maps a string to a single value (most of them) or
308 /// to another array of things. Currently, we only handle the case that maps
309 /// to scalar value.
310 Error generateKernelInfo(msgpack::ArrayDocNode::ArrayTy::iterator It) {
312 std::string KernelName;
313 auto Entry = (*It).getMap();
314 for (auto MI = Entry.begin(), E = Entry.end(); MI != E; ++MI)
315 if (auto Err = extractKernelData(*MI, KernelName, KernelData))
316 return Err;
317
318 KernelInfoMap.insert({KernelName, KernelData});
319 return Error::success();
320 }
321
322 /// Go over the list of AMD kernels in the "amdhsa.kernels" entry
323 Error iterateAMDKernels(msgpack::MapDocNode &MDN) {
324 auto KernelsOrErr = getAMDKernelsArray(MDN);
325 if (auto Err = KernelsOrErr.takeError())
326 return Err;
327
328 auto KernelsArr = *KernelsOrErr;
329 for (auto It = KernelsArr.begin(), E = KernelsArr.end(); It != E; ++It) {
330 if (!It->isMap())
331 continue; // we expect <key,value> pairs
332
333 // Obtain the value for the different entries. Each array entry is a
334 // MapDocNode
335 if (auto Err = generateKernelInfo(It))
336 return Err;
337 }
338 return Error::success();
339 }
340
341 // Kernel names are the keys
343};
344} // namespace
345
347 MemoryBufferRef MemBuffer,
349 uint16_t &ELFABIVersion) {
350 Error Err = Error::success(); // Used later as out-parameter
351
352 auto ELFOrError = object::ELF64LEFile::create(MemBuffer.getBuffer());
353 if (auto Err = ELFOrError.takeError())
354 return Err;
355
356 const object::ELF64LEFile ELFObj = ELFOrError.get();
358 if (!Sections)
359 return Sections.takeError();
360 KernelInfoReader Reader(KernelInfoMap);
361
362 // Read the code object version from ELF image header
363 auto Header = ELFObj.getHeader();
364 ELFABIVersion = (uint8_t)(Header.e_ident[ELF::EI_ABIVERSION]);
365 for (const auto &S : *Sections) {
366 if (S.sh_type != ELF::SHT_NOTE)
367 continue;
368
369 for (const auto N : ELFObj.notes(S, Err)) {
370 if (Err)
371 return Err;
372 // Fills the KernelInfoTabel entries in the reader
373 if ((Err = Reader.processNote(N, S.sh_addralign)))
374 return Err;
375 }
376 }
377 return Error::success();
378}
380 std::unique_ptr<MemoryBuffer> &Img) {
381 constexpr char INTEL_ONEOMP_OFFLOAD_VERSION[] = "1.0";
382 constexpr int NT_INTEL_ONEOMP_OFFLOAD_VERSION = 1;
383 constexpr int NT_INTEL_ONEOMP_OFFLOAD_IMAGE_COUNT = 2;
384 constexpr int NT_INTEL_ONEOMP_OFFLOAD_IMAGE_AUX = 3;
385
386 // Start creating notes for the ELF container.
387 std::vector<ELFYAML::NoteEntry> Notes;
388 std::string Version = toHex(INTEL_ONEOMP_OFFLOAD_VERSION);
389 Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
390 yaml::BinaryRef(Version),
391 NT_INTEL_ONEOMP_OFFLOAD_VERSION});
392
393 // The AuxInfo string will hold auxiliary information for the image.
394 // ELFYAML::NoteEntry structures will hold references to the
395 // string, so we have to make sure the string is valid.
396 std::string AuxInfo;
397
398 // TODO: Pass compile/link opts
399 StringRef CompileOpts = "";
400 StringRef LinkOpts = "";
401
402 unsigned ImageFmt = 1; // SPIR-V format
403
404 AuxInfo = toHex((Twine(0) + Twine('\0') + Twine(ImageFmt) + Twine('\0') +
405 CompileOpts + Twine('\0') + LinkOpts)
406 .str());
407 Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
408 yaml::BinaryRef(AuxInfo),
409 NT_INTEL_ONEOMP_OFFLOAD_IMAGE_AUX});
410
411 std::string ImgCount = toHex(Twine(1).str()); // always one image per ELF
412 Notes.emplace_back(ELFYAML::NoteEntry{"INTELONEOMPOFFLOAD",
413 yaml::BinaryRef(ImgCount),
414 NT_INTEL_ONEOMP_OFFLOAD_IMAGE_COUNT});
415
416 std::string YamlFile;
417 llvm::raw_string_ostream YamlFileStream(YamlFile);
418
419 // Write the YAML template file.
420
421 // We use 64-bit little-endian ELF currently.
422 ELFYAML::FileHeader Header{};
423 Header.Class = ELF::ELFCLASS64;
424 Header.Data = ELF::ELFDATA2LSB;
425 Header.Type = ELF::ET_DYN;
426 // Use an existing Intel machine type as there is not one specifically for
427 // Intel GPUs.
428 Header.Machine = ELF::EM_IA_64;
429
430 // Create a section with notes.
431 ELFYAML::NoteSection Section{};
432 Section.Type = ELF::SHT_NOTE;
433 Section.AddressAlign = 0;
434 Section.Name = ".note.inteloneompoffload";
435 Section.Notes.emplace(std::move(Notes));
436
437 ELFYAML::Object Object{};
438 Object.Header = Header;
439 Object.Chunks.push_back(
440 std::make_unique<ELFYAML::NoteSection>(std::move(Section)));
441
442 // Create the section that will hold the image
443 ELFYAML::RawContentSection ImageSection{};
444 ImageSection.Type = ELF::SHT_PROGBITS;
445 ImageSection.AddressAlign = 0;
446 std::string Name = "__openmp_offload_spirv_0";
447 ImageSection.Name = Name;
448 ImageSection.Content =
449 llvm::yaml::BinaryRef(arrayRefFromStringRef(Img->getBuffer()));
450 Object.Chunks.push_back(
451 std::make_unique<ELFYAML::RawContentSection>(std::move(ImageSection)));
452 Error Err = Error::success();
454 Object, YamlFileStream,
455 [&Err](const Twine &Msg) { Err = createStringError(Msg); }, UINT64_MAX);
456 if (Err)
457 return Err;
458
459 Img = MemoryBuffer::getMemBufferCopy(YamlFile);
460 return Error::success();
461}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This is a verifier for AMDGPU HSA metadata, which can verify both well-typed metadata and untyped met...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
uint64_t Addr
std::string Name
uint64_t Size
This file declares classes for handling the YAML representation of ELF.
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares a class that exposes a simple in-memory representation of a document of MsgPack ob...
verify safepoint Safepoint IR Verifier
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
Definition: Constants.cpp:1677
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:2989
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
Definition: Constants.cpp:2261
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1380
This is an important base class in LLVM.
Definition: Constant.h:43
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
Tagged union holding either a T or a Error.
Definition: Error.h:485
Error takeError()
Take ownership of the stored error.
Definition: Error.h:612
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:69
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:60
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:58
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:53
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:57
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Root of the metadata hierarchy.
Definition: Metadata.h:63
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
A tuple of MDNodes.
Definition: Metadata.h:1753
LLVM_ABI void addOperand(MDNode *M)
Definition: Metadata.cpp:1471
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:133
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:710
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:434
Class to represent struct types.
Definition: DerivedTypes.h:218
static LLVM_ABI StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
Definition: Type.cpp:739
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:620
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:771
bool isNVPTX() const
Tests whether the target is NVPTX (32- or 64-bit).
Definition: Triple.h:896
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:766
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
A node in a MsgPack Document.
MapDocNode & getMap(bool Convert=false)
Get a MapDocNode for a map node.
ArrayDocNode & getArray(bool Convert=false)
Get an ArrayDocNode for an array node.
StringRef getString() const
Simple in-memory representation of a document of msgpack objects with ability to find and create arra...
DocNode & getRoot()
Get ref to the document's root element.
LLVM_ABI bool readFromBlob(StringRef Blob, bool Multi, function_ref< int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)> Merger=[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) { return -1;})
Read a document from a binary msgpack blob, merging into anything already in the Document.
A DocNode that is a map.
MapTy::iterator find(DocNode Key)
const Elf_Ehdr & getHeader() const
Definition: ELF.h:284
static Expected< ELFFile > create(StringRef Object)
Definition: ELF.h:893
iterator_range< Elf_Note_Iterator > notes(const Elf_Phdr &Phdr, Error &Err) const
Get an iterator range over notes of a program header.
Definition: ELF.h:467
Expected< Elf_Shdr_Range > sections() const
Definition: ELF.h:930
static uint64_t getAlignment()
Definition: OffloadBinary.h:87
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
Specialized YAMLIO scalar type for representing a binary blob.
Definition: YAML.h:64
#define UINT64_MAX
Definition: DataTypes.h:77
@ Entry
Definition: COFF.h:862
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
Definition: ELF.h:30
@ ELFCLASS64
Definition: ELF.h:334
@ EI_ABIVERSION
Definition: ELF.h:59
@ EM_IA_64
Definition: ELF.h:171
@ NT_AMDGPU_METADATA
Definition: ELF.h:1977
@ SHT_PROGBITS
Definition: ELF.h:1140
@ SHT_NOTE
Definition: ELF.h:1146
@ ET_DYN
Definition: ELF.h:121
@ ELFDATA2LSB
Definition: ELF.h:340
OffloadKind
The producer of the associated offloading image.
Definition: OffloadBinary.h:34
LLVM_ABI Error getAMDGPUMetaDataFromImage(MemoryBufferRef MemBuffer, StringMap< AMDGPUKernelMetaData > &KernelInfoMap, uint16_t &ELFABIVersion)
Reads AMDGPU specific metadata from the ELF file and propagates the KernelInfoMap.
Definition: Utility.cpp:346
LLVM_ABI bool isImageCompatibleWithEnv(StringRef ImageArch, uint32_t ImageFlags, StringRef EnvTargetID)
Check if an image is compatible with current system's environment.
Definition: Utility.cpp:154
LLVM_ABI Error containerizeOpenMPSPIRVImage(std::unique_ptr< MemoryBuffer > &Binary)
Containerizes an offloading binary into the ELF binary format expected by the Intel runtime offload p...
Definition: Utility.cpp:379
LLVM_ABI void emitOffloadingEntry(Module &M, object::OffloadKind Kind, Constant *Addr, StringRef Name, uint64_t Size, uint32_t Flags, uint64_t Data, Constant *AuxAddr=nullptr, StringRef SectionName="llvm_offload_entries")
Create an offloading section struct used to register this global at runtime.
Definition: Utility.cpp:85
LLVM_ABI std::pair< Constant *, GlobalVariable * > getOffloadingEntryInitializer(Module &M, object::OffloadKind Kind, Constant *Addr, StringRef Name, uint64_t Size, uint32_t Flags, uint64_t Data, Constant *AuxAddr)
Create a constant struct initializer used to register this global at runtime.
Definition: Utility.cpp:40
LLVM_ABI StructType * getEntryTy(Module &M)
Returns the type of the offloading entry we use to store kernels and globals that will be registered ...
Definition: Utility.cpp:26
LLVM_ABI std::pair< GlobalVariable *, GlobalVariable * > getOffloadEntryArray(Module &M, StringRef SectionName="llvm_offload_entries")
Creates a pair of globals used to iterate the array of offloading entries by accessing the section va...
Definition: Utility.cpp:112
LLVM_ABI bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH, uint64_t MaxSize)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1305
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Description of the encoding of one expression Op.
This is the record of an object that just be registered with the offloading runtime.
Definition: Utility.h:28
Struct for holding metadata related to AMDGPU kernels, for more information about the metadata and it...
Definition: Utility.h:120
uint32_t SGPRSpillCount
Number of stores from a scalar register to a register allocator created spill location.
Definition: Utility.h:135
uint32_t SGPRCount
Number of scalar registers required by a wavefront.
Definition: Utility.h:130
uint32_t VGPRSpillCount
Number of stores from a vector register to a register allocator created spill location.
Definition: Utility.h:138
uint32_t VGPRCount
Number of vector registers required by each work-item.
Definition: Utility.h:132
uint32_t PrivateSegmentSize
The amount of fixed private address space memory required for a work-item in bytes.
Definition: Utility.h:128
uint32_t GroupSegmentList
The amount of group segment memory required by a work-group in bytes.
Definition: Utility.h:125
uint32_t MaxFlatWorkgroupSize
Maximum flat work-group size supported by the kernel in work-items.
Definition: Utility.h:149
uint32_t WorkgroupSizeHint[3]
Corresponds to the OpenCL work_group_size_hint attribute.
Definition: Utility.h:145
uint32_t AGPRCount
Number of accumulator registers required by each work-item.
Definition: Utility.h:140
uint32_t RequestedWorkgroupSize[3]
Corresponds to the OpenCL reqd_work_group_size attribute.
Definition: Utility.h:142
Common declarations for yaml2obj.