Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
CodeGenDataReader.cpp
Go to the documentation of this file.
1//===- CodeGenDataReader.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 reading codegen data.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/CGData/CodeGenDataReader.h"
14#include "llvm/CGData/OutlinedHashTreeRecord.h"
15#include "llvm/Object/ObjectFile.h"
16#include "llvm/Support/MemoryBuffer.h"
17
18#define DEBUG_TYPE "cg-data-reader"
19
20using namespacellvm;
21
22namespacellvm {
23
24staticExpected<std::unique_ptr<MemoryBuffer>>
25setupMemoryBuffer(constTwine &Filename,vfs::FileSystem &FS) {
26auto BufferOrErr = Filename.str() =="-" ?MemoryBuffer::getSTDIN()
27 : FS.getBufferForFile(Filename);
28if (std::error_code EC = BufferOrErr.getError())
29returnerrorCodeToError(EC);
30return std::move(BufferOrErr.get());
31}
32
33ErrorCodeGenDataReader::mergeFromObjectFile(
34constobject::ObjectFile *Obj,OutlinedHashTreeRecord &GlobalOutlineRecord,
35StableFunctionMapRecord &GlobalFunctionMapRecord,
36stable_hash *CombinedHash) {
37Triple TT = Obj->makeTriple();
38auto CGOutlineName =
39getCodeGenDataSectionName(CG_outline, TT.getObjectFormat(),false);
40auto CGMergeName =
41getCodeGenDataSectionName(CG_merge, TT.getObjectFormat(),false);
42
43auto processSectionContents = [&](constStringRef &Name,
44constStringRef &Contents) {
45if (Name != CGOutlineName &&Name != CGMergeName)
46return;
47if (CombinedHash)
48 *CombinedHash =stable_hash_combine(*CombinedHash,xxh3_64bits(Contents));
49auto *Data =reinterpret_cast<constunsignedchar *>(Contents.data());
50auto *EndData =Data + Contents.size();
51// In case dealing with an executable that has concatenated cgdata,
52// we want to merge them into a single cgdata.
53// Although it's not a typical workflow, we support this scenario
54// by looping over all data in the sections.
55if (Name == CGOutlineName) {
56while (Data != EndData) {
57OutlinedHashTreeRecord LocalOutlineRecord;
58 LocalOutlineRecord.deserialize(Data);
59 GlobalOutlineRecord.merge(LocalOutlineRecord);
60 }
61 }elseif (Name == CGMergeName) {
62while (Data != EndData) {
63StableFunctionMapRecord LocalFunctionMapRecord;
64 LocalFunctionMapRecord.deserialize(Data);
65 GlobalFunctionMapRecord.merge(LocalFunctionMapRecord);
66 }
67 }
68 };
69
70for (auto &Section : Obj->sections()) {
71Expected<StringRef> NameOrErr = Section.getName();
72if (!NameOrErr)
73return NameOrErr.takeError();
74Expected<StringRef> ContentsOrErr = Section.getContents();
75if (!ContentsOrErr)
76return ContentsOrErr.takeError();
77 processSectionContents(*NameOrErr, *ContentsOrErr);
78 }
79
80returnError::success();
81}
82
83ErrorIndexedCodeGenDataReader::read() {
84using namespacesupport;
85
86// The smallest header with the version 1 is 24 bytes.
87// Do not update this value even with the new version of the header.
88constunsigned MinHeaderSize = 24;
89if (DataBuffer->getBufferSize() < MinHeaderSize)
90returnerror(cgdata_error::bad_header);
91
92auto *Start =
93reinterpret_cast<constunsignedchar *>(DataBuffer->getBufferStart());
94auto *End =
95reinterpret_cast<constunsignedchar *>(DataBuffer->getBufferEnd());
96if (auto E =IndexedCGData::Header::readFromBuffer(Start).moveInto(Header))
97return E;
98
99if (hasOutlinedHashTree()) {
100constunsignedchar *Ptr = Start + Header.OutlinedHashTreeOffset;
101if (Ptr >=End)
102returnerror(cgdata_error::eof);
103HashTreeRecord.deserialize(Ptr);
104 }
105if (hasStableFunctionMap()) {
106constunsignedchar *Ptr = Start + Header.StableFunctionMapOffset;
107if (Ptr >=End)
108returnerror(cgdata_error::eof);
109FunctionMapRecord.deserialize(Ptr);
110 }
111
112returnsuccess();
113}
114
115Expected<std::unique_ptr<CodeGenDataReader>>
116CodeGenDataReader::create(constTwine &Path,vfs::FileSystem &FS) {
117// Set up the buffer to read.
118auto BufferOrError =setupMemoryBuffer(Path, FS);
119if (Error E = BufferOrError.takeError())
120return std::move(E);
121returnCodeGenDataReader::create(std::move(BufferOrError.get()));
122}
123
124Expected<std::unique_ptr<CodeGenDataReader>>
125CodeGenDataReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
126if (Buffer->getBufferSize() == 0)
127return make_error<CGDataError>(cgdata_error::empty_cgdata);
128
129 std::unique_ptr<CodeGenDataReader> Reader;
130// Create the reader.
131if (IndexedCodeGenDataReader::hasFormat(*Buffer))
132 Reader = std::make_unique<IndexedCodeGenDataReader>(std::move(Buffer));
133elseif (TextCodeGenDataReader::hasFormat(*Buffer))
134 Reader = std::make_unique<TextCodeGenDataReader>(std::move(Buffer));
135else
136return make_error<CGDataError>(cgdata_error::malformed);
137
138// Initialize the reader and return the result.
139if (Error E = Reader->read())
140return std::move(E);
141
142return std::move(Reader);
143}
144
145boolIndexedCodeGenDataReader::hasFormat(constMemoryBuffer &DataBuffer) {
146using namespacesupport;
147if (DataBuffer.getBufferSize() <sizeof(IndexedCGData::Magic))
148returnfalse;
149
150uint64_t Magic = endian::read<uint64_t, llvm::endianness::little, aligned>(
151 DataBuffer.getBufferStart());
152// Verify that it's magical.
153return Magic ==IndexedCGData::Magic;
154}
155
156boolTextCodeGenDataReader::hasFormat(constMemoryBuffer &Buffer) {
157// Verify that this really looks like plain ASCII text by checking a
158// 'reasonable' number of characters (up to the magic size).
159StringRef Prefix = Buffer.getBuffer().take_front(sizeof(uint64_t));
160returnllvm::all_of(Prefix, [](char c) {return isPrint(c) || isSpace(c); });
161}
162ErrorTextCodeGenDataReader::read() {
163using namespacesupport;
164
165// Parse the custom header line by line.
166for (; !Line.is_at_eof(); ++Line) {
167// Skip empty or whitespace-only lines
168if (Line->trim().empty())
169continue;
170
171if (!Line->starts_with(":"))
172break;
173StringRef Str = Line->drop_front().rtrim();
174if (Str.equals_insensitive("outlined_hash_tree"))
175 DataKind |=CGDataKind::FunctionOutlinedHashTree;
176elseif (Str.equals_insensitive("stable_function_map"))
177 DataKind |=CGDataKind::StableFunctionMergingMap;
178else
179returnerror(cgdata_error::bad_header);
180 }
181
182// We treat an empty header (that is a comment # only) as a valid header.
183if (Line.is_at_eof()) {
184if (DataKind ==CGDataKind::Unknown)
185returnError::success();
186returnerror(cgdata_error::bad_header);
187 }
188
189// The YAML docs follow after the header.
190constchar *Pos = Line->data();
191size_tSize =reinterpret_cast<size_t>(DataBuffer->getBufferEnd()) -
192reinterpret_cast<size_t>(Pos);
193 yaml::Input YOS(StringRef(Pos,Size));
194if (hasOutlinedHashTree())
195HashTreeRecord.deserializeYAML(YOS);
196if (hasStableFunctionMap())
197FunctionMapRecord.deserializeYAML(YOS);
198
199returnError::success();
200}
201}// end namespace llvm
CodeGenDataReader.h
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
End
bool End
Definition:ELF_riscv.cpp:480
MemoryBuffer.h
ObjectFile.h
OutlinedHashTreeRecord.h
error
#define error(X)
Definition:SymbolRecordMapping.cpp:14
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
llvm::CodeGenDataReader::success
Error success()
Clear the current error and return a successful one.
Definition:CodeGenDataReader.h:98
llvm::CodeGenDataReader::HashTreeRecord
OutlinedHashTreeRecord HashTreeRecord
The outlined hash tree that has been read.
Definition:CodeGenDataReader.h:74
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::FunctionMapRecord
StableFunctionMapRecord FunctionMapRecord
The stable function map that has been read. When it's released by.
Definition:CodeGenDataReader.h:78
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::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
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::IndexedCodeGenDataReader::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in binary codegen data format.
Definition:CodeGenDataReader.cpp:145
llvm::IndexedCodeGenDataReader::read
Error read() override
Read the contents including the header.
Definition:CodeGenDataReader.cpp:83
llvm::IndexedCodeGenDataReader::hasStableFunctionMap
bool hasStableFunctionMap() const override
Return true if the header indicates the data has a stable function map.
Definition:CodeGenDataReader.h:131
llvm::IndexedCodeGenDataReader::hasOutlinedHashTree
bool hasOutlinedHashTree() const override
Return true if the header indicates the data has an outlined hash tree.
Definition:CodeGenDataReader.h:126
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition:MemoryBuffer.h:51
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition:MemoryBuffer.h:68
llvm::MemoryBuffer::getBuffer
StringRef getBuffer() const
Definition:MemoryBuffer.h:70
llvm::MemoryBuffer::getSTDIN
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
Definition:MemoryBuffer.cpp:566
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition:MemoryBuffer.h:66
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::starts_with
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition:StringRef.h:265
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition:StringRef.h:609
llvm::StringRef::data
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition:StringRef.h:144
llvm::StringRef::rtrim
StringRef rtrim(char Char) const
Return string with consecutive Char characters starting from the right removed.
Definition:StringRef.h:803
llvm::StringRef::take_front
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition:StringRef.h:580
llvm::StringRef::trim
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition:StringRef.h:815
llvm::TextCodeGenDataReader::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text codegen data format.
Definition:CodeGenDataReader.cpp:156
llvm::TextCodeGenDataReader::hasStableFunctionMap
bool hasStableFunctionMap() const override
Return true if the header indicates the data has a stable function map.
Definition:CodeGenDataReader.h:172
llvm::TextCodeGenDataReader::hasOutlinedHashTree
bool hasOutlinedHashTree() const override
Return true if the header indicates the data has an outlined hash tree.
Definition:CodeGenDataReader.h:166
llvm::TextCodeGenDataReader::read
Error read() override
Read the contents including the header.
Definition:CodeGenDataReader.cpp:162
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition:Triple.h:44
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::line_iterator::is_at_eof
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
Definition:LineIterator.h:60
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition:ObjectFile.h:229
llvm::object::ObjectFile::makeTriple
Triple makeTriple() const
Create a triple from the data in this object file.
Definition:ObjectFile.cpp:109
llvm::object::ObjectFile::sections
section_iterator_range sections() const
Definition:ObjectFile.h:329
llvm::vfs::FileSystem
The virtual file system interface.
Definition:VirtualFileSystem.h:266
uint64_t
llvm::IndexedCGData::Magic
const uint64_t Magic
Definition:CodeGenData.h:276
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::CGDataKind::StableFunctionMergingMap
@ StableFunctionMergingMap
llvm::CGDataKind::Unknown
@ Unknown
llvm::CGDataKind::FunctionOutlinedHashTree
@ FunctionOutlinedHashTree
llvm::setupMemoryBuffer
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
Definition:CodeGenDataReader.cpp:25
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1739
llvm::xxh3_64bits
uint64_t xxh3_64bits(ArrayRef< uint8_t > data)
Definition:xxhash.cpp:553
llvm::cgdata_error::eof
@ eof
llvm::cgdata_error::malformed
@ malformed
llvm::cgdata_error::empty_cgdata
@ empty_cgdata
llvm::cgdata_error::bad_header
@ bad_header
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition:Error.cpp:111
llvm::stable_hash_combine
stable_hash stable_hash_combine(ArrayRef< stable_hash > Buffer)
Definition:StableHashing.h:30
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::getCodeGenDataSectionName
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Definition:CodeGenData.cpp:127
llvm::IndexedCGData::Header::StableFunctionMapOffset
uint64_t StableFunctionMapOffset
Definition:CodeGenData.h:293
llvm::IndexedCGData::Header::readFromBuffer
static Expected< Header > readFromBuffer(const unsigned char *Curr)
Definition:CodeGenData.cpp:176
llvm::IndexedCGData::Header::OutlinedHashTreeOffset
uint64_t OutlinedHashTreeOffset
Definition:CodeGenData.h:292
llvm::OutlinedHashTreeRecord
Definition:OutlinedHashTreeRecord.h:35
llvm::OutlinedHashTreeRecord::deserializeYAML
void deserializeYAML(yaml::Input &YIS)
Deserialize the outlined hash tree from a YAML stream.
Definition:OutlinedHashTreeRecord.cpp:105
llvm::OutlinedHashTreeRecord::deserialize
void deserialize(const unsigned char *&Ptr)
Deserialize the outlined hash tree from a raw_ostream.
Definition:OutlinedHashTreeRecord.cpp:74
llvm::OutlinedHashTreeRecord::merge
void merge(const OutlinedHashTreeRecord &Other)
Merge the other outlined hash tree into this one.
Definition:OutlinedHashTreeRecord.h:52
llvm::StableFunctionMapRecord
Definition:StableFunctionMapRecord.h:25
llvm::StableFunctionMapRecord::merge
void merge(const StableFunctionMapRecord &Other)
Merge the stable function map into this one.
Definition:StableFunctionMapRecord.h:55
llvm::StableFunctionMapRecord::deserialize
void deserialize(const unsigned char *&Ptr)
Deserialize the stable function map from a raw_ostream.
Definition:StableFunctionMapRecord.cpp:123
llvm::StableFunctionMapRecord::deserializeYAML
void deserializeYAML(yaml::Input &YIS)
Deserialize the stable function map from a YAML stream.
Definition:StableFunctionMapRecord.cpp:196

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

©2009-2025 Movatter.jp