Skip to content

Commit 1f9a45e

Browse files
author
Salinas, David
authored
SWDEV-522811 - fix compress/decompress in LLVM Offloading API (llvm#2988)
2 parents 32c5784 + 38eeb8a commit 1f9a45e

File tree

3 files changed

+391
-200
lines changed

3 files changed

+391
-200
lines changed

llvm/include/llvm/Object/OffloadBundle.h

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,56 @@ 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 = 2;
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, bool Verbose = false);
67+
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
68+
decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
5869
};
5970

6071
/// Bundle entry in binary clang-offload-bundler format.
6172
struct OffloadBundleEntry {
6273
uint64_t Offset = 0u;
6374
uint64_t Size = 0u;
6475
uint64_t IDLength = 0u;
65-
StringRef ID;
66-
OffloadBundleEntry(uint64_t O, uint64_t S, uint64_t I, StringRef T)
67-
: Offset(O), Size(S), IDLength(I), ID(T) {}
76+
std::string ID;
77+
OffloadBundleEntry(uint64_t O, uint64_t S, uint64_t I, std::string T)
78+
: Offset(O), Size(S), IDLength(I) {
79+
ID.reserve(T.size());
80+
ID = T;
81+
}
6882
void dumpInfo(raw_ostream &OS) {
6983
OS << "Offset = " << Offset << ", Size = " << Size
70-
<< ", ID Length = " << IDLength << ", ID = " << ID;
84+
<< ", ID Length = " << IDLength << ", ID = " << ID << "\n";
7185
}
7286
void dumpURI(raw_ostream &OS, StringRef FilePath) {
7387
OS << ID.data() << "\tfile://" << FilePath << "#offset=" << Offset
@@ -82,15 +96,20 @@ class OffloadBundleFatBin {
8296
StringRef FileName;
8397
uint64_t NumberOfEntries;
8498
SmallVector<OffloadBundleEntry> Entries;
99+
bool Decompressed;
85100

86101
public:
102+
std::unique_ptr<MemoryBuffer> DecompressedBuffer;
103+
87104
SmallVector<OffloadBundleEntry> getEntries() { return Entries; }
88105
uint64_t getSize() const { return Size; }
89106
StringRef getFileName() const { return FileName; }
90107
uint64_t getNumEntries() const { return NumberOfEntries; }
108+
bool isDecompressed() const { return Decompressed; }
91109

92110
LLVM_ABI static Expected<std::unique_ptr<OffloadBundleFatBin>>
93-
create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName);
111+
create(MemoryBufferRef, uint64_t SectionOffset, StringRef FileName,
112+
bool Decompress = false);
94113
LLVM_ABI Error extractBundle(const ObjectFile &Source);
95114

96115
LLVM_ABI Error dumpEntryToCodeObject();
@@ -106,9 +125,15 @@ class OffloadBundleFatBin {
106125
Entry.dumpURI(outs(), FileName);
107126
}
108127

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

114139
enum UriTypeT { FILE_URI, MEMORY_URI };
@@ -191,6 +216,10 @@ LLVM_ABI Error extractOffloadBundleFatBinary(
191216
LLVM_ABI Error extractCodeObject(const ObjectFile &Source, int64_t Offset,
192217
int64_t Size, StringRef OutputFileName);
193218

219+
/// Extract code object memory from the given \p Source object file at \p Offset
220+
/// and of \p Size, and copy into \p OutputFileName.
221+
LLVM_ABI Error extractCodeObject(MemoryBufferRef Buffer, int64_t Offset,
222+
int64_t Size, StringRef OutputFileName);
194223
/// Extracts an Offload Bundle Entry given by URI
195224
LLVM_ABI Error extractOffloadBundleByURI(StringRef URIstr);
196225

0 commit comments

Comments
 (0)