LLVM 24.0.0git
OffloadBinary.cpp
Go to the documentation of this file.
1//===- OffloadBinary.cpp - Utilities for handling offloading code ---------===//
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
10
11#include "llvm/ADT/ArrayRef.h"
15#include "llvm/IR/Constants.h"
16#include "llvm/IR/Module.h"
19#include "llvm/Object/Archive.h"
20#include "llvm/Object/Binary.h"
22#include "llvm/Object/Error.h"
27#include "llvm/Support/Error.h"
31
32#include <cassert>
33#include <cstddef>
34#include <memory>
35
36using namespace llvm;
37using namespace llvm::object;
38
39namespace {
40
41/// Attempts to extract all the embedded device images contained inside the
42/// buffer \p Contents. The buffer is expected to contain a valid offloading
43/// binary format.
44Error extractOffloadFiles(MemoryBufferRef Contents,
46 uint64_t Offset = 0;
47 // There could be multiple offloading binaries stored at this section.
48 while (Offset < Contents.getBufferSize()) {
49 std::unique_ptr<MemoryBuffer> Buffer =
51 /*RequiresNullTerminator*/ false);
53 Buffer->getBufferStart()))
54 Buffer = MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(),
55 Buffer->getBufferIdentifier());
56
57 auto HeaderOrErr = OffloadBinary::extractHeader(*Buffer);
58 if (!HeaderOrErr)
59 return HeaderOrErr.takeError();
60 const OffloadBinary::Header *Header = *HeaderOrErr;
61
62 MemoryBufferRef Slice(Buffer->getBuffer().take_front(Header->Size),
63 Contents.getBufferIdentifier());
64 auto BinariesOrErr = OffloadBinary::create(Slice);
65 if (!BinariesOrErr)
66 return BinariesOrErr.takeError();
67
68 for (auto &Binary : *BinariesOrErr)
69 Binaries.emplace_back(std::move(Binary));
70
72 }
73
74 return Error::success();
75}
76
77// Extract offloading binaries from an Object file \p Obj.
78Error extractFromObject(const ObjectFile &Obj,
80 assert((Obj.isELF() || Obj.isCOFF()) && "Invalid file type");
81
82 for (SectionRef Sec : Obj.sections()) {
83 // ELF files contain a section with the LLVM_OFFLOADING type.
84 if (Obj.isELF() &&
85 static_cast<ELFSectionRef>(Sec).getType() != ELF::SHT_LLVM_OFFLOADING)
86 continue;
87
88 // COFF has no section types so we rely on the name of the section.
89 if (Obj.isCOFF()) {
90 Expected<StringRef> NameOrErr = Sec.getName();
91 if (!NameOrErr)
92 return NameOrErr.takeError();
93
94 if (!NameOrErr->starts_with(".llvm.offloading"))
95 continue;
96 }
97
98 Expected<StringRef> Buffer = Sec.getContents();
99 if (!Buffer)
100 return Buffer.takeError();
101
102 MemoryBufferRef Contents(*Buffer, Obj.getFileName());
103 if (Error Err = extractOffloadFiles(Contents, Binaries))
104 return Err;
105 }
106
107 return Error::success();
108}
109
110Error extractFromBitcode(MemoryBufferRef Buffer,
112 LLVMContext Context;
113 SMDiagnostic Err;
114 std::unique_ptr<Module> M = getLazyIRModule(
115 MemoryBuffer::getMemBuffer(Buffer, /*RequiresNullTerminator=*/false), Err,
116 Context);
117 if (!M)
119 "Failed to create module");
120
121 // Extract offloading data from globals referenced by the
122 // `llvm.embedded.object` metadata with the `.llvm.offloading` section.
123 auto *MD = M->getNamedMetadata("llvm.embedded.objects");
124 if (!MD)
125 return Error::success();
126
127 for (const MDNode *Op : MD->operands()) {
128 if (Op->getNumOperands() < 2)
129 continue;
130
131 MDString *SectionID = dyn_cast<MDString>(Op->getOperand(1));
132 if (!SectionID || SectionID->getString() != ".llvm.offloading")
133 continue;
134
135 GlobalVariable *GV =
137 if (!GV)
138 continue;
139
141 if (!CDS)
142 continue;
143
144 MemoryBufferRef Contents(CDS->getAsString(), M->getName());
145 if (Error Err = extractOffloadFiles(Contents, Binaries))
146 return Err;
147 }
148
149 return Error::success();
150}
151
152Error extractFromArchive(const Archive &Library,
154 // Try to extract device code from each file stored in the static archive.
155 Error Err = Error::success();
156 for (auto Child : Library.children(Err)) {
157 auto ChildBufferOrErr = Child.getMemoryBufferRef();
158 if (!ChildBufferOrErr)
159 return ChildBufferOrErr.takeError();
160 std::unique_ptr<MemoryBuffer> ChildBuffer =
161 MemoryBuffer::getMemBuffer(*ChildBufferOrErr, false);
162
163 // Check if the buffer has the required alignment.
165 ChildBuffer->getBufferStart()))
166 ChildBuffer = MemoryBuffer::getMemBufferCopy(
167 ChildBufferOrErr->getBuffer(),
168 ChildBufferOrErr->getBufferIdentifier());
169
170 if (Error Err = extractOffloadBinaries(*ChildBuffer, Binaries))
171 return Err;
172 }
173
174 if (Err)
175 return Err;
176 return Error::success();
177}
178
179bool isCompressed(const OffloadBinary::Header &Header) {
180 return Header.Version >= 3 && Header.InflatedSize != 0;
181}
182
184decompressOffloadBinary(MemoryBufferRef Buf) {
185 const auto *Header =
186 reinterpret_cast<const OffloadBinary::Header *>(Buf.getBufferStart());
187 if (Header->EntriesOffset != sizeof(OffloadBinary::Header) ||
188 Header->EntriesOffset > Header->Size ||
189 Header->InflatedSize < Header->EntriesOffset)
191
192 // Get the compressed binary blob after the header.
193 StringRef Compressed = Buf.getBuffer()
194 .take_front(Header->Size)
195 .drop_front(Header->EntriesOffset);
196 uint64_t BodySize = Header->InflatedSize - Header->EntriesOffset;
197
200 Body, BodySize))
201 return std::move(Err);
202
203 // Restore the old header data for the newly uncompressed blob.
204 OffloadBinary::Header Restored = *Header;
205 Restored.Size = Restored.InflatedSize;
206 Restored.InflatedSize = 0;
207 if (Restored.EntriesOffset + Body.size() != Restored.Size)
209
211 Out.reserve(Restored.Size);
212 Out.append(StringRef(reinterpret_cast<const char *>(&Restored),
213 sizeof(OffloadBinary::Header)));
214 Out.append(toStringRef(Body));
216}
217
218} // namespace
219
222 if (Buf.getBufferSize() < sizeof(Header))
224
225 // Check for 0x10FF1OAD magic bytes.
228
229 // Make sure that the data has sufficient alignment.
232
233 const char *Start = Buf.getBufferStart();
234 const Header *TheHeader = reinterpret_cast<const Header *>(Start);
235 if (TheHeader->Version == 0 || TheHeader->Version > OffloadBinary::Version)
237
238 if (TheHeader->Size > Buf.getBufferSize() || TheHeader->Size < sizeof(Header))
240
241 if (isCompressed(*TheHeader))
242 return TheHeader;
243
244 if (TheHeader->Size < sizeof(Entry))
246
247 uint64_t EntriesCount =
248 (TheHeader->Version == 1) ? 1 : TheHeader->EntriesCount;
249 uint64_t EntriesSize = sizeof(Entry) * EntriesCount;
250 if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize ||
251 // v1/v2 headers are 32 bytes; sizeof(Header) grew in v3.
252 EntriesSize > TheHeader->Size - offsetof(Header, InflatedSize))
254
255 return TheHeader;
256}
257
259OffloadBinary::create(MemoryBufferRef Buf, std::optional<uint64_t> Index) {
260 auto HeaderOrErr = extractHeader(Buf);
261 if (!HeaderOrErr)
262 return HeaderOrErr.takeError();
263 const Header *OnDisk = *HeaderOrErr;
264
265 // The binary data may be a compressed image.
266 std::shared_ptr<MemoryBuffer> Binary;
267 if (isCompressed(*OnDisk)) {
268 auto DecompressedOrErr = decompressOffloadBinary(Buf);
269 if (!DecompressedOrErr)
270 return DecompressedOrErr.takeError();
271 Binary = std::shared_ptr<MemoryBuffer>(std::move(*DecompressedOrErr));
272 } else {
273 Binary = std::shared_ptr<MemoryBuffer>(MemoryBuffer::getMemBufferCopy(
274 Buf.getBuffer().take_front(OnDisk->Size), Buf.getBufferIdentifier()));
275 }
276
277 // Owned is now an uncompressed OffloadBinary, parse it as before.
278 MemoryBufferRef Owned = *Binary;
279 HeaderOrErr = extractHeader(Owned);
280 if (!HeaderOrErr)
281 return HeaderOrErr.takeError();
282 const Header *TheHeader = *HeaderOrErr;
283
284 const char *Start = Owned.getBufferStart();
285 const Entry *Entries =
286 reinterpret_cast<const Entry *>(&Start[TheHeader->EntriesOffset]);
287
288 auto validateEntry = [&](const Entry *TheEntry) -> Error {
289 const uint64_t BufSize = Owned.getBufferSize();
290 if (TheEntry->ImageOffset > BufSize ||
291 TheEntry->ImageSize > BufSize - TheEntry->ImageOffset)
293
294 const size_t StringEntrySize =
295 TheHeader->Version == 1 ? sizeof(StringEntryV1) : sizeof(StringEntry);
296 if (TheEntry->StringOffset > BufSize ||
297 TheEntry->NumStrings >
298 (BufSize - TheEntry->StringOffset) / StringEntrySize)
300 return Error::success();
301 };
302
304 if (TheHeader->Version > 1 && Index.has_value()) {
305 if (*Index >= TheHeader->EntriesCount)
307 const Entry *TheEntry = &Entries[*Index];
308 if (auto Err = validateEntry(TheEntry))
309 return std::move(Err);
310
311 Binaries.emplace_back(
312 new OffloadBinary(Binary, TheHeader, TheEntry, *Index));
313 return std::move(Binaries);
314 }
315
316 uint64_t EntriesCount = TheHeader->Version == 1 ? 1 : TheHeader->EntriesCount;
317 for (uint64_t I = 0; I < EntriesCount; ++I) {
318 const Entry *TheEntry = &Entries[I];
319 if (auto Err = validateEntry(TheEntry))
320 return std::move(Err);
321
322 Binaries.emplace_back(new OffloadBinary(Binary, TheHeader, TheEntry, I));
323 }
324
325 return std::move(Binaries);
326}
327
329 uint64_t EntriesCount = OffloadingData.size();
330 assert(EntriesCount > 0 && "At least one offloading image is required");
331
332 // Create a null-terminated string table with all the used strings.
333 // Also calculate total size of images.
335 uint64_t TotalStringEntries = 0;
336 uint64_t TotalImagesSize = 0;
337 for (const OffloadingImage &Img : OffloadingData) {
338 for (auto &KeyAndValue : Img.StringData) {
339 StrTab.add(KeyAndValue.first);
340 StrTab.add(KeyAndValue.second);
341 }
342 TotalStringEntries += Img.StringData.size();
343 TotalImagesSize += Img.Image->getBufferSize();
344 }
345 StrTab.finalize();
346
347 uint64_t StringEntrySize = sizeof(StringEntry) * TotalStringEntries;
348 uint64_t EntriesSize = sizeof(Entry) * EntriesCount;
349 uint64_t StrTabOffset = sizeof(Header) + EntriesSize + StringEntrySize;
350
351 // Make sure the image we're wrapping around is aligned as well.
352 uint64_t BinaryDataSize =
353 alignTo(StrTabOffset + StrTab.getSize(), getAlignment());
354
355 // Create the header and fill in the offsets. The entries will be directly
356 // placed after the header in memory. Align the size to the alignment of the
357 // header so this can be placed contiguously in a single section.
358 Header TheHeader{};
359 TheHeader.Size = alignTo(BinaryDataSize + TotalImagesSize, getAlignment());
360 TheHeader.EntriesOffset = sizeof(Header);
361 TheHeader.EntriesCount = EntriesCount;
362
364 Data.reserve(TheHeader.Size);
366 OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
367
368 // Create the entries using the string table offsets. The string table will be
369 // placed directly after the set of entries in memory, and all the images are
370 // after that.
371 uint64_t StringEntryOffset = sizeof(Header) + EntriesSize;
372 uint64_t ImageOffset = BinaryDataSize;
373 for (const OffloadingImage &Img : OffloadingData) {
374 Entry TheEntry;
375
376 TheEntry.TheImageKind = Img.TheImageKind;
377 TheEntry.TheOffloadKind = Img.TheOffloadKind;
378 TheEntry.Flags = Img.Flags;
379
380 TheEntry.StringOffset = StringEntryOffset;
381 StringEntryOffset += sizeof(StringEntry) * Img.StringData.size();
382 TheEntry.NumStrings = Img.StringData.size();
383
384 TheEntry.ImageOffset = ImageOffset;
385 ImageOffset += Img.Image->getBufferSize();
386 TheEntry.ImageSize = Img.Image->getBufferSize();
387
388 OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
389 }
390
391 // Create the string map entries.
392 for (const OffloadingImage &Img : OffloadingData) {
393 for (auto &KeyAndValue : Img.StringData) {
394 StringEntry Map{StrTabOffset + StrTab.getOffset(KeyAndValue.first),
395 StrTabOffset + StrTab.getOffset(KeyAndValue.second),
396 KeyAndValue.second.size()};
397 OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
398 }
399 }
400
401 StrTab.write(OS);
402 // Add padding to required image alignment.
403 OS.write_zeros(BinaryDataSize - OS.tell());
404
405 for (const OffloadingImage &Img : OffloadingData)
406 OS << Img.Image->getBuffer();
407
408 // Add final padding to required alignment.
409 assert(TheHeader.Size >= OS.tell() && "Too much data written?");
410 OS.write_zeros(TheHeader.Size - OS.tell());
411 assert(TheHeader.Size == OS.tell() && "Size mismatch");
412
413 return Data;
414}
415
418 compression::Params Compress) {
419 if (const char *Reason = compression::getReasonIfUnsupported(Compress.format))
420 return createStringError(Reason);
421
422 // Write the complete offloading binary as normal.
423 SmallString<0> Uncompressed = write(OffloadingData);
425 *reinterpret_cast<const OffloadBinary::Header *>(Uncompressed.data());
426
427 // Compress the entries after the header with the requested configuration.
428 StringRef Body = StringRef(Uncompressed).drop_front(Header.EntriesOffset);
429 SmallVector<uint8_t, 0> CompressedBuffer;
431 CompressedBuffer);
432
433 // Reset the header sizes and create the newly compressed binary.
434 Header.InflatedSize = Uncompressed.size();
435 Header.Size = Header.EntriesOffset + CompressedBuffer.size();
436
438 Data.reserve(alignTo(Header.Size, getAlignment()));
440 OS << StringRef(reinterpret_cast<const char *>(&Header),
442 OS << toStringRef(CompressedBuffer);
443 assert(Header.Size == OS.tell() && "Size mismatch");
445 return Data;
446}
447
451 switch (Type) {
453 return extractFromBitcode(Buffer, Binaries);
460 if (!ObjFile)
461 return ObjFile.takeError();
462 return extractFromObject(*ObjFile->get(), Binaries);
463 }
464 case file_magic::archive: {
467 if (!LibFile)
468 return LibFile.takeError();
469 return extractFromArchive(*LibFile->get(), Binaries);
470 }
472 return extractOffloadFiles(Buffer, Binaries);
473 default:
474 return Error::success();
475 }
476}
477
480 .Case("openmp", OFK_OpenMP)
481 .Case("cuda", OFK_Cuda)
482 .Case("hip", OFK_HIP)
483 .Case("sycl", OFK_SYCL)
485}
486
488 switch (Kind) {
489 case OFK_OpenMP:
490 return "openmp";
491 case OFK_Cuda:
492 return "cuda";
493 case OFK_HIP:
494 return "hip";
495 case OFK_SYCL:
496 return "sycl";
497 default:
498 return "none";
499 }
500}
501
504 .Case("o", IMG_Object)
505 .Case("bc", IMG_Bitcode)
506 .Case("cubin", IMG_Cubin)
507 .Case("fatbin", IMG_Fatbinary)
508 .Case("s", IMG_PTX)
509 .Case("spv", IMG_SPIRV)
511}
512
514 switch (Kind) {
515 case IMG_Object:
516 return "o";
517 case IMG_Bitcode:
518 return "bc";
519 case IMG_Cubin:
520 return "cubin";
521 case IMG_Fatbinary:
522 return "fatbin";
523 case IMG_PTX:
524 return "s";
525 case IMG_SPIRV:
526 return "spv";
527 default:
528 return "";
529 }
530}
531
533 const OffloadFile::TargetID &RHS) {
534 llvm::Triple LHSTT(LHS.first);
535 llvm::Triple RHSTT(RHS.first);
536
537 // Check for logical AMDGPU target-id equivalence.
538 if (LHSTT.isAMDGPU()) {
539 AMDGPU::TargetID LHSID(LHSTT, LHS.second);
540 AMDGPU::TargetID RHSID(RHSTT, RHS.second);
541 return LHSID.isEquivalent(RHSID);
542 }
543
544 // For other targets the triples must be compatible and the arch must match.
545 return LHSTT.isCompatibleWith(RHSTT) && LHS.second == RHS.second;
546}
547
549 const OffloadFile::TargetID &Requested) {
550 llvm::Triple ProvidedTT(Provided.first);
551 llvm::Triple RequestedTT(Requested.first);
552
553 // The AMDGPU target requires target-id aware checks (base processor plus
554 // xnack/sramecc features).
555 if (ProvidedTT.isAMDGPU()) {
556 AMDGPU::TargetID ProvidedID(ProvidedTT, Provided.second);
557 AMDGPU::TargetID RequestedID(RequestedTT, Requested.second);
558 return ProvidedID.providesFor(RequestedID);
559 }
560
561 // For other targets the triples must be compatible.
562 if (!ProvidedTT.isCompatibleWith(RequestedTT))
563 return false;
564
565 // If the architecture is "generic" we assume it is always compatible.
566 if (Provided.second == "generic" || Requested.second == "generic")
567 return true;
568
569 return Provided.second == Requested.second;
570}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
#define offsetof(TYPE, MEMBER)
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some functions that are useful when dealing with strings.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool isEquivalent(const TargetID &Other) const
Returns true if Other denotes the same target as *this, i.e.
bool providesFor(const TargetID &Other) const
Returns true if a device image for *this can provide the device code for a request for Other.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
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
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Metadata node.
Definition Metadata.h:1081
A single uniqued string.
Definition Metadata.h:733
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:615
size_t getBufferSize() const
StringRef getBufferIdentifier() const
const char * getBufferStart() const
StringRef getBuffer() const
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
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.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition SourceMgr.h:305
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition StringRef.h:635
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition StringRef.h:606
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Utility for building string tables with deduplicated suffixes.
LLVM_ABI size_t getOffset(CachedHashStringRef S) const
Get the offest of a string in the string table.
LLVM_ABI size_t add(CachedHashStringRef S, uint8_t Priority=0)
Add a string to the builder.
LLVM_ABI void write(raw_ostream &OS) const
LLVM_ABI void finalize()
Analyze the strings and build the final table.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isAMDGPU() const
Definition Triple.h:997
LLVM_ABI bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Definition Triple.cpp:2274
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
iterator_range< child_iterator > children(Error &Err, bool SkipInternal=true) const
Definition Archive.h:416
static Expected< std::unique_ptr< Archive > > create(MemoryBufferRef Source)
Definition Archive.cpp:785
MemoryBufferRef Data
Definition Binary.h:38
Binary(unsigned int Type, MemoryBufferRef Source)
Definition Binary.cpp:36
This class is the base class for all object file types.
Definition ObjectFile.h:231
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
static uint64_t getAlignment()
static LLVM_ABI Expected< SmallVector< std::unique_ptr< OffloadBinary > > > create(MemoryBufferRef Buf, std::optional< uint64_t > Index=std::nullopt)
Attempt to parse the offloading binary stored in Buf.
static LLVM_ABI SmallString< 0 > write(ArrayRef< OffloadingImage > OffloadingData)
Serialize the contents of OffloadingData to a binary buffer to be read later.
static LLVM_ABI Expected< const Header * > extractHeader(MemoryBufferRef Buf)
Attempt to extract and validate the header from the offloading binary in Buf.
static const uint32_t Version
The current version of the binary used for backwards compatibility.
std::pair< StringRef, StringRef > TargetID
This is a value type class that represents a single section in the list of sections in the object fil...
Definition ObjectFile.h:83
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
A raw_ostream that writes to an SmallVector or SmallString.
@ SHT_LLVM_OFFLOADING
Definition ELF.h:1196
LLVM_ABI const char * getReasonIfUnsupported(Format F)
LLVM_ABI Error decompress(DebugCompressionType T, ArrayRef< uint8_t > Input, uint8_t *Output, size_t UncompressedSize)
LLVM_ABI void compress(Params P, ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &Output)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:720
LLVM_ABI bool areTargetsEquivalent(const OffloadFile::TargetID &LHS, const OffloadFile::TargetID &RHS)
Returns true if LHS and RHS denote the same logical target, i.e.
LLVM_ABI bool areTargetsCompatible(const OffloadFile::TargetID &Provided, const OffloadFile::TargetID &Requested)
Returns true if an image built for target Provided can provide the device code for a request for targ...
LLVM_ABI Error extractOffloadBinaries(MemoryBufferRef Buffer, SmallVectorImpl< OffloadFile > &Binaries)
Extracts embedded device offloading code from a memory Buffer to a list of Binaries.
LLVM_ABI ImageKind getImageKind(StringRef Name)
Convert a string Name to an image kind.
OffloadKind
The producer of the associated offloading image.
LLVM_ABI OffloadKind getOffloadKind(StringRef Name)
Convert a string Name to an offload kind.
LLVM_ABI StringRef getImageKindName(ImageKind Name)
Convert an image kind to its string representation.
ImageKind
The type of contents the offloading image contains.
LLVM_ABI StringRef getOffloadKindName(OffloadKind Name)
Convert an offload kind to its string representation.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
Definition Magic.cpp:33
@ Offset
Definition DWP.cpp:577
ArrayRef< CharT > arrayRefFromStringRef(StringRef Input)
Construct an array ref of bytes from a string ref.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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:94
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
DWARFExpression::Operation Op
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:107
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition Alignment.h:139
LLVM_ABI std::unique_ptr< Module > getLazyIRModule(std::unique_ptr< MemoryBuffer > Buffer, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given MemoryBuffer holds a bitcode image, return a Module for it which does lazy deserializati...
Definition IRReader.cpp:32
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
Definition Magic.h:21
@ elf_relocatable
ELF Relocatable object file.
Definition Magic.h:28
@ archive
ar style archive file
Definition Magic.h:26
@ elf_shared_object
ELF dynamically linked shared lib.
Definition Magic.h:30
@ elf_executable
ELF Executable image.
Definition Magic.h:29
@ offload_binary
LLVM offload object file.
Definition Magic.h:58
@ bitcode
Bitcode file.
Definition Magic.h:24
@ coff_object
COFF object file.
Definition Magic.h:48
The offloading metadata that will be serialized to a memory buffer.