Skip to content

Commit efda523

Browse files
david-salinasdsalinas_amdeng
andauthored
Fix compress/decompress in LLVM Offloading API (#150064)
Co-authored-by: dsalinas_amdeng <[email protected]>
1 parent 087c832 commit efda523

File tree

3 files changed

+425
-258
lines changed

3 files changed

+425
-258
lines changed

llvm/include/llvm/Object/OffloadBundle.h

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,54 @@ namespace llvm {
3232

3333
namespace object {
3434

35+
// CompressedOffloadBundle represents the format for the compressed offload
36+
// bundles.
37+
//
38+
// The format is as follows:
39+
// - Magic Number (4 bytes) - A constant "CCOB".
40+
// - Version (2 bytes)
41+
// - Compression Method (2 bytes) - Uses the values from
42+
// llvm::compression::Format.
43+
// - Total file size (4 bytes in V2, 8 bytes in V3).
44+
// - Uncompressed Size (4 bytes in V1/V2, 8 bytes in V3).
45+
// - Truncated MD5 Hash (8 bytes).
46+
// - Compressed Data (variable length).
3547
class CompressedOffloadBundle {
3648
private:
37-
static inline const size_t MagicSize = 4;
38-
static inline const size_t VersionFieldSize = sizeof(uint16_t);
39-
static inline const size_t MethodFieldSize = sizeof(uint16_t);
40-
static inline const size_t FileSizeFieldSize = sizeof(uint32_t);
41-
static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t);
42-
static inline const size_t HashFieldSize = sizeof(uint64_t);
43-
static inline const size_t V1HeaderSize =
44-
MagicSize + VersionFieldSize + MethodFieldSize +
45-
UncompressedSizeFieldSize + HashFieldSize;
46-
static inline const size_t V2HeaderSize =
47-
MagicSize + VersionFieldSize + FileSizeFieldSize + MethodFieldSize +
48-
UncompressedSizeFieldSize + HashFieldSize;
4949
static inline const llvm::StringRef MagicNumber = "CCOB";
50-
static inline const uint16_t Version = 2;
5150

5251
public:
53-
LLVM_ABI static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
52+
struct CompressedBundleHeader {
53+
unsigned Version;
54+
llvm::compression::Format CompressionFormat;
55+
std::optional<size_t> FileSize;
56+
size_t UncompressedFileSize;
57+
uint64_t Hash;
58+
59+
static llvm::Expected<CompressedBundleHeader> tryParse(llvm::StringRef);
60+
};
61+
62+
static inline const uint16_t DefaultVersion = 3;
63+
64+
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
5465
compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input,
55-
bool Verbose = false);
56-
LLVM_ABI static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
57-
decompress(llvm::MemoryBufferRef &Input, bool Verbose = false);
66+
uint16_t Version, raw_ostream *VerboseStream = nullptr);
67+
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
68+
decompress(const llvm::MemoryBuffer &Input,
69+
raw_ostream *VerboseStream = nullptr);
5870
};
5971

6072
/// Bundle entry in binary clang-offload-bundler format.
6173
struct OffloadBundleEntry {
6274
uint64_t Offset = 0u;
6375
uint64_t Size = 0u;
6476
uint64_t IDLength = 0u;
65-
StringRef ID;
77+
std::string ID;
6678
OffloadBundleEntry(uint64_t O, uint64_t S, uint64_t I, StringRef T)
67-
: Offset(O), Size(S), IDLength(I), ID(T) {}
79+
: Offset(O), Size(S), IDLength(I), ID(T.str()) {}
6880
void dumpInfo(raw_ostream &OS) {
6981
OS << "Offset = " << Offset << ", Size = " << Size
70-
<< ", ID Length = " << IDLength << ", ID = " << ID;
82+
<< ", ID Length = " << IDLength << ", ID = " << ID << "\n";
7183
}
7284
void dumpURI(raw_ostream &OS, StringRef FilePath) {
7385
OS << ID.data() << "\tfile://" << FilePath << "#offset=" << Offset
@@ -81,16 +93,21 @@ class OffloadBundleFatBin {
8193
uint64_t Size = 0u;
8294
StringRef FileName;
8395
uint64_t NumberOfEntries;
96+
bool Decompressed;
8497
SmallVector<OffloadBundleEntry> Entries;
8598

8699
public:
100+
std::unique_ptr<MemoryBuffer> DecompressedBuffer;
101+
87102
SmallVector<OffloadBundleEntry> getEntries() { return Entries; }
88103
uint64_t getSize() const { return Size; }
89104
StringRef getFileName() const { return FileName; }
90105
uint64_t getNumEntries() const { return NumberOfEntries; }
106+
bool isDecompressed() const { return Decompressed; }
91107

92108
LLVM_ABI static Expected<std::unique_ptr<OffloadBundleFatBin>>
93-
create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName);
109+
create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName,
110+
bool Decompress = false);
94111
LLVM_ABI Error extractBundle(const ObjectFile &Source);
95112

96113
LLVM_ABI Error dumpEntryToCodeObject();
@@ -106,9 +123,14 @@ class OffloadBundleFatBin {
106123
Entry.dumpURI(outs(), FileName);
107124
}
108125

109-
OffloadBundleFatBin(MemoryBufferRef Source, StringRef File)
110-
: FileName(File), NumberOfEntries(0),
111-
Entries(SmallVector<OffloadBundleEntry>()) {}
126+
OffloadBundleFatBin(MemoryBufferRef Source, StringRef File,
127+
bool Decompress = false)
128+
: FileName(File), NumberOfEntries(0), Decompressed(Decompress),
129+
Entries(SmallVector<OffloadBundleEntry>()) {
130+
if (Decompress)
131+
DecompressedBuffer =
132+
MemoryBuffer::getMemBufferCopy(Source.getBuffer(), File);
133+
}
112134
};
113135

114136
enum UriTypeT { FILE_URI, MEMORY_URI };
@@ -191,6 +213,10 @@ LLVM_ABI Error extractOffloadBundleFatBinary(
191213
LLVM_ABI Error extractCodeObject(const ObjectFile &Source, int64_t Offset,
192214
int64_t Size, StringRef OutputFileName);
193215

216+
/// Extract code object memory from the given \p Source object file at \p Offset
217+
/// and of \p Size, and copy into \p OutputFileName.
218+
LLVM_ABI Error extractCodeObject(MemoryBufferRef Buffer, int64_t Offset,
219+
int64_t Size, StringRef OutputFileName);
194220
/// Extracts an Offload Bundle Entry given by URI
195221
LLVM_ABI Error extractOffloadBundleByURI(StringRef URIstr);
196222

0 commit comments

Comments
 (0)