LLVM 22.0.0git
CodeGenDataWriter.cpp
Go to the documentation of this file.
1//===- CodeGenDataWriter.cpp ----------------------------------------------===//
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 support for writing codegen data.
10//
11//===----------------------------------------------------------------------===//
12
14
15#define DEBUG_TYPE "cg-data-writer"
16
17using namespace llvm;
18
20 using namespace support;
21
22 switch (Kind) {
23 case OStreamKind::fd: {
24 raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
25 const uint64_t LastPos = FDOStream.tell();
26 for (const auto &K : P) {
27 FDOStream.seek(K.Pos);
28 for (size_t I = 0; I < K.D.size(); ++I)
29 write(K.D[I]);
30 }
31 // Reset the stream to the last position after patching so that users
32 // don't accidentally overwrite data. This makes it consistent with
33 // the string stream below which replaces the data directly.
34 FDOStream.seek(LastPos);
35 break;
36 }
37 case OStreamKind::string: {
38 raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS);
39 std::string &Data = SOStream.str(); // with flush
40 for (const auto &K : P) {
41 for (size_t I = 0; I < K.D.size(); ++I) {
42 uint64_t Bytes =
43 endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]);
44 Data.replace(K.Pos + I * sizeof(uint64_t), sizeof(uint64_t),
45 reinterpret_cast<const char *>(&Bytes), sizeof(uint64_t));
46 }
47 }
48 break;
49 }
50 case OStreamKind::svector: {
51 raw_svector_ostream &VOStream = static_cast<raw_svector_ostream &>(OS);
52 for (const auto &K : P) {
53 for (size_t I = 0; I < K.D.size(); ++I) {
54 uint64_t Bytes =
55 endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]);
56 VOStream.pwrite(reinterpret_cast<const char *>(&Bytes),
57 sizeof(uint64_t), K.Pos + I * sizeof(uint64_t));
58 }
59 }
60 break;
61 }
62 }
63}
64
66 assert(Record.HashTree && "empty hash tree in the record");
67 HashTreeRecord.HashTree = std::move(Record.HashTree);
68
70}
71
73 assert(Record.FunctionMap && "empty function map in the record");
74 FunctionMapRecord.FunctionMap = std::move(Record.FunctionMap);
75
77}
78
80 CGDataOStream COS(OS);
81 return writeImpl(COS);
82}
83
84Error CodeGenDataWriter::writeHeader(CGDataOStream &COS) {
85 using namespace support;
87 Header.Magic = IndexedCGData::Magic;
88 Header.Version = IndexedCGData::Version;
89
90 // Set the CGDataKind depending on the kind.
91 Header.DataKind = 0;
92 if (static_cast<bool>(DataKind & CGDataKind::FunctionOutlinedHashTree))
93 Header.DataKind |=
95 if (static_cast<bool>(DataKind & CGDataKind::StableFunctionMergingMap))
96 Header.DataKind |=
98 Header.OutlinedHashTreeOffset = 0;
99 Header.StableFunctionMapOffset = 0;
100
101 // Only write up to the CGDataKind. We need to remember the offset of the
102 // remaining fields to allow back-patching later.
103 COS.write(Header.Magic);
104 COS.write32(Header.Version);
105 COS.write32(Header.DataKind);
106
107 // Save the location of Header.OutlinedHashTreeOffset field in \c COS.
108 OutlinedHashTreeOffset = COS.tell();
109
110 // Reserve the space for OutlinedHashTreeOffset field.
111 COS.write(0);
112
113 // Save the location of Header.StableFunctionMapOffset field in \c COS.
114 StableFunctionMapOffset = COS.tell();
115
116 // Reserve the space for StableFunctionMapOffset field.
117 COS.write(0);
118
119 return Error::success();
120}
121
122Error CodeGenDataWriter::writeImpl(CGDataOStream &COS) {
123 if (Error E = writeHeader(COS))
124 return E;
125
126 std::vector<CGDataPatchItem> PatchItems;
127
128 uint64_t OutlinedHashTreeFieldStart = COS.tell();
130 HashTreeRecord.serialize(COS.OS);
131 uint64_t StableFunctionMapFieldStart = COS.tell();
133 FunctionMapRecord.serialize(COS.OS, PatchItems);
134
135 // Back patch the offsets.
136 PatchItems.emplace_back(OutlinedHashTreeOffset, &OutlinedHashTreeFieldStart,
137 1);
138 PatchItems.emplace_back(StableFunctionMapOffset, &StableFunctionMapFieldStart,
139 1);
140 COS.patch(PatchItems);
141
142 return Error::success();
143}
144
145Error CodeGenDataWriter::writeHeaderText(raw_fd_ostream &OS) {
147 OS << "# Outlined stable hash tree\n:outlined_hash_tree\n";
148
150 OS << "# Stable function map\n:stable_function_map\n";
151
152 // TODO: Add more data types in this header
153
154 return Error::success();
155}
156
158 if (Error E = writeHeaderText(OS))
159 return E;
160
161 yaml::Output YOS(OS);
163 HashTreeRecord.serializeYAML(YOS);
164
166 FunctionMapRecord.serializeYAML(YOS);
167
168 // TODO: Write more yaml cgdata in order
169
170 return Error::success();
171}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A wrapper class to abstract writer stream with support of bytes back patching.
LLVM_ABI void patch(ArrayRef< CGDataPatchItem > P)
void write32(uint32_t V)
void write(uint64_t V)
LLVM_ABI Error writeText(raw_fd_ostream &OS)
Write the codegen data in text format to OS.
LLVM_ABI Error write(raw_fd_ostream &OS)
Write the codegen data to OS.
bool hasOutlinedHashTree() const
Return true if the header indicates the data has an outlined hash tree.
bool hasStableFunctionMap() const
Return true if the header indicates the data has a stable function map.
LLVM_ABI void addRecord(OutlinedHashTreeRecord &Record)
Add the outlined hash tree record. The input hash tree is released.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:461
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:148
void pwrite(const char *Ptr, size_t Size, uint64_t Offset)
Definition: raw_ostream.h:443
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:680
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:692
const uint64_t Version
Definition: CodeGenData.h:293
const uint64_t Magic
Definition: CodeGenData.h:277
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void serializeYAML(yaml::Output &YOS) const
Serialize the outlined hash tree to a YAML stream.
LLVM_ABI void serialize(raw_ostream &OS) const
Serialize the outlined hash tree to a raw_ostream.
std::unique_ptr< OutlinedHashTree > HashTree
The structure of the serialized stable function map is as follows:
std::unique_ptr< StableFunctionMap > FunctionMap
static LLVM_ABI void serialize(raw_ostream &OS, const StableFunctionMap *FunctionMap, std::vector< CGDataPatchItem > &PatchItems)
A static helper function to serialize the stable function map without owning the stable function map.
LLVM_ABI void serializeYAML(yaml::Output &YOS) const
Serialize the stable function map to a YAML stream.