LLVM 20.0.0git
CodeGenData.h
Go to the documentation of this file.
1//===- CodeGenData.h --------------------------------------------*- 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 support for codegen data that has stable summary which
10// can be used to optimize the code in the subsequent codegen.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CGDATA_CODEGENDATA_H
15#define LLVM_CGDATA_CODEGENDATA_H
16
23#include "llvm/IR/Module.h"
28#include <mutex>
29
30namespace llvm {
31
33#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
35};
36
39 bool AddSegmentInfo = true);
40
41enum class CGDataKind {
42 Unknown = 0x0,
43 // A function outlining info.
45 // A function merging info.
48};
49
50const std::error_category &cgdata_category();
51
52enum class cgdata_error {
53 success = 0,
54 eof,
60};
61
62inline std::error_code make_error_code(cgdata_error E) {
63 return std::error_code(static_cast<int>(E), cgdata_category());
64}
65
66class CGDataError : public ErrorInfo<CGDataError> {
67public:
68 CGDataError(cgdata_error Err, const Twine &ErrStr = Twine())
69 : Err(Err), Msg(ErrStr.str()) {
70 assert(Err != cgdata_error::success && "Not an error");
71 }
72
73 std::string message() const override;
74
75 void log(raw_ostream &OS) const override { OS << message(); }
76
77 std::error_code convertToErrorCode() const override {
78 return make_error_code(Err);
79 }
80
81 cgdata_error get() const { return Err; }
82 const std::string &getMessage() const { return Msg; }
83
84 /// Consume an Error and return the raw enum value contained within it, and
85 /// the optional error message. The Error must either be a success value, or
86 /// contain a single CGDataError.
87 static std::pair<cgdata_error, std::string> take(Error E) {
88 auto Err = cgdata_error::success;
89 std::string Msg;
90 handleAllErrors(std::move(E), [&Err, &Msg](const CGDataError &IPE) {
91 assert(Err == cgdata_error::success && "Multiple errors encountered");
92 Err = IPE.get();
93 Msg = IPE.getMessage();
94 });
95 return {Err, Msg};
96 }
97
98 static char ID;
99
100private:
101 cgdata_error Err;
102 std::string Msg;
103};
104
109};
110
112 /// Global outlined hash tree that has oulined hash sequences across modules.
113 std::unique_ptr<OutlinedHashTree> PublishedHashTree;
114 /// Global stable function map that has stable function info across modules.
115 std::unique_ptr<StableFunctionMap> PublishedStableFunctionMap;
116
117 /// This flag is set when -fcodegen-data-generate is passed.
118 /// Or, it can be mutated with -fcodegen-data-thinlto-two-rounds.
119 bool EmitCGData;
120
121 /// This is a singleton instance which is thread-safe. Unlike profile data
122 /// which is largely function-based, codegen data describes the whole module.
123 /// Therefore, this can be initialized once, and can be used across modules
124 /// instead of constructing the same one for each codegen backend.
125 static std::unique_ptr<CodeGenData> Instance;
126 static std::once_flag OnceFlag;
127
128 CodeGenData() = default;
129
130public:
131 ~CodeGenData() = default;
132
133 static CodeGenData &getInstance();
134
135 /// Returns true if we have a valid outlined hash tree.
137 return PublishedHashTree && !PublishedHashTree->empty();
138 }
140 return PublishedStableFunctionMap && !PublishedStableFunctionMap->empty();
141 }
142
143 /// Returns the outlined hash tree. This can be globally used in a read-only
144 /// manner.
146 return PublishedHashTree.get();
147 }
149 return PublishedStableFunctionMap.get();
150 }
151
152 /// Returns true if we should write codegen data.
153 bool emitCGData() { return EmitCGData; }
154
155 /// Publish the (globally) merged or read outlined hash tree.
156 void publishOutlinedHashTree(std::unique_ptr<OutlinedHashTree> HashTree) {
157 PublishedHashTree = std::move(HashTree);
158 // Ensure we disable emitCGData as we do not want to read and write both.
159 EmitCGData = false;
160 }
161 void
162 publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
163 PublishedStableFunctionMap = std::move(FunctionMap);
164 // Ensure we disable emitCGData as we do not want to read and write both.
165 EmitCGData = false;
166 }
167};
168
169namespace cgdata {
170
171inline bool hasOutlinedHashTree() {
173}
174
175inline bool hasStableFunctionMap() {
177}
178
181}
182
185}
186
187inline bool emitCGData() { return CodeGenData::getInstance().emitCGData(); }
188
189inline void
190publishOutlinedHashTree(std::unique_ptr<OutlinedHashTree> HashTree) {
192}
193
194inline void
195publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
196 CodeGenData::getInstance().publishStableFunctionMap(std::move(FunctionMap));
197}
198
200 /// Backing buffer for serialized data stream.
202 /// Callback function to add serialized data to the stream.
204 /// Backing buffer for cached data.
206 /// Cache mechanism for storing data.
208
209 StreamCacheData(unsigned Size, const FileCache &OrigCache,
210 const Twine &CachePrefix)
211 : Outputs(Size), Files(Size) {
212 AddStream = [&](size_t Task, const Twine &ModuleName) {
213 return std::make_unique<CachedFileStream>(
214 std::make_unique<raw_svector_ostream>(Outputs[Task]));
215 };
216
217 if (OrigCache.isValid()) {
218 auto CGCacheOrErr =
219 localCache("ThinLTO", CachePrefix, OrigCache.getCacheDirectoryPath(),
220 [&](size_t Task, const Twine &ModuleName,
221 std::unique_ptr<MemoryBuffer> MB) {
222 Files[Task] = std::move(MB);
223 });
224 if (Error Err = CGCacheOrErr.takeError())
225 report_fatal_error(std::move(Err));
226 Cache = std::move(*CGCacheOrErr);
227 }
228 }
229 StreamCacheData() = delete;
230
231 /// Retrieve results from either the cache or the stream.
232 std::unique_ptr<SmallVector<StringRef>> getResult() {
233 unsigned NumOutputs = Outputs.size();
234 auto Result = std::make_unique<SmallVector<StringRef>>(NumOutputs);
235 for (unsigned I = 0; I < NumOutputs; ++I)
236 if (Files[I])
237 (*Result)[I] = Files[I]->getBuffer();
238 else
239 (*Result)[I] = Outputs[I];
240 return Result;
241 }
242};
243
244/// Save \p TheModule before the first codegen round.
245/// \p Task represents the partition number in the parallel code generation
246/// process. \p AddStream is the callback used to add the serialized module to
247/// the stream.
248void saveModuleForTwoRounds(const Module &TheModule, unsigned Task,
249 AddStreamFn AddStream);
250
251/// Load the optimized bitcode module for the second codegen round.
252/// \p OrigModule is the original bitcode module.
253/// \p Task identifies the partition number in the parallel code generation
254/// process. \p Context provides the environment settings for module operations.
255/// \p IRFiles contains optimized bitcode module files needed for loading.
256/// \return A unique_ptr to the loaded Module, or nullptr if loading fails.
257std::unique_ptr<Module> loadModuleForTwoRounds(BitcodeModule &OrigModule,
258 unsigned Task,
259 LLVMContext &Context,
260 ArrayRef<StringRef> IRFiles);
261
262/// Merge the codegen data from the scratch objects \p ObjectFiles from the
263/// first codegen round.
264/// \return the combined hash of the merged codegen data.
266
267void warn(Error E, StringRef Whence = "");
268void warn(Twine Message, std::string Whence = "", std::string Hint = "");
269
270} // end namespace cgdata
271
272namespace IndexedCGData {
273
274// A signature for data validation, representing "\xffcgdata\x81" in
275// little-endian order
276const uint64_t Magic = 0x81617461646763ff;
277
279 // Version 1 is the first version. This version supports the outlined
280 // hash tree.
282 // Version 2 supports the stable function merging map.
284 CurrentVersion = CG_DATA_INDEX_VERSION
287
288struct Header {
294
295 // New fields should only be added at the end to ensure that the size
296 // computation is correct. The methods below need to be updated to ensure that
297 // the new field is read correctly.
298
299 // Reads a header struct from the buffer.
300 static Expected<Header> readFromBuffer(const unsigned char *Curr);
301};
302
303} // end namespace IndexedCGData
304
305} // end namespace llvm
306
307#endif // LLVM_CODEGEN_PREPARE_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
uint64_t Size
Module.h This file contains the declarations for the Module class.
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Represents a module in a bitcode file.
const std::string & getMessage() const
Definition: CodeGenData.h:82
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: CodeGenData.h:77
static std::pair< cgdata_error, std::string > take(Error E)
Consume an Error and return the raw enum value contained within it, and the optional error message.
Definition: CodeGenData.h:87
static char ID
Definition: CodeGenData.h:98
std::string message() const override
Return the error message as a string.
Definition: CodeGenData.cpp:98
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition: CodeGenData.h:75
CGDataError(cgdata_error Err, const Twine &ErrStr=Twine())
Definition: CodeGenData.h:68
cgdata_error get() const
Definition: CodeGenData.h:81
bool hasStableFunctionMap()
Definition: CodeGenData.h:139
const StableFunctionMap * getStableFunctionMap()
Definition: CodeGenData.h:148
bool emitCGData()
Returns true if we should write codegen data.
Definition: CodeGenData.h:153
void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)
Publish the (globally) merged or read outlined hash tree.
Definition: CodeGenData.h:156
bool hasOutlinedHashTree()
Returns true if we have a valid outlined hash tree.
Definition: CodeGenData.h:136
const OutlinedHashTree * getOutlinedHashTree()
Returns the outlined hash tree.
Definition: CodeGenData.h:145
~CodeGenData()=default
void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)
Definition: CodeGenData.h:162
static CodeGenData & getInstance()
Base class for user error types.
Definition: Error.h:355
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:481
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
ObjectFormatType
Definition: Triple.h:307
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
const uint64_t Version
Definition: CodeGenData.h:286
const uint64_t Magic
Definition: CodeGenData.h:276
Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)
Definition: CodeGenData.h:190
bool hasOutlinedHashTree()
Definition: CodeGenData.h:171
bool hasStableFunctionMap()
Definition: CodeGenData.h:175
void warn(Error E, StringRef Whence="")
const OutlinedHashTree * getOutlinedHashTree()
Definition: CodeGenData.h:179
void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)
Definition: CodeGenData.h:195
void saveModuleForTwoRounds(const Module &TheModule, unsigned Task, AddStreamFn AddStream)
Save TheModule before the first codegen round.
bool emitCGData()
Definition: CodeGenData.h:187
const StableFunctionMap * getStableFunctionMap()
Definition: CodeGenData.h:183
std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)
Load the optimized bitcode module for the second codegen round.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
CGDataKind
Definition: CodeGenData.h:41
CGDataMode
Definition: CodeGenData.h:105
@ Read
Definition: CodeGenData.h:107
@ Write
Definition: CodeGenData.h:108
std::error_code make_error_code(BitcodeError E)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:977
std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
Definition: Caching.h:42
cgdata_error
Definition: CodeGenData.h:52
@ None
Definition: CodeGenData.h:106
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
const std::error_category & cgdata_category()
Definition: CodeGenData.cpp:93
CGDataSectKind
Definition: CodeGenData.h:32
Expected< FileCache > localCache(const Twine &CacheNameRef, const Twine &TempFilePrefixRef, const Twine &CacheDirectoryPathRef, AddBufferFn AddBuffer=[](size_t Task, const Twine &ModuleName, std::unique_ptr< MemoryBuffer > MB) {})
Create a local file system cache which uses the given cache name, temporary file prefix,...
Definition: Caching.cpp:29
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
This type represents a file cache system that manages caching of files.
Definition: Caching.h:67
const std::string & getCacheDirectoryPath() const
Definition: Caching.h:77
bool isValid() const
Definition: Caching.h:80
static Expected< Header > readFromBuffer(const unsigned char *Curr)
SmallVector< SmallString< 0 > > Outputs
Backing buffer for serialized data stream.
Definition: CodeGenData.h:201
FileCache Cache
Cache mechanism for storing data.
Definition: CodeGenData.h:207
SmallVector< std::unique_ptr< MemoryBuffer > > Files
Backing buffer for cached data.
Definition: CodeGenData.h:205
std::unique_ptr< SmallVector< StringRef > > getResult()
Retrieve results from either the cache or the stream.
Definition: CodeGenData.h:232
AddStreamFn AddStream
Callback function to add serialized data to the stream.
Definition: CodeGenData.h:203
StreamCacheData(unsigned Size, const FileCache &OrigCache, const Twine &CachePrefix)
Definition: CodeGenData.h:209