LLVM 22.0.0git
OffloadBinary.h
Go to the documentation of this file.
1//===--- Offloading.h - Utilities for handling offloading code -*- 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// This file contains the binary format used for budingling device metadata with
10// an associated device image. The data can then be stored inside a host object
11// file to create a fat binary and read by the linker. This is intended to be a
12// thin wrapper around the image itself. If this format becomes sufficiently
13// complex it should be moved to a standard binary format like msgpack or ELF.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_OBJECT_OFFLOADBINARY_H
18#define LLVM_OBJECT_OFFLOADBINARY_H
19
20#include "llvm/ADT/MapVector.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/Object/Binary.h"
25#include "llvm/Support/Error.h"
27#include <memory>
28
29namespace llvm {
30
31namespace object {
32
33/// The producer of the associated offloading image.
36 OFK_OpenMP = (1 << 0),
37 OFK_Cuda = (1 << 1),
38 OFK_HIP = (1 << 2),
39 OFK_SYCL = (1 << 3),
40 OFK_LAST = (1 << 4),
41};
42
43/// The type of contents the offloading image contains.
52};
53
54/// A simple binary serialization of an offloading file. We use this format to
55/// embed the offloading image into the host executable so it can be extracted
56/// and used by the linker.
57///
58/// Many of these could be stored in the same section by the time the linker
59/// sees it so we mark this information with a header. The version is used to
60/// detect ABI stability and the size is used to find other offloading entries
61/// that may exist in the same section. All offsets are given as absolute byte
62/// offsets from the beginning of the file.
63class OffloadBinary : public Binary {
64public:
67
68 /// The current version of the binary used for backwards compatibility.
69 static const uint32_t Version = 1;
70
71 /// The offloading metadata that will be serialized to a memory buffer.
77 std::unique_ptr<MemoryBuffer> Image;
78 };
79
80 /// Attempt to parse the offloading binary stored in \p Data.
83
84 /// Serialize the contents of \p File to a binary buffer to be read later.
86
87 static uint64_t getAlignment() { return 8; }
88
89 ImageKind getImageKind() const { return TheEntry->TheImageKind; }
90 OffloadKind getOffloadKind() const { return TheEntry->TheOffloadKind; }
91 uint32_t getVersion() const { return TheHeader->Version; }
92 uint32_t getFlags() const { return TheEntry->Flags; }
93 uint64_t getSize() const { return TheHeader->Size; }
94
95 StringRef getTriple() const { return getString("triple"); }
96 StringRef getArch() const { return getString("arch"); }
98 return StringRef(&Buffer[TheEntry->ImageOffset], TheEntry->ImageSize);
99 }
100
101 // Iterator over all the key and value pairs in the binary.
103 return string_iterator_range(StringData.begin(), StringData.end());
104 }
105
106 StringRef getString(StringRef Key) const { return StringData.lookup(Key); }
107
108 static bool classof(const Binary *V) { return V->isOffloadFile(); }
109
110 struct Header {
111 uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
112 uint32_t Version = OffloadBinary::Version; // Version identifier.
113 uint64_t Size; // Size in bytes of this entire binary.
114 uint64_t EntryOffset; // Offset of the metadata entry in bytes.
115 uint64_t EntrySize; // Size of the metadata entry in bytes.
116 };
117
118 struct Entry {
119 ImageKind TheImageKind; // The kind of the image stored.
120 OffloadKind TheOffloadKind; // The producer of this image.
121 uint32_t Flags; // Additional flags associated with the image.
122 uint64_t StringOffset; // Offset in bytes to the string map.
123 uint64_t NumStrings; // Number of entries in the string map.
124 uint64_t ImageOffset; // Offset in bytes of the actual binary image.
125 uint64_t ImageSize; // Size in bytes of the binary image.
126 };
127
128 struct StringEntry {
131 };
132
133private:
134 OffloadBinary(MemoryBufferRef Source, const Header *TheHeader,
135 const Entry *TheEntry)
136 : Binary(Binary::ID_Offload, Source), Buffer(Source.getBufferStart()),
137 TheHeader(TheHeader), TheEntry(TheEntry) {
138 const StringEntry *StringMapBegin =
139 reinterpret_cast<const StringEntry *>(&Buffer[TheEntry->StringOffset]);
140 for (uint64_t I = 0, E = TheEntry->NumStrings; I != E; ++I) {
141 StringRef Key = &Buffer[StringMapBegin[I].KeyOffset];
142 StringData[Key] = &Buffer[StringMapBegin[I].ValueOffset];
143 }
144 }
145
146 OffloadBinary(const OffloadBinary &Other) = delete;
147
148 /// Map from keys to offsets in the binary.
150 /// Raw pointer to the MemoryBufferRef for convenience.
151 const char *Buffer;
152 /// Location of the header within the binary.
153 const Header *TheHeader;
154 /// Location of the metadata entries within the binary.
155 const Entry *TheEntry;
156};
157
158/// A class to contain the binary information for a single OffloadBinary that
159/// owns its memory.
160class OffloadFile : public OwningBinary<OffloadBinary> {
161public:
162 using TargetID = std::pair<StringRef, StringRef>;
163
164 OffloadFile(std::unique_ptr<OffloadBinary> Binary,
165 std::unique_ptr<MemoryBuffer> Buffer)
166 : OwningBinary<OffloadBinary>(std::move(Binary), std::move(Buffer)) {}
167
168 /// Make a deep copy of this offloading file.
170 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBufferCopy(
171 getBinary()->getMemoryBufferRef().getBuffer(),
172 getBinary()->getMemoryBufferRef().getBufferIdentifier());
173
174 // This parsing should never fail because it has already been parsed.
175 auto NewBinaryOrErr = OffloadBinary::create(*Buffer);
176 assert(NewBinaryOrErr && "Failed to parse a copy of the binary?");
177 if (!NewBinaryOrErr)
178 llvm::consumeError(NewBinaryOrErr.takeError());
179 return OffloadFile(std::move(*NewBinaryOrErr), std::move(Buffer));
180 }
181
182 /// We use the Triple and Architecture pair to group linker inputs together.
183 /// This conversion function lets us use these inputs in a hash-map.
184 operator TargetID() const {
185 return std::make_pair(getBinary()->getTriple(), getBinary()->getArch());
186 }
187};
188
189/// Extracts embedded device offloading code from a memory \p Buffer to a list
190/// of \p Binaries.
193
194/// Convert a string \p Name to an image kind.
196
197/// Convert an image kind to its string representation.
199
200/// Convert a string \p Name to an offload kind.
202
203/// Convert an offload kind to its string representation.
205
206/// If the target is AMD we check the target IDs for mutual compatibility. A
207/// target id is a string conforming to the folowing BNF syntax:
208///
209/// target-id ::= '<arch> ( : <feature> ( '+' | '-' ) )*'
210///
211/// The features 'xnack' and 'sramecc' are currently supported. These can be in
212/// the state of on, off, and any when unspecified. A target marked as any can
213/// bind with either on or off. This is used to link mutually compatible
214/// architectures together. Returns false in the case of an exact match.
217
218} // namespace object
219
220} // namespace llvm
221#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition: Compiler.h:213
std::string Name
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
This file defines the SmallString class.
Value * RHS
Value * LHS
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
Tagged union holding either a T or a Error.
Definition: Error.h:485
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
typename VectorType::const_iterator const_iterator
Definition: MapVector.h:43
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.
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...
Definition: SmallVector.h:574
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
A range adaptor for a pair of iterators.
A simple binary serialization of an offloading file.
Definition: OffloadBinary.h:63
static uint64_t getAlignment()
Definition: OffloadBinary.h:87
OffloadKind getOffloadKind() const
Definition: OffloadBinary.h:90
iterator_range< string_iterator > string_iterator_range
Definition: OffloadBinary.h:66
StringRef getString(StringRef Key) const
uint32_t getVersion() const
Definition: OffloadBinary.h:91
StringRef getImage() const
Definition: OffloadBinary.h:97
static LLVM_ABI SmallString< 0 > write(const OffloadingImage &)
Serialize the contents of File to a binary buffer to be read later.
uint32_t getFlags() const
Definition: OffloadBinary.h:92
StringRef getTriple() const
Definition: OffloadBinary.h:95
ImageKind getImageKind() const
Definition: OffloadBinary.h:89
static LLVM_ABI Expected< std::unique_ptr< OffloadBinary > > create(MemoryBufferRef)
Attempt to parse the offloading binary stored in Data.
static bool classof(const Binary *V)
string_iterator_range strings() const
StringRef getArch() const
Definition: OffloadBinary.h:96
uint64_t getSize() const
Definition: OffloadBinary.h:93
static const uint32_t Version
The current version of the binary used for backwards compatibility.
Definition: OffloadBinary.h:69
MapVector< StringRef, StringRef >::const_iterator string_iterator
Definition: OffloadBinary.h:65
A class to contain the binary information for a single OffloadBinary that owns its memory.
std::pair< StringRef, StringRef > TargetID
OffloadFile copy() const
Make a deep copy of this offloading file.
OffloadFile(std::unique_ptr< OffloadBinary > Binary, std::unique_ptr< MemoryBuffer > Buffer)
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.
LLVM_ABI bool areTargetsCompatible(const OffloadFile::TargetID &LHS, const OffloadFile::TargetID &RHS)
If the target is AMD we check the target IDs for mutual compatibility.
OffloadKind
The producer of the associated offloading image.
Definition: OffloadBinary.h:34
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.
Definition: OffloadBinary.h:44
LLVM_ABI StringRef getOffloadKindName(OffloadKind Name)
Convert an offload kind to its string representation.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Other
Any other memory.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1083
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
The offloading metadata that will be serialized to a memory buffer.
Definition: OffloadBinary.h:72
std::unique_ptr< MemoryBuffer > Image
Definition: OffloadBinary.h:77
MapVector< StringRef, StringRef > StringData
Definition: OffloadBinary.h:76