LLVM 24.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"
29#include <mutex>
30
31namespace llvm {
32
33namespace cl {
35} // namespace cl
36
38#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
40};
41
44 bool AddSegmentInfo = true);
45
46enum class CGDataKind {
47 Unknown = 0x0,
48 // A function outlining info.
50 // A function merging info.
53};
54
55LLVM_ABI const std::error_category &cgdata_category();
66
67inline std::error_code make_error_code(cgdata_error E) {
68 return std::error_code(static_cast<int>(E), cgdata_category());
69}
70
71class LLVM_ABI CGDataError : public ErrorInfo<CGDataError> {
72public:
73 CGDataError(cgdata_error Err, const Twine &ErrStr = Twine())
74 : Err(Err), Msg(ErrStr.str()) {
75 assert(Err != cgdata_error::success && "Not an error");
76 }
77
78 std::string message() const override;
79
80 void log(raw_ostream &OS) const override { OS << message(); }
81
82 std::error_code convertToErrorCode() const override {
83 return make_error_code(Err);
84 }
85
86 cgdata_error get() const { return Err; }
87 const std::string &getMessage() const { return Msg; }
88
89 /// Consume an Error and return the raw enum value contained within it, and
90 /// the optional error message. The Error must either be a success value, or
91 /// contain a single CGDataError.
92 static std::pair<cgdata_error, std::string> take(Error E) {
93 auto Err = cgdata_error::success;
94 std::string Msg;
95 handleAllErrors(std::move(E), [&Err, &Msg](const CGDataError &IPE) {
96 assert(Err == cgdata_error::success && "Multiple errors encountered");
97 Err = IPE.get();
98 Msg = IPE.getMessage();
99 });
100 return {Err, Msg};
101 }
102
103 static char ID;
104
105private:
106 cgdata_error Err;
107 std::string Msg;
108};
109
115
116class CodeGenData {
117 /// Global outlined hash tree that has oulined hash sequences across modules.
118 std::unique_ptr<OutlinedHashTree> PublishedHashTree;
119 /// Global stable function map that has stable function info across modules.
120 std::unique_ptr<StableFunctionMap> PublishedStableFunctionMap;
121
122 /// This flag is set when -fcodegen-data-generate is passed.
123 /// Or, it can be mutated with -fcodegen-data-thinlto-two-rounds.
124 bool EmitCGData;
125
126 /// This is a singleton instance which is thread-safe. Unlike profile data
127 /// which is largely function-based, codegen data describes the whole module.
128 /// Therefore, this can be initialized once, and can be used across modules
129 /// instead of constructing the same one for each codegen backend.
130 static std::unique_ptr<CodeGenData> Instance;
131 static std::once_flag OnceFlag;
132
133 CodeGenData() = default;
134
135public:
136 ~CodeGenData() = default;
137
138 /// The first call's \p LibraryOptions configure the singleton.
139 LLVM_ABI static CodeGenData &
140 getInstance(const cl::LibraryOptionsContext &LibraryOptions);
141
142 /// Returns true if we have a valid outlined hash tree.
144 return PublishedHashTree && !PublishedHashTree->empty();
145 }
147 return PublishedStableFunctionMap && !PublishedStableFunctionMap->empty();
148 }
149
150 /// Returns the outlined hash tree. This can be globally used in a read-only
151 /// manner.
153 return PublishedHashTree.get();
154 }
156 return PublishedStableFunctionMap.get();
157 }
158
159 /// Returns true if we should write codegen data.
160 bool emitCGData() { return EmitCGData; }
161
162 /// Publish the (globally) merged or read outlined hash tree.
163 void publishOutlinedHashTree(std::unique_ptr<OutlinedHashTree> HashTree) {
164 PublishedHashTree = std::move(HashTree);
165 // Ensure we disable emitCGData as we do not want to read and write both.
166 EmitCGData = false;
167 }
168 void
169 publishStableFunctionMap(std::unique_ptr<StableFunctionMap> FunctionMap) {
170 PublishedStableFunctionMap = std::move(FunctionMap);
171 // Ensure we disable emitCGData as we do not want to read and write both.
172 EmitCGData = false;
173 }
174};
175
176namespace cgdata {
177
178inline bool
180 return CodeGenData::getInstance(LibraryOptions).hasOutlinedHashTree();
181}
182
183inline bool
185 return CodeGenData::getInstance(LibraryOptions).hasStableFunctionMap();
186}
187
188inline const OutlinedHashTree *
190 return CodeGenData::getInstance(LibraryOptions).getOutlinedHashTree();
191}
192
193inline const StableFunctionMap *
195 return CodeGenData::getInstance(LibraryOptions).getStableFunctionMap();
196}
197
198inline bool emitCGData(const cl::LibraryOptionsContext &LibraryOptions) {
199 return CodeGenData::getInstance(LibraryOptions).emitCGData();
200}
201
202inline void
204 std::unique_ptr<OutlinedHashTree> HashTree) {
205 CodeGenData::getInstance(LibraryOptions)
206 .publishOutlinedHashTree(std::move(HashTree));
207}
208
209inline void
211 std::unique_ptr<StableFunctionMap> FunctionMap) {
212 CodeGenData::getInstance(LibraryOptions)
213 .publishStableFunctionMap(std::move(FunctionMap));
214}
215
217 /// Backing buffer for serialized data stream.
219 /// Callback function to add serialized data to the stream.
221 /// Backing buffer for cached data.
223 /// Cache mechanism for storing data.
225
226 StreamCacheData(unsigned Size, const FileCache &OrigCache,
227 const Twine &CachePrefix)
228 : Outputs(Size), Files(Size) {
229 AddStream = [&](size_t Task, const Twine &ModuleName) {
230 return std::make_unique<CachedFileStream>(
231 std::make_unique<raw_svector_ostream>(Outputs[Task]));
232 };
233
234 if (OrigCache.isValid()) {
235 auto CGCacheOrErr =
236 localCache("ThinLTO", CachePrefix, OrigCache.getCacheDirectoryPath(),
237 [&](size_t Task, const Twine &ModuleName,
238 std::unique_ptr<MemoryBuffer> MB) {
239 Files[Task] = std::move(MB);
240 });
241 if (Error Err = CGCacheOrErr.takeError())
242 report_fatal_error(std::move(Err));
243 Cache = std::move(*CGCacheOrErr);
244 }
245 }
246 StreamCacheData() = delete;
247
248 /// Retrieve results from either the cache or the stream.
249 std::unique_ptr<SmallVector<StringRef>> getResult() {
250 unsigned NumOutputs = Outputs.size();
251 auto Result = std::make_unique<SmallVector<StringRef>>(NumOutputs);
252 for (unsigned I = 0; I < NumOutputs; ++I)
253 if (Files[I])
254 (*Result)[I] = Files[I]->getBuffer();
255 else
256 (*Result)[I] = Outputs[I];
257 return Result;
258 }
259};
260
261/// Returns whether ThinLTO runs two rounds of code generation
262/// (-codegen-data-thinlto-two-rounds).
263LLVM_ABI bool thinLTOTwoRounds(const cl::LibraryOptionsContext &LibraryOptions);
264
265/// Save \p TheModule before the first codegen round.
266/// \p Task represents the partition number in the parallel code generation
267/// process. \p AddStream is the callback used to add the serialized module to
268/// the stream.
269LLVM_ABI void saveModuleForTwoRounds(const Module &TheModule, unsigned Task,
270 AddStreamFn AddStream);
271
272/// Load the optimized bitcode module for the second codegen round.
273/// \p OrigModule is the original bitcode module.
274/// \p Task identifies the partition number in the parallel code generation
275/// process. \p Context provides the environment settings for module operations.
276/// \p IRFiles contains optimized bitcode module files needed for loading.
277/// \return A unique_ptr to the loaded Module, or nullptr if loading fails.
278LLVM_ABI std::unique_ptr<Module>
279loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task,
280 LLVMContext &Context, ArrayRef<StringRef> IRFiles);
281
282/// Merge the codegen data from the scratch objects \p ObjectFiles from the
283/// first codegen round.
284/// \return the combined hash of the merged codegen data.
286mergeCodeGenData(const cl::LibraryOptionsContext &LibraryOptions,
287 ArrayRef<StringRef> ObjectFiles);
288
289LLVM_ABI void warn(Error E, StringRef Whence = "");
290LLVM_ABI void warn(Twine Message, StringRef Whence = "", StringRef Hint = "");
291
292} // end namespace cgdata
293
294namespace IndexedCGData {
295
296// A signature for data validation, representing "\xffcgdata\x81" in
297// little-endian order
298const uint64_t Magic = 0x81617461646763ff;
299
301 // Version 1 is the first version. This version supports the outlined
302 // hash tree.
304 // Version 2 supports the stable function merging map.
306 // Version 3 adds the total size of the Names in the stable function map so
307 // we can skip reading them into the memory for non-assertion builds.
309 // Version 4 adjusts the structure of stable function merging map for
310 // efficient lazy loading support.
313};
315
316struct Header {
322
323 // New fields should only be added at the end to ensure that the size
324 // computation is correct. The methods below need to be updated to ensure that
325 // the new field is read correctly.
326
327 // Reads a header struct from the buffer.
328 LLVM_ABI static Expected<Header> readFromBuffer(const unsigned char *Curr);
329};
330
331} // end namespace IndexedCGData
332
333} // end namespace llvm
334
335#endif // LLVM_CODEGEN_PREPARE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define CG_DATA_INDEX_VERSION
#define LLVM_ABI
Definition Compiler.h:211
Module.h This file contains the declarations for the Module class.
#define I(x, y, z)
Definition MD5.cpp:57
if(PassOpts->AAPipeline)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Represents a module in a bitcode file.
const std::string & getMessage() const
Definition CodeGenData.h:87
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition CodeGenData.h:82
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:92
std::string message() const override
Return the error message as a string.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
Definition CodeGenData.h:80
CGDataError(cgdata_error Err, const Twine &ErrStr=Twine())
Definition CodeGenData.h:73
cgdata_error get() const
Definition CodeGenData.h:86
bool hasStableFunctionMap()
const StableFunctionMap * getStableFunctionMap()
bool emitCGData()
Returns true if we should write codegen data.
void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)
Publish the (globally) merged or read outlined hash tree.
bool hasOutlinedHashTree()
Returns true if we have a valid outlined hash tree.
const OutlinedHashTree * getOutlinedHashTree()
Returns the outlined hash tree.
~CodeGenData()=default
static LLVM_ABI CodeGenData & getInstance(const cl::LibraryOptionsContext &LibraryOptions)
The first call's LibraryOptions configure the singleton.
void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)
Base class for user error types.
Definition Error.h:354
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
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
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
const uint64_t Version
const uint64_t Magic
const OutlinedHashTree * getOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions)
void publishStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions, std::unique_ptr< StableFunctionMap > FunctionMap)
bool hasStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions)
const StableFunctionMap * getStableFunctionMap(const cl::LibraryOptionsContext &LibraryOptions)
bool hasOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions)
void publishOutlinedHashTree(const cl::LibraryOptionsContext &LibraryOptions, std::unique_ptr< OutlinedHashTree > HashTree)
bool emitCGData(const cl::LibraryOptionsContext &LibraryOptions)
This namespace contains all of the command line option processing machinery.
Definition CodeGenData.h:33
This is an optimization pass for GlobalISel generic memory operations.
@ Unknown
Not known to have no common set bits.
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:1013
cgdata_error
Definition CodeGenData.h:57
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI const std::error_category & cgdata_category()
CGDataSectKind
Definition CodeGenData.h:37
LogicalResult success(bool IsSuccess=true)
Utility function to generate a LogicalResult.
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:79
LLVM_ABI 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:105
bool isValid() const
Definition Caching.h:118
static LLVM_ABI Expected< Header > readFromBuffer(const unsigned char *Curr)
SmallVector< SmallString< 0 > > Outputs
Backing buffer for serialized data stream.
FileCache Cache
Cache mechanism for storing data.
SmallVector< std::unique_ptr< MemoryBuffer > > Files
Backing buffer for cached data.
std::unique_ptr< SmallVector< StringRef > > getResult()
Retrieve results from either the cache or the stream.
AddStreamFn AddStream
Callback function to add serialized data to the stream.
StreamCacheData(unsigned Size, const FileCache &OrigCache, const Twine &CachePrefix)