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
180decompressOffloadBinary(MemoryBufferRef Buf) {
181 const auto *Header =
182 reinterpret_cast<const OffloadBinary::Header *>(Buf.getBufferStart());
183 if (Header->EntriesOffset != sizeof(OffloadBinary::Header) ||
184 Header->EntriesOffset > Header->Size ||
185 Header->InflatedSize < Header->EntriesOffset)
187
188 // Get the compressed binary blob after the header.
189 StringRef Compressed = Buf.getBuffer()
190 .take_front(Header->Size)
191 .drop_front(Header->EntriesOffset);
192 uint64_t BodySize = Header->InflatedSize - Header->EntriesOffset;
193
196 Body, BodySize))
197 return std::move(Err);
198
199 // Restore the old header data for the newly uncompressed blob.
200 OffloadBinary::Header Restored = *Header;
201 Restored.Size = Restored.InflatedSize;
202 Restored.InflatedSize = 0;
203 if (Restored.EntriesOffset + Body.size() != Restored.Size)
205
207 Out.reserve(Restored.Size);
208 Out.append(StringRef(reinterpret_cast<const char *>(&Restored),
209 sizeof(OffloadBinary::Header)));
210 Out.append(toStringRef(Body));
212}
213
214} // namespace
215
217 if (Buf.getBufferSize() < sizeof(Header) ||
220 return false;
221
222 const auto *Hdr = reinterpret_cast<const Header *>(Buf.getBufferStart());
223 return Hdr->Version >= 3 && Hdr->InflatedSize != 0;
224}
225
228 if (Buf.getBufferSize() < sizeof(Header))
230
231 // Check for 0x10FF1OAD magic bytes.
234
235 // Make sure that the data has sufficient alignment.
238
239 const char *Start = Buf.getBufferStart();
240 const Header *TheHeader = reinterpret_cast<const Header *>(Start);
241 if (TheHeader->Version == 0 || TheHeader->Version > OffloadBinary::Version)
243
244 if (TheHeader->Size > Buf.getBufferSize() || TheHeader->Size < sizeof(Header))
246
247 if (isCompressed(Buf))
248 return TheHeader;
249
250 if (TheHeader->Size < sizeof(Entry))
252
253 uint64_t EntriesCount =
254 (TheHeader->Version == 1) ? 1 : TheHeader->EntriesCount;
255 uint64_t EntriesSize = sizeof(Entry) * EntriesCount;
256 if (TheHeader->EntriesOffset > TheHeader->Size - EntriesSize ||
257 // v1/v2 headers are 32 bytes; sizeof(Header) grew in v3.
258 EntriesSize > TheHeader->Size - offsetof(Header, InflatedSize))
260
261 return TheHeader;
262}
263
265OffloadBinary::create(MemoryBufferRef Buf, std::optional<uint64_t> Index) {
266 auto HeaderOrErr = extractHeader(Buf);
267 if (!HeaderOrErr)
268 return HeaderOrErr.takeError();
269 const Header *OnDisk = *HeaderOrErr;
270
271 // The binary data may be a compressed image.
272 std::shared_ptr<MemoryBuffer> Binary;
273 if (isCompressed(Buf)) {
274 auto DecompressedOrErr = decompressOffloadBinary(Buf);
275 if (!DecompressedOrErr)
276 return DecompressedOrErr.takeError();
277 Binary = std::shared_ptr<MemoryBuffer>(std::move(*DecompressedOrErr));
278 } else {
279 Binary = std::shared_ptr<MemoryBuffer>(MemoryBuffer::getMemBufferCopy(
280 Buf.getBuffer().take_front(OnDisk->Size), Buf.getBufferIdentifier()));
281 }
282
283 // Owned is now an uncompressed OffloadBinary, parse it as before.
284 MemoryBufferRef Owned = *Binary;
285 HeaderOrErr = extractHeader(Owned);
286 if (!HeaderOrErr)
287 return HeaderOrErr.takeError();
288 const Header *TheHeader = *HeaderOrErr;
289
290 const char *Start = Owned.getBufferStart();
291 const Entry *Entries =
292 reinterpret_cast<const Entry *>(&Start[TheHeader->EntriesOffset]);
293
294 auto validateEntry = [&](const Entry *TheEntry) -> Error {
295 const uint64_t BufSize = Owned.getBufferSize();
296 if (TheEntry->ImageOffset > BufSize ||
297 TheEntry->ImageSize > BufSize - TheEntry->ImageOffset)
299
300 const size_t StringEntrySize =
301 TheHeader->Version == 1 ? sizeof(StringEntryV1) : sizeof(StringEntry);
302 if (TheEntry->StringOffset > BufSize ||
303 TheEntry->NumStrings >
304 (BufSize - TheEntry->StringOffset) / StringEntrySize)
306 return Error::success();
307 };
308
310 if (TheHeader->Version > 1 && Index.has_value()) {
311 if (*Index >= TheHeader->EntriesCount)
313 const Entry *TheEntry = &Entries[*Index];
314 if (auto Err = validateEntry(TheEntry))
315 return std::move(Err);
316
317 Binaries.emplace_back(
318 new OffloadBinary(Binary, TheHeader, TheEntry, *Index));
319 return std::move(Binaries);
320 }
321
322 uint64_t EntriesCount = TheHeader->Version == 1 ? 1 : TheHeader->EntriesCount;
323 for (uint64_t I = 0; I < EntriesCount; ++I) {
324 const Entry *TheEntry = &Entries[I];
325 if (auto Err = validateEntry(TheEntry))
326 return std::move(Err);
327
328 Binaries.emplace_back(new OffloadBinary(Binary, TheHeader, TheEntry, I));
329 }
330
331 return std::move(Binaries);
332}
333
335 uint64_t EntriesCount = OffloadingData.size();
336 assert(EntriesCount > 0 && "At least one offloading image is required");
337
338 // Create a null-terminated string table with all the used strings.
339 // Also calculate total size of images.
341 uint64_t TotalStringEntries = 0;
342 uint64_t TotalImagesSize = 0;
343 for (const OffloadingImage &Img : OffloadingData) {
344 for (auto &KeyAndValue : Img.StringData) {
345 StrTab.add(KeyAndValue.first);
346 StrTab.add(KeyAndValue.second);
347 }
348 TotalStringEntries += Img.StringData.size();
349 TotalImagesSize += Img.Image->getBufferSize();
350 }
351 StrTab.finalize();
352
353 uint64_t StringEntrySize = sizeof(StringEntry) * TotalStringEntries;
354 uint64_t EntriesSize = sizeof(Entry) * EntriesCount;
355 uint64_t StrTabOffset = sizeof(Header) + EntriesSize + StringEntrySize;
356
357 // Make sure the image we're wrapping around is aligned as well.
358 uint64_t BinaryDataSize =
359 alignTo(StrTabOffset + StrTab.getSize(), getAlignment());
360
361 // Create the header and fill in the offsets. The entries will be directly
362 // placed after the header in memory. Align the size to the alignment of the
363 // header so this can be placed contiguously in a single section.
364 Header TheHeader{};
365 TheHeader.Size = alignTo(BinaryDataSize + TotalImagesSize, getAlignment());
366 TheHeader.EntriesOffset = sizeof(Header);
367 TheHeader.EntriesCount = EntriesCount;
368
370 Data.reserve(TheHeader.Size);
372 OS << StringRef(reinterpret_cast<char *>(&TheHeader), sizeof(Header));
373
374 // Create the entries using the string table offsets. The string table will be
375 // placed directly after the set of entries in memory, and all the images are
376 // after that.
377 uint64_t StringEntryOffset = sizeof(Header) + EntriesSize;
378 uint64_t ImageOffset = BinaryDataSize;
379 for (const OffloadingImage &Img : OffloadingData) {
380 Entry TheEntry;
381
382 TheEntry.TheImageKind = Img.TheImageKind;
383 TheEntry.TheOffloadKind = Img.TheOffloadKind;
384 TheEntry.Flags = Img.Flags;
385
386 TheEntry.StringOffset = StringEntryOffset;
387 StringEntryOffset += sizeof(StringEntry) * Img.StringData.size();
388 TheEntry.NumStrings = Img.StringData.size();
389
390 TheEntry.ImageOffset = ImageOffset;
391 ImageOffset += Img.Image->getBufferSize();
392 TheEntry.ImageSize = Img.Image->getBufferSize();
393
394 OS << StringRef(reinterpret_cast<char *>(&TheEntry), sizeof(Entry));
395 }
396
397 // Create the string map entries.
398 for (const OffloadingImage &Img : OffloadingData) {
399 for (auto &KeyAndValue : Img.StringData) {
400 StringEntry Map{StrTabOffset + StrTab.getOffset(KeyAndValue.first),
401 StrTabOffset + StrTab.getOffset(KeyAndValue.second),
402 KeyAndValue.second.size()};
403 OS << StringRef(reinterpret_cast<char *>(&Map), sizeof(StringEntry));
404 }
405 }
406
407 StrTab.write(OS);
408 // Add padding to required image alignment.
409 OS.write_zeros(BinaryDataSize - OS.tell());
410
411 for (const OffloadingImage &Img : OffloadingData)
412 OS << Img.Image->getBuffer();
413
414 // Add final padding to required alignment.
415 assert(TheHeader.Size >= OS.tell() && "Too much data written?");
416 OS.write_zeros(TheHeader.Size - OS.tell());
417 assert(TheHeader.Size == OS.tell() && "Size mismatch");
418
419 return Data;
420}
421
424 compression::Params Compress) {
425 if (const char *Reason = compression::getReasonIfUnsupported(Compress.format))
426 return createStringError(Reason);
427
428 // Write the complete offloading binary as normal.
429 SmallString<0> Uncompressed = write(OffloadingData);
431 *reinterpret_cast<const OffloadBinary::Header *>(Uncompressed.data());
432
433 // Compress the entries after the header with the requested configuration.
434 StringRef Body = StringRef(Uncompressed).drop_front(Header.EntriesOffset);
435 SmallVector<uint8_t, 0> CompressedBuffer;
437 CompressedBuffer);
438
439 // Reset the header sizes and create the newly compressed binary.
440 Header.InflatedSize = Uncompressed.size();
441 Header.Size = Header.EntriesOffset + CompressedBuffer.size();
442
444 Data.reserve(alignTo(Header.Size, getAlignment()));
446 OS << StringRef(reinterpret_cast<const char *>(&Header),
448 OS << toStringRef(CompressedBuffer);
449 assert(Header.Size == OS.tell() && "Size mismatch");
451 return Data;
452}
453
457 switch (Type) {
459 return extractFromBitcode(Buffer, Binaries);
466 if (!ObjFile)
467 return ObjFile.takeError();
468 return extractFromObject(*ObjFile->get(), Binaries);
469 }
470 case file_magic::archive: {
473 if (!LibFile)
474 return LibFile.takeError();
475 return extractFromArchive(*LibFile->get(), Binaries);
476 }
478 return extractOffloadFiles(Buffer, Binaries);
479 default:
480 return Error::success();
481 }
482}
483
486 .Case("openmp", OFK_OpenMP)
487 .Case("cuda", OFK_Cuda)
488 .Case("hip", OFK_HIP)
489 .Case("sycl", OFK_SYCL)
491}
492
494 switch (Kind) {
495 case OFK_OpenMP:
496 return "openmp";
497 case OFK_Cuda:
498 return "cuda";
499 case OFK_HIP:
500 return "hip";
501 case OFK_SYCL:
502 return "sycl";
503 default:
504 return "none";
505 }
506}
507
510 .Case("o", IMG_Object)
511 .Case("bc", IMG_Bitcode)
512 .Case("cubin", IMG_Cubin)
513 .Case("fatbin", IMG_Fatbinary)
514 .Case("s", IMG_PTX)
515 .Case("spv", IMG_SPIRV)
517}
518
520 switch (Kind) {
521 case IMG_Object:
522 return "o";
523 case IMG_Bitcode:
524 return "bc";
525 case IMG_Cubin:
526 return "cubin";
527 case IMG_Fatbinary:
528 return "fatbin";
529 case IMG_PTX:
530 return "s";
531 case IMG_SPIRV:
532 return "spv";
533 default:
534 return "";
535 }
536}
537
539 const OffloadFile::TargetID &RHS) {
540 llvm::Triple LHSTT(LHS.first);
541 llvm::Triple RHSTT(RHS.first);
542
543 // Check for logical AMDGPU target-id equivalence.
544 if (LHSTT.isAMDGPU()) {
545 AMDGPU::TargetID LHSID(LHSTT, LHS.second);
546 AMDGPU::TargetID RHSID(RHSTT, RHS.second);
547 return LHSID.isEquivalent(RHSID);
548 }
549
550 // For other targets the triples must be compatible and the arch must match.
551 return LHSTT.isCompatibleWith(RHSTT) && LHS.second == RHS.second;
552}
553
555 const OffloadFile::TargetID &Requested) {
556 llvm::Triple ProvidedTT(Provided.first);
557 llvm::Triple RequestedTT(Requested.first);
558
559 // The AMDGPU target requires target-id aware checks (base processor plus
560 // xnack/sramecc features).
561 if (ProvidedTT.isAMDGPU()) {
562 AMDGPU::TargetID ProvidedID(ProvidedTT, Provided.second);
563 AMDGPU::TargetID RequestedID(RequestedTT, Requested.second);
564 return ProvidedID.providesFor(RequestedID);
565 }
566
567 // For other targets the triples must be compatible.
568 if (!ProvidedTT.isCompatibleWith(RequestedTT))
569 return false;
570
571 // If the architecture is "generic" we assume it is always compatible.
572 if (Provided.second == "generic" || Requested.second == "generic")
573 return true;
574
575 return Provided.second == Requested.second;
576}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t 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:76
Metadata node.
Definition Metadata.h:1081
A single uniqued string.
Definition Metadata.h:733
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:613
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:307
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:998
LLVM_ABI bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Definition Triple.cpp:2276
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:811
MemoryBufferRef Data
Definition Binary.h:38
Binary(unsigned int Type, MemoryBufferRef Source)
Definition Binary.cpp:20
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 bool isCompressed(MemoryBufferRef Buf)
True if Buf is a compressed offload package, false otherwise.
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:1004
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:149
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:144
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.