Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
CodeGenData.cpp
Go to the documentation of this file.
1//===-- CodeGenData.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 codegen data that has stable summary which
10// can be used to optimize the code in the subsequent codegen.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Bitcode/BitcodeWriter.h"
15#include "llvm/CGData/CodeGenDataReader.h"
16#include "llvm/CGData/OutlinedHashTreeRecord.h"
17#include "llvm/CGData/StableFunctionMapRecord.h"
18#include "llvm/Object/ObjectFile.h"
19#include "llvm/Support/Caching.h"
20#include "llvm/Support/CommandLine.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/Path.h"
23#include "llvm/Support/WithColor.h"
24
25#define DEBUG_TYPE "cg-data"
26
27using namespacellvm;
28using namespacecgdata;
29
30cl::opt<bool>
31CodeGenDataGenerate("codegen-data-generate",cl::init(false),cl::Hidden,
32cl::desc("Emit CodeGen Data into custom sections"));
33cl::opt<std::string>
34CodeGenDataUsePath("codegen-data-use-path",cl::init(""),cl::Hidden,
35cl::desc("File path to where .cgdata file is read"));
36cl::opt<bool>CodeGenDataThinLTOTwoRounds(
37"codegen-data-thinlto-two-rounds",cl::init(false),cl::Hidden,
38cl::desc("Enable two-round ThinLTO code generation. The first round "
39"emits codegen data, while the second round uses the emitted "
40"codegen data for further optimizations."));
41
42static std::stringgetCGDataErrString(cgdata_error Err,
43const std::string &ErrMsg ="") {
44 std::string Msg;
45raw_string_ostreamOS(Msg);
46
47switch (Err) {
48case cgdata_error::success:
49OS <<"success";
50break;
51case cgdata_error::eof:
52OS <<"end of File";
53break;
54case cgdata_error::bad_magic:
55OS <<"invalid codegen data (bad magic)";
56break;
57case cgdata_error::bad_header:
58OS <<"invalid codegen data (file header is corrupt)";
59break;
60case cgdata_error::empty_cgdata:
61OS <<"empty codegen data";
62break;
63case cgdata_error::malformed:
64OS <<"malformed codegen data";
65break;
66case cgdata_error::unsupported_version:
67OS <<"unsupported codegen data version";
68break;
69 }
70
71// If optional error message is not empty, append it to the message.
72if (!ErrMsg.empty())
73OS <<": " << ErrMsg;
74
75returnOS.str();
76}
77
78namespace{
79
80// FIXME: This class is only here to support the transition to llvm::Error. It
81// will be removed once this transition is complete. Clients should prefer to
82// deal with the Error value directly, rather than converting to error_code.
83classCGDataErrorCategoryType :public std::error_category {
84constchar *name()const noexcept override{return"llvm.cgdata"; }
85
86 std::string message(int IE) const override{
87returngetCGDataErrString(static_cast<cgdata_error>(IE));
88 }
89};
90
91}// end anonymous namespace
92
93const std::error_category &llvm::cgdata_category() {
94static CGDataErrorCategoryType ErrorCategory;
95return ErrorCategory;
96}
97
98std::stringCGDataError::message() const{
99returngetCGDataErrString(Err, Msg);
100}
101
102charCGDataError::ID = 0;
103
104namespace{
105
106constchar *CodeGenDataSectNameCommon[] = {
107#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
108 SectNameCommon,
109#include "llvm/CGData/CodeGenData.inc"
110};
111
112constchar *CodeGenDataSectNameCoff[] = {
113#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
114 SectNameCoff,
115#include "llvm/CGData/CodeGenData.inc"
116};
117
118constchar *CodeGenDataSectNamePrefix[] = {
119#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Prefix,
120#include "llvm/CGData/CodeGenData.inc"
121};
122
123}// namespace
124
125namespacellvm {
126
127std::stringgetCodeGenDataSectionName(CGDataSectKind CGSK,
128Triple::ObjectFormatType OF,
129bool AddSegmentInfo) {
130 std::string SectName;
131
132if (OF ==Triple::MachO && AddSegmentInfo)
133 SectName = CodeGenDataSectNamePrefix[CGSK];
134
135if (OF ==Triple::COFF)
136 SectName += CodeGenDataSectNameCoff[CGSK];
137else
138 SectName += CodeGenDataSectNameCommon[CGSK];
139
140return SectName;
141}
142
143std::unique_ptr<CodeGenData> CodeGenData::Instance =nullptr;
144std::once_flag CodeGenData::OnceFlag;
145
146CodeGenData &CodeGenData::getInstance() {
147 std::call_once(CodeGenData::OnceFlag, []() {
148 Instance = std::unique_ptr<CodeGenData>(newCodeGenData());
149
150if (CodeGenDataGenerate ||CodeGenDataThinLTOTwoRounds)
151 Instance->EmitCGData =true;
152elseif (!CodeGenDataUsePath.empty()) {
153// Initialize the global CGData if the input file name is given.
154// We do not error-out when failing to parse the input file.
155// Instead, just emit an warning message and fall back as if no CGData
156// were available.
157auto FS =vfs::getRealFileSystem();
158auto ReaderOrErr =CodeGenDataReader::create(CodeGenDataUsePath, *FS);
159if (Error E = ReaderOrErr.takeError()) {
160warn(std::move(E),CodeGenDataUsePath);
161return;
162 }
163// Publish each CGData based on the data type in the header.
164auto Reader = ReaderOrErr->get();
165if (Reader->hasOutlinedHashTree())
166 Instance->publishOutlinedHashTree(Reader->releaseOutlinedHashTree());
167if (Reader->hasStableFunctionMap())
168 Instance->publishStableFunctionMap(Reader->releaseStableFunctionMap());
169 }
170 });
171return *Instance;
172}
173
174namespaceIndexedCGData {
175
176Expected<Header>Header::readFromBuffer(constunsignedchar *Curr) {
177using namespacesupport;
178
179static_assert(std::is_standard_layout_v<llvm::IndexedCGData::Header>,
180"The header should be standard layout type since we use offset "
181"of fields to read.");
182HeaderH;
183H.Magic = endian::readNext<uint64_t, endianness::little, unaligned>(Curr);
184if (H.Magic !=IndexedCGData::Magic)
185return make_error<CGDataError>(cgdata_error::bad_magic);
186H.Version = endian::readNext<uint32_t, endianness::little, unaligned>(Curr);
187if (H.Version >IndexedCGData::CGDataVersion::CurrentVersion)
188return make_error<CGDataError>(cgdata_error::unsupported_version);
189H.DataKind = endian::readNext<uint32_t, endianness::little, unaligned>(Curr);
190
191static_assert(IndexedCGData::CGDataVersion::CurrentVersion ==Version2,
192"Please update the offset computation below if a new field has "
193"been added to the header.");
194H.OutlinedHashTreeOffset =
195 endian::readNext<uint64_t, endianness::little, unaligned>(Curr);
196if (H.Version >= 2)
197H.StableFunctionMapOffset =
198 endian::readNext<uint64_t, endianness::little, unaligned>(Curr);
199
200returnH;
201}
202
203}// end namespace IndexedCGData
204
205namespacecgdata {
206
207voidwarn(Twine Message, std::string Whence, std::string Hint) {
208WithColor::warning();
209if (!Whence.empty())
210errs() << Whence <<": ";
211errs() << Message <<"\n";
212if (!Hint.empty())
213WithColor::note() << Hint <<"\n";
214}
215
216voidwarn(Error E,StringRef Whence) {
217if (E.isA<CGDataError>()) {
218handleAllErrors(std::move(E), [&](constCGDataError &IPE) {
219warn(IPE.message(), Whence.str(),"");
220 });
221 }
222}
223
224voidsaveModuleForTwoRounds(constModule &TheModule,unsigned Task,
225AddStreamFn AddStream) {
226LLVM_DEBUG(dbgs() <<"Saving module: " << TheModule.getModuleIdentifier()
227 <<" in Task " << Task <<"\n");
228Expected<std::unique_ptr<CachedFileStream>> StreamOrErr =
229 AddStream(Task, TheModule.getModuleIdentifier());
230if (Error Err = StreamOrErr.takeError())
231report_fatal_error(std::move(Err));
232 std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
233
234WriteBitcodeToFile(TheModule, *Stream->OS,
235/*ShouldPreserveUseListOrder=*/true);
236}
237
238std::unique_ptr<Module>loadModuleForTwoRounds(BitcodeModule &OrigModule,
239unsigned Task,
240LLVMContext &Context,
241ArrayRef<StringRef> IRFiles) {
242LLVM_DEBUG(dbgs() <<"Loading module: " << OrigModule.getModuleIdentifier()
243 <<" in Task " << Task <<"\n");
244auto FileBuffer =MemoryBuffer::getMemBuffer(
245 IRFiles[Task],"in-memory IR file",/*RequiresNullTerminator=*/false);
246auto RestoredModule =parseBitcodeFile(*FileBuffer, Context);
247if (!RestoredModule)
248report_fatal_error(
249Twine("Failed to parse optimized bitcode loaded for Task: ") +
250Twine(Task) +"\n");
251
252// Restore the original module identifier.
253 (*RestoredModule)->setModuleIdentifier(OrigModule.getModuleIdentifier());
254return std::move(*RestoredModule);
255}
256
257Expected<stable_hash>mergeCodeGenData(ArrayRef<StringRef> ObjFiles) {
258OutlinedHashTreeRecord GlobalOutlineRecord;
259StableFunctionMapRecord GlobalStableFunctionMapRecord;
260stable_hash CombinedHash = 0;
261for (auto File : ObjFiles) {
262if (File.empty())
263continue;
264 std::unique_ptr<MemoryBuffer> Buffer =MemoryBuffer::getMemBuffer(
265 File,"in-memory object file",/*RequiresNullTerminator=*/false);
266Expected<std::unique_ptr<object::ObjectFile>> BinOrErr =
267object::ObjectFile::createObjectFile(Buffer->getMemBufferRef());
268if (!BinOrErr)
269return BinOrErr.takeError();
270
271 std::unique_ptr<object::ObjectFile> &Obj = BinOrErr.get();
272if (auto E =CodeGenDataReader::mergeFromObjectFile(
273 Obj.get(), GlobalOutlineRecord, GlobalStableFunctionMapRecord,
274 &CombinedHash))
275return E;
276 }
277
278 GlobalStableFunctionMapRecord.finalize();
279
280if (!GlobalOutlineRecord.empty())
281cgdata::publishOutlinedHashTree(std::move(GlobalOutlineRecord.HashTree));
282if (!GlobalStableFunctionMapRecord.empty())
283cgdata::publishStableFunctionMap(
284 std::move(GlobalStableFunctionMapRecord.FunctionMap));
285
286return CombinedHash;
287}
288
289}// end namespace cgdata
290
291}// end namespace llvm
const
aarch64 promote const
Definition:AArch64PromoteConstant.cpp:230
BitcodeWriter.h
Caching.h
CodeGenDataReader.h
getCGDataErrString
static std::string getCGDataErrString(cgdata_error Err, const std::string &ErrMsg="")
Definition:CodeGenData.cpp:42
CodeGenDataThinLTOTwoRounds
cl::opt< bool > CodeGenDataThinLTOTwoRounds("codegen-data-thinlto-two-rounds", cl::init(false), cl::Hidden, cl::desc("Enable two-round ThinLTO code generation. The first round " "emits codegen data, while the second round uses the emitted " "codegen data for further optimizations."))
CodeGenDataUsePath
cl::opt< std::string > CodeGenDataUsePath("codegen-data-use-path", cl::init(""), cl::Hidden, cl::desc("File path to where .cgdata file is read"))
CodeGenDataGenerate
cl::opt< bool > CodeGenDataGenerate("codegen-data-generate", cl::init(false), cl::Hidden, cl::desc("Emit CodeGen Data into custom sections"))
CodeGenData.inc
CommandLine.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
FileSystem.h
H
#define H(x, y, z)
Definition:MD5.cpp:57
ObjectFile.h
OutlinedHashTreeRecord.h
Path.h
name
static const char * name
Definition:SMEABIPass.cpp:46
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
StableFunctionMapRecord.h
WithColor.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::BitcodeModule
Represents a module in a bitcode file.
Definition:BitcodeReader.h:101
llvm::BitcodeModule::getModuleIdentifier
StringRef getModuleIdentifier() const
Definition:BitcodeReader.h:136
llvm::CGDataError
Definition:CodeGenData.h:66
llvm::CGDataError::ID
static char ID
Definition:CodeGenData.h:98
llvm::CGDataError::message
std::string message() const override
Return the error message as a string.
Definition:CodeGenData.cpp:98
llvm::CodeGenDataReader::create
static Expected< std::unique_ptr< CodeGenDataReader > > create(const Twine &Path, vfs::FileSystem &FS)
Factory method to create an appropriately typed reader for the given codegen data file path and file ...
Definition:CodeGenDataReader.cpp:116
llvm::CodeGenDataReader::mergeFromObjectFile
static Error mergeFromObjectFile(const object::ObjectFile *Obj, OutlinedHashTreeRecord &GlobalOutlineRecord, StableFunctionMapRecord &GlobalFunctionMapRecord, stable_hash *CombinedHash=nullptr)
Extract the cgdata embedded in sections from the given object file and merge them into the GlobalOutl...
Definition:CodeGenDataReader.cpp:33
llvm::CodeGenData
Definition:CodeGenData.h:111
llvm::CodeGenData::getInstance
static CodeGenData & getInstance()
Definition:CodeGenData.cpp:146
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::isA
bool isA() const
Check whether one error is a subclass of another.
Definition:Error.h:247
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition:Error.h:578
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::MemoryBuffer::getMemBuffer
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Definition:MemoryBuffer.cpp:129
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition:Module.h:65
llvm::Module::getModuleIdentifier
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition:Module.h:268
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::Triple::ObjectFormatType
ObjectFormatType
Definition:Triple.h:307
llvm::Triple::MachO
@ MachO
Definition:Triple.h:314
llvm::Triple::COFF
@ COFF
Definition:Triple.h:310
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::WithColor::warning
static raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
Definition:WithColor.cpp:85
llvm::WithColor::note
static raw_ostream & note()
Convenience method for printing "note: " to stderr.
Definition:WithColor.cpp:87
llvm::cl::opt
Definition:CommandLine.h:1423
llvm::object::ObjectFile::createObjectFile
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition:ObjectFile.cpp:209
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition:raw_ostream.h:661
uint64_t
llvm::IndexedCGData::Version2
@ Version2
Definition:CodeGenData.h:283
llvm::IndexedCGData::CurrentVersion
@ CurrentVersion
Definition:CodeGenData.h:284
llvm::IndexedCGData::Magic
const uint64_t Magic
Definition:CodeGenData.h:276
llvm::cgdata::mergeCodeGenData
Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
Definition:CodeGenData.cpp:257
llvm::cgdata::publishOutlinedHashTree
void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)
Definition:CodeGenData.h:190
llvm::cgdata::warn
void warn(Error E, StringRef Whence="")
Definition:CodeGenData.cpp:216
llvm::cgdata::publishStableFunctionMap
void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)
Definition:CodeGenData.h:195
llvm::cgdata::saveModuleForTwoRounds
void saveModuleForTwoRounds(const Module &TheModule, unsigned Task, AddStreamFn AddStream)
Save TheModule before the first codegen round.
Definition:CodeGenData.cpp:224
llvm::cgdata::loadModuleForTwoRounds
std::unique_ptr< Module > loadModuleForTwoRounds(BitcodeModule &OrigModule, unsigned Task, LLVMContext &Context, ArrayRef< StringRef > IRFiles)
Load the optimized bitcode module for the second codegen round.
Definition:CodeGenData.cpp:238
llvm::cl::Hidden
@ Hidden
Definition:CommandLine.h:137
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm::vfs::getRealFileSystem
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
Definition:VirtualFileSystem.cpp:399
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::parseBitcodeFile
Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
Definition:BitcodeReader.cpp:8721
llvm::WriteBitcodeToFile
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
Definition:BitcodeWriter.cpp:5371
llvm::handleAllErrors
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
llvm::AddStreamFn
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
llvm::cgdata_error
cgdata_error
Definition:CodeGenData.h:52
llvm::cgdata_error::unsupported_version
@ unsupported_version
llvm::cgdata_error::bad_magic
@ bad_magic
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167
llvm::cgdata_category
const std::error_category & cgdata_category()
Definition:CodeGenData.cpp:93
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition:raw_ostream.cpp:907
llvm::CGDataSectKind
CGDataSectKind
Definition:CodeGenData.h:32
llvm::getCodeGenDataSectionName
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Definition:CodeGenData.cpp:127
llvm::IndexedCGData::Header
Definition:CodeGenData.h:288
llvm::IndexedCGData::Header::readFromBuffer
static Expected< Header > readFromBuffer(const unsigned char *Curr)
Definition:CodeGenData.cpp:176
llvm::OutlinedHashTreeRecord
Definition:OutlinedHashTreeRecord.h:35
llvm::OutlinedHashTreeRecord::empty
bool empty() const
Definition:OutlinedHashTreeRecord.h:57
llvm::OutlinedHashTreeRecord::HashTree
std::unique_ptr< OutlinedHashTree > HashTree
Definition:OutlinedHashTreeRecord.h:36
llvm::StableFunctionMapRecord
Definition:StableFunctionMapRecord.h:25
llvm::StableFunctionMapRecord::empty
bool empty() const
Definition:StableFunctionMapRecord.h:60
llvm::StableFunctionMapRecord::finalize
void finalize(bool SkipTrim=false)
Finalize the stable function map by trimming content.
Definition:StableFunctionMapRecord.h:52
llvm::StableFunctionMapRecord::FunctionMap
std::unique_ptr< StableFunctionMap > FunctionMap
Definition:StableFunctionMapRecord.h:26
llvm::cl::desc
Definition:CommandLine.h:409

Generated on Fri Jul 18 2025 10:26:08 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp