LLVM 23.0.0git
DXContainerInfo.cpp
Go to the documentation of this file.
1//===- llvm/MC/DXContainerInfo.cpp - DXContainer Info -----*- 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
12#include "llvm/Config/config.h"
17#include "llvm/Support/VCSRevision.h"
18#include <type_traits>
19
20using namespace llvm;
21using namespace llvm::mcdxbc;
22
26
27template <typename StructT>
28static void writeStruct(raw_ostream &OS, StructT S) {
29 static_assert(std::is_class<StructT>() &&
30 "This method must be used for writing structure types");
32 S.swapBytes();
33 OS.write(reinterpret_cast<const char *>(&S), sizeof(StructT));
34}
35
36static void writeString(raw_ostream &OS, StringRef S) {
37 OS.write(S.data(), S.size());
38 // Write null terminator.
39 OS.write_zeros(1);
40}
41
42static void writePadding(raw_ostream &OS, uint64_t Prev) {
43 uint64_t UnpaddedSize = OS.tell() - Prev;
44 uint64_t Padding = align(UnpaddedSize) - UnpaddedSize;
45 if (Padding)
46 OS.write_zeros(Padding);
47}
48
49void DebugName::setFilename(StringRef DebugFilename) {
50 Parameters.NameLength = DebugFilename.size();
51 Filename = DebugFilename;
52}
53
56 writeString(OS, Filename.substr(0, Parameters.NameLength));
57}
58
60 Parameters.Major = LLVM_VERSION_MAJOR;
61 Parameters.Minor = LLVM_VERSION_MINOR;
62 Parameters.Flags = dxbc::CompilerVersionFlags::Default;
63#ifndef NDEBUG
64 Parameters.Flags |= dxbc::CompilerVersionFlags::Debug;
65#endif
66 Parameters.CommitCount = 0;
67 Parameters.ContentSizeInBytes = 0;
68#ifdef LLVM_REVISION
69 CommitSha = LLVM_REVISION;
70#else
71 CommitSha = "";
72#endif
73 CustomVersionString = PACKAGE_VERSION;
74 updateContentSize();
75}
76
78 this->CommitSha = CommitSha;
79 updateContentSize();
80}
81
83 this->CustomVersionString = VersionString;
84 updateContentSize();
85}
86
87void CompilerVersion::updateContentSize() {
90}
91
94 SmallString<64> Content;
95 raw_svector_ostream ContentStream(Content);
96 writeString(ContentStream, CommitSha);
97 writeString(ContentStream, CustomVersionString);
98 Content.resize(Parameters.ContentSizeInBytes);
99 OS.write(Content.data(), Parameters.ContentSizeInBytes);
100}
101
104 GenericHeader.AlignedSizeInBytes = align(sizeof(GenericHeader) + ContentSize);
105 GenericHeader.Flags = 0;
106 GenericHeader.Type = SecType;
107}
108
110 Parameters.Flags = 0;
111 Parameters.ContentSizeInBytes = FileContent.size() + 1;
112 Parameters.AlignedSizeInBytes =
113 align(Parameters.ContentSizeInBytes +
115}
116
119 size_t ContentEntriesSize = 0;
120 for (const SourceContents::Entry &ContentEntry : Entries)
121 ContentEntriesSize += ContentEntry.Parameters.AlignedSizeInBytes;
122
123 Parameters.Flags = 0;
124 Parameters.Type = CompType;
125 Parameters.Count = Entries.size();
126
127 Parameters.UncompressedEntriesSizeInBytes = align(ContentEntriesSize);
128 computeFinalSize(Parameters.UncompressedEntriesSizeInBytes);
129}
130
132 Parameters.EntriesSizeInBytes = CompressedSize;
133 Parameters.AlignedSizeInBytes =
134 align(Parameters.EntriesSizeInBytes +
136 computeGenericHeader(Parameters.AlignedSizeInBytes,
137 dxbc::SourceInfo::SectionType::SourceContents);
138}
139
141 Parameters.Flags = 0;
142 Parameters.NameSizeInBytes = FileName.size() + 1;
143 Parameters.ContentSizeInBytes = ContentSize;
144 Parameters.AlignedSizeInBytes = align(Parameters.NameSizeInBytes +
146}
147
149 const dxbc::SourceInfo::Names::HeaderOnDisk &H) {
150 const auto *HPtr = reinterpret_cast<const uint8_t *>(&H);
154}
155
157 size_t NameEntriesSize = 0;
158 for (const SourceNames::Entry &NameEntry : Entries)
159 NameEntriesSize += NameEntry.Parameters.AlignedSizeInBytes;
160
161 Parameters.Flags = 0;
162 Parameters.Count = Entries.size();
163 Parameters.EntriesSizeInBytes = align(NameEntriesSize);
164
165 computeGenericHeader(Parameters.EntriesSizeInBytes +
166 sizeof(dxbc::SourceInfo::Names::HeaderOnDisk),
167 dxbc::SourceInfo::SectionType::SourceNames);
168}
169
171 size_t ArgEntriesSize = 0;
172 for (auto [ArgName, ArgVal] : Args) {
173 // Null-terminated argument name and empty null-terminated argument value.
174 ArgEntriesSize += ArgName.size() + 1 + ArgVal.size() + 1;
175 }
176
177 Parameters.Flags = 0;
178 Parameters.SizeInBytes = ArgEntriesSize;
179 Parameters.Count = Args.size();
180
181 computeGenericHeader(Parameters.SizeInBytes +
183 dxbc::SourceInfo::SectionType::Args);
184}
185
187 Parameters.Flags = 0;
188 Parameters.SectionCount = 3;
189 Parameters.AlignedSizeInBytes =
191 Names.GenericHeader.AlignedSizeInBytes +
192 Contents.GenericHeader.AlignedSizeInBytes +
193 Args.GenericHeader.AlignedSizeInBytes);
194}
195
196template <typename VecT> static void clearAndReserve(VecT &Vec, size_t N) {
197 Vec.clear();
198 Vec.reserve(N);
199}
200
202 IsFilled = true;
203 clearAndReserve(BaseData.Names.Entries, FileNamesAndContents.size());
204 clearAndReserve(BaseData.Contents.Entries, FileNamesAndContents.size());
205 for (const auto &NameContent : FileNamesAndContents) {
207 ContentEntry.FileContent = NameContent.second.str();
208 ContentEntry.compute();
209 BaseData.Contents.Entries.emplace_back(std::move(ContentEntry));
210
212 NameEntry.FileName = NameContent.first;
213 NameEntry.compute(ContentEntry.Parameters.ContentSizeInBytes);
214 BaseData.Names.Entries.emplace_back(std::move(NameEntry));
215 }
216
217 clearAndReserve(BaseData.Args.Args, Args.size());
218 for (auto [ArgName, ArgValue] : Args)
219 BaseData.Args.Args.emplace_back(ArgName, ArgValue);
220}
221
222void SourceInfoBuilder::recomputeAfterCompression(uint32_t CompressedSize) {
223 BaseData.Contents.computeFinalSize(CompressedSize);
224 BaseData.compute();
225}
226
228 assert(IsFilled && "SourceInfo::computeEntries() must be called before "
229 "SourceInfo::computeUncompressed()");
230 assert(CompressionType && "Compression type must be set.");
231
232 IsFinalized = true;
233
234 BaseData.Contents.computeUncompressed(*CompressionType);
235 BaseData.Names.compute();
236 BaseData.Args.compute();
237 BaseData.compute();
238
239 // Compress Contents right here, to calculate compressed size.
240 CompressedContents.clear();
242 {
244 for (auto &E : BaseData.Contents.Entries) {
245 uint64_t EntryOffset = OS.tell();
246 writeStruct(OS, E.Parameters);
247 writeString(OS, E.FileContent);
248 writePadding(OS, EntryOffset);
249 }
250 writePadding(OS, 0);
251 }
252 uint32_t CompressedSize = 0;
253 switch (BaseData.Contents.Parameters.Type) {
254 case dxbc::SourceInfo::Contents::CompressionType::Zlib: {
256 reportFatalUsageError(Twine("DXContainer SRCI Contents should be "
257 "compressed with Zlib, but ") +
260
261 SmallVector<uint8_t, 128> CompressedData;
263 ArrayRef(reinterpret_cast<uint8_t *>(Data.data()), Data.size()),
266 OS.write(reinterpret_cast<char *>(CompressedData.data()),
267 CompressedData.size());
268 CompressedSize = CompressedContents.size();
269 break;
270 }
271 case dxbc::SourceInfo::Contents::CompressionType::None: {
272 CompressedContents = std::move(Data);
273 CompressedSize = align(CompressedContents.size());
274 break;
275 }
276 }
277 recomputeAfterCompression(CompressedSize);
278}
279
282 "SourceInfo::finalize() must be called before SourceInfo::write()");
283
284 writeStruct(OS, BaseData.Parameters);
285
286 // Write Names section.
287 auto &Names = BaseData.Names;
288 uint64_t NamesOffset = OS.tell();
294 for (auto &E : Names.Entries) {
295 uint64_t EntryOffset = OS.tell();
296 writeStruct(OS, E.Parameters);
297 writeString(OS, E.FileName);
298 writePadding(OS, EntryOffset);
299 }
300 writePadding(OS, NamesOffset);
301
302 // Write Contents section.
303 auto &Contents = BaseData.Contents;
304 uint64_t ContentsOffset = OS.tell();
307
308 if (BaseData.Contents.Parameters.EntriesSizeInBytes !=
309 CompressedContents.size())
311 "DXContainer SRCI Contents compressed size in header ({0} bytes) "
312 "doesn't match the actual compressed size ({1} bytes)",
313 BaseData.Contents.Parameters.EntriesSizeInBytes,
314 CompressedContents.size()));
315
317 writePadding(OS, ContentsOffset);
318
319 // Write Args section.
320 auto &Args = BaseData.Args;
321 uint64_t ArgsOffset = OS.tell();
322 writeStruct(OS, Args.GenericHeader);
323 writeStruct(OS, Args.Parameters);
324 for (auto &E : Args.Args) {
325 writeString(OS, E.first);
326 writeString(OS, E.second);
327 }
328 writePadding(OS, ArgsOffset);
329}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint64_t align(uint64_t Size)
static void clearAndReserve(VecT &Vec, size_t N)
static void writeString(raw_ostream &OS, StringRef S)
static void writeStruct(raw_ostream &OS, StructT S)
static void writePadding(raw_ostream &OS, uint64_t Prev)
#define H(x, y, z)
Definition MD5.cpp:56
This file defines the SmallString class.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
void resize(size_type N)
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
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI void compress(ArrayRef< uint8_t > Input, SmallVectorImpl< uint8_t > &CompressedBuffer, int Level=DefaultCompression)
LLVM_ABI bool isAvailable()
constexpr int BestSizeCompression
Definition Compression.h:40
LLVM_ABI const char * getReasonIfUnsupported(Format F)
static constexpr uint64_t DXCONTAINER_STRUCT_ALIGNMENT
Definition DXContainer.h:47
uint16_t read16le(const void *P)
Definition Endian.h:429
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:96
uint32_t read32le(const void *P)
Definition Endian.h:432
constexpr bool IsBigEndianHost
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
#define N
uint32_t ContentSizeInBytes
Byte size of CommitSha and CustomVersionString, padding not included.
uint32_t ContentSizeInBytes
Size of the file contents following this header, including the null terminator, excluding entry paddi...
void setCommitSha(StringRef CommitSha)
void setVersionString(StringRef VersionString)
void write(raw_ostream &OS) const
dxbc::CompilerVersionHeader Parameters
dxbc::DebugNameHeader Parameters
void setFilename(StringRef DebugFilename)
void write(raw_ostream &OS) const
SmallString< 128 > CompressedContents
void write(raw_ostream &OS) const
void compute()
Compute Parameters based on Args.
dxbc::SourceInfo::Args::Header Parameters
void computeGenericHeader(uint32_t ContentSize, dxbc::SourceInfo::SectionType Type)
dxbc::SourceInfo::SectionHeader GenericHeader
void compute()
Compute Parameters based on FileContent.
dxbc::SourceInfo::Contents::Entry Parameters
void computeUncompressed(dxbc::SourceInfo::Contents::CompressionType Type)
Compute Parameters based on the content of Args.
void computeFinalSize(uint32_t CompressedSize)
Update Parameters based on the compressed size of section content.
dxbc::SourceInfo::Contents::Header Parameters
void compute(uint32_t ContentSize)
Compute Parameters based on FileName and FileContent.
dxbc::SourceInfo::Names::Entry Parameters
void compute()
Compute headers based on the content of entries.
void compute()
Compute Parameters based on the content of sections.
dxbc::SourceInfo::Header Parameters