LLVM: lib/CGData/CodeGenData.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
22
23#define DEBUG_TYPE "cg-data"
24
25using namespace llvm;
26using namespace cgdata;
27
30 cl::desc("Emit CodeGen Data into custom sections"));
33 cl::desc("File path to where .cgdata file is read"));
34
35namespace llvm {
38 cl::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}
42
44 const std::string &ErrMsg = "") {
45 std::string Msg;
47
48 switch (Err) {
50 OS << "success";
51 break;
53 OS << "end of File";
54 break;
56 OS << "invalid codegen data (bad magic)";
57 break;
59 OS << "invalid codegen data (file header is corrupt)";
60 break;
62 OS << "empty codegen data";
63 break;
65 OS << "malformed codegen data";
66 break;
68 OS << "unsupported codegen data version";
69 break;
70 }
71
72
73 if (!ErrMsg.empty())
74 OS << ": " << ErrMsg;
75
76 return OS.str();
77}
78
79namespace {
80
81
82
83
84class CGDataErrorCategoryType : public std::error_category {
85 const char *name() const noexcept override { return "llvm.cgdata"; }
86
87 std::string message(int IE) const override {
89 }
90};
91
92}
93
95 static CGDataErrorCategoryType ErrorCategory;
96 return ErrorCategory;
97}
98
102
104
105namespace {
106
107const char *CodeGenDataSectNameCommon[] = {
108#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
109 SectNameCommon,
111};
112
113const char *CodeGenDataSectNameCoff[] = {
114#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
115 SectNameCoff,
117};
118
119const char *CodeGenDataSectNamePrefix[] = {
120#define CG_DATA_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Prefix,
122};
123
124}
125
126namespace llvm {
127
130 bool AddSegmentInfo) {
131 std::string SectName;
132
134 SectName = CodeGenDataSectNamePrefix[CGSK];
135
137 SectName += CodeGenDataSectNameCoff[CGSK];
138 else
139 SectName += CodeGenDataSectNameCommon[CGSK];
140
141 return SectName;
142}
143
144std::unique_ptr CodeGenData::Instance = nullptr;
145std::once_flag CodeGenData::OnceFlag;
146
148 std::call_once(CodeGenData::OnceFlag, []() {
149 Instance = std::unique_ptr(new CodeGenData());
150
152 Instance->EmitCGData = true;
154
155
156
157
160 if (Error E = ReaderOrErr.takeError()) {
162 return;
163 }
164
165 auto Reader = ReaderOrErr->get();
166 if (Reader->hasOutlinedHashTree())
167 Instance->publishOutlinedHashTree(Reader->releaseOutlinedHashTree());
168 if (Reader->hasStableFunctionMap())
169 Instance->publishStableFunctionMap(Reader->releaseStableFunctionMap());
170 }
171 });
172 return *Instance;
173}
174
176
179
180 static_assert(std::is_standard_layout_vllvm::IndexedCGData::Header,
181 "The header should be standard layout type since we use offset "
182 "of fields to read.");
191
193 "Please update the offset computation below if a new field has "
194 "been added to the header.");
195 H.OutlinedHashTreeOffset =
197 if (H.Version >= 2)
198 H.StableFunctionMapOffset =
200
201 return H;
202}
203
204}
205
207
210 if (!Whence.empty())
211 errs() << Whence << ": ";
212 errs() << Message << "\n";
213 if (!Hint.empty())
215}
216
224
228 << " in Task " << Task << "\n");
233 std::unique_ptr &Stream = *StreamOrErr;
234
236 true);
237
238 if (Error Err = Stream->commit())
240}
241
243 unsigned Task,
247 << " in Task " << Task << "\n");
249 IRFiles[Task], "in-memory IR file", false);
250 auto RestoredModule = parseBitcodeFile(*FileBuffer, Context);
251 if (!RestoredModule)
253 Twine("Failed to parse optimized bitcode loaded for Task: ") +
254 Twine(Task) + "\n");
255
256
257 (*RestoredModule)->setModuleIdentifier(OrigModule.getModuleIdentifier());
258 return std::move(*RestoredModule);
259}
260
265 for (auto File : ObjFiles) {
266 if (File.empty())
267 continue;
269 File, "in-memory object file", false);
272 if (!BinOrErr)
274
275 std::unique_ptrobject::ObjectFile &Obj = BinOrErr.get();
277 Obj.get(), GlobalOutlineRecord, GlobalStableFunctionMapRecord,
278 &CombinedHash))
279 return E;
280 }
281
282 GlobalStableFunctionMapRecord.finalize();
283
284 if (!GlobalOutlineRecord.empty())
286 if (!GlobalStableFunctionMapRecord.empty())
288 std::move(GlobalStableFunctionMapRecord.FunctionMap));
289
290 return CombinedHash;
291}
292
293}
294
295}
static std::string getCGDataErrString(cgdata_error Err, const std::string &ErrMsg="")
Definition CodeGenData.cpp:43
static cl::opt< std::string > CodeGenDataUsePath("codegen-data-use-path", cl::init(""), cl::Hidden, cl::desc("File path to where .cgdata file is read"))
static cl::opt< bool > CodeGenDataGenerate("codegen-data-generate", cl::init(false), cl::Hidden, cl::desc("Emit CodeGen Data into custom sections"))
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents a module in a bitcode file.
StringRef getModuleIdentifier() const
std::string message() const override
Return the error message as a string.
Definition CodeGenData.cpp:99
static LLVM_ABI 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 ...
static LLVM_ABI 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...
static LLVM_ABI CodeGenData & getInstance()
Definition CodeGenData.cpp:147
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
This is an important class for using LLVM in a threaded context.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
A Module instance is used to store all the information related to an LLVM module.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static LLVM_ABI raw_ostream & warning()
Convenience method for printing "warning: " to stderr.
static LLVM_ABI raw_ostream & note()
Convenience method for printing "note: " to stderr.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
LLVM_ABI Expected< stable_hash > mergeCodeGenData(ArrayRef< StringRef > ObjectFiles)
Merge the codegen data from the scratch objects ObjectFiles from the first codegen round.
Definition CodeGenData.cpp:261
void publishOutlinedHashTree(std::unique_ptr< OutlinedHashTree > HashTree)
LLVM_ABI void warn(Error E, StringRef Whence="")
Definition CodeGenData.cpp:217
void publishStableFunctionMap(std::unique_ptr< StableFunctionMap > FunctionMap)
LLVM_ABI void saveModuleForTwoRounds(const Module &TheModule, unsigned Task, AddStreamFn AddStream)
Save TheModule before the first codegen round.
Definition CodeGenData.cpp:225
LLVM_ABI 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:242
initializer< Ty > init(const Ty &Val)
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
LLVM_ABI 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.
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."))
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
uint64_t stable_hash
An opaque object representing a stable hash code.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI const std::error_category & cgdata_category()
Definition CodeGenData.cpp:94
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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.
LLVM_ABI std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Definition CodeGenData.cpp:128
std::unique_ptr< OutlinedHashTree > HashTree
The structure of the serialized stable function map is as follows:
void finalize(bool SkipTrim=false)
Finalize the stable function map by trimming content.
std::unique_ptr< StableFunctionMap > FunctionMap