15
15
#include " llvm/CGData/CodeGenDataReader.h"
16
16
#include " llvm/CGData/OutlinedHashTreeRecord.h"
17
17
#include " llvm/Object/ObjectFile.h"
18
+ #include " llvm/Support/Caching.h"
18
19
#include " llvm/Support/CommandLine.h"
19
20
#include " llvm/Support/FileSystem.h"
20
21
#include " llvm/Support/Path.h"
@@ -37,9 +38,6 @@ cl::opt<bool> CodeGenDataThinLTOTwoRounds(
37
38
" emits codegen data, while the second round uses the emitted "
38
39
" codegen data for further optimizations." ));
39
40
40
- // Path to where the optimized bitcodes are saved and restored for ThinLTO.
41
- static SmallString<128 > CodeGenDataThinLTOTwoRoundsPath;
42
-
43
41
static std::string getCGDataErrString (cgdata_error Err,
44
42
const std::string &ErrMsg = " " ) {
45
43
std::string Msg;
@@ -224,59 +222,78 @@ void warn(Error E, StringRef Whence) {
224
222
}
225
223
}
226
224
227
- static std::string getPath (StringRef Dir, unsigned Task) {
228
- llvm::SmallString<128 > Path (Dir);
229
- llvm::sys::path::append (Path, llvm::Twine (Task) + " .saved_copy.bc" );
230
- return std::string (Path);
231
- }
232
-
233
- void initializeTwoCodegenRounds () {
225
+ void initializeTwoCodegenRounds (StreamCacheData &CG, StreamCacheData &IR,
226
+ const FileCache &OrigCache) {
234
227
assert (CodeGenDataThinLTOTwoRounds);
235
- if (auto EC = llvm::sys::fs::createUniqueDirectory (
236
- " cgdata" , CodeGenDataThinLTOTwoRoundsPath))
237
- report_fatal_error (Twine (" Failed to create directory: " ) + EC.message ());
228
+ CG.AddStream = [&](size_t Task, const Twine &ModuleName) {
229
+ return std::make_unique<CachedFileStream>(
230
+ std::make_unique<raw_svector_ostream>(CG.Outputs [Task]));
231
+ };
232
+ IR.AddStream = [&](size_t Task, const Twine &ModuleName) {
233
+ return std::make_unique<CachedFileStream>(
234
+ std::make_unique<raw_svector_ostream>(IR.Outputs [Task]));
235
+ };
236
+
237
+ if (OrigCache.isValid ()) {
238
+ auto CGCacheOrErr =
239
+ localCache (" ThinLTO" , " CG" , OrigCache.getCacheDirectoryPath (),
240
+ [&](size_t Task, const Twine &ModuleName,
241
+ std::unique_ptr<MemoryBuffer> MB) {
242
+ CG.Files [Task] = std::move (MB);
243
+ });
244
+ if (Error Err = CGCacheOrErr.takeError ())
245
+ report_fatal_error (std::move (Err));
246
+ CG.Cache = std::move (*CGCacheOrErr);
247
+ auto IRCacheOrErr =
248
+ localCache (" ThinLTO" , " IR" , OrigCache.getCacheDirectoryPath (),
249
+ [&](size_t Task, const Twine &NoduleName,
250
+ std::unique_ptr<MemoryBuffer> MB) {
251
+ IR.Files [Task] = std::move (MB);
252
+ });
253
+ if (Error Err = IRCacheOrErr.takeError ())
254
+ report_fatal_error (std::move (Err));
255
+ IR.Cache = std::move (*IRCacheOrErr);
256
+ }
238
257
}
239
258
240
- void saveModuleForTwoRounds (const Module &TheModule, unsigned Task) {
241
- assert (sys::fs::is_directory (CodeGenDataThinLTOTwoRoundsPath));
242
- std::string Path = getPath (CodeGenDataThinLTOTwoRoundsPath, Task);
243
- std::error_code EC;
244
- raw_fd_ostream OS (Path, EC, sys::fs::OpenFlags::OF_None);
245
- if (EC)
246
- report_fatal_error (Twine (" Failed to open " ) + Path +
247
- " to save optimized bitcode: " + EC.message ());
248
- WriteBitcodeToFile (TheModule, OS, /* ShouldPreserveUseListOrder=*/ true );
259
+ void saveModuleForTwoRounds (const Module &TheModule, unsigned Task,
260
+ AddStreamFn AddStream) {
261
+ LLVM_DEBUG (dbgs () << " Saving module: " << TheModule.getModuleIdentifier ()
262
+ << " in Task " << Task << " \n " );
263
+ Expected<std::unique_ptr<CachedFileStream>> StreamOrErr =
264
+ AddStream (Task, TheModule.getModuleIdentifier ());
265
+ if (Error Err = StreamOrErr.takeError ())
266
+ report_fatal_error (std::move (Err));
267
+ std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
268
+
269
+ WriteBitcodeToFile (TheModule, *Stream->OS ,
270
+ /* ShouldPreserveUseListOrder=*/ true );
249
271
}
250
272
251
273
std::unique_ptr<Module> loadModuleForTwoRounds (BitcodeModule &OrigModule,
252
274
unsigned Task,
253
- LLVMContext &Context) {
254
- assert (sys::fs::is_directory (CodeGenDataThinLTOTwoRoundsPath));
255
- std::string Path = getPath (CodeGenDataThinLTOTwoRoundsPath, Task);
256
- auto FileOrError = MemoryBuffer::getFile (Path);
257
- if (auto EC = FileOrError.getError ())
258
- report_fatal_error (Twine (" Failed to open " ) + Path +
259
- " to load optimized bitcode: " + EC.message ());
260
-
261
- std::unique_ptr<MemoryBuffer> FileBuffer = std::move (*FileOrError);
275
+ LLVMContext &Context,
276
+ ArrayRef<StringRef> IRFiles) {
277
+ LLVM_DEBUG (dbgs () << " Loading module: " << OrigModule.getModuleIdentifier ()
278
+ << " in Task " << Task << " \n " );
279
+ std::unique_ptr<MemoryBuffer> FileBuffer = MemoryBuffer::getMemBuffer (
280
+ IRFiles[Task], " in-memory IR file" , /* RequiresNullTerminator=*/ false );
262
281
auto RestoredModule = parseBitcodeFile (*FileBuffer, Context);
263
282
if (!RestoredModule)
264
- report_fatal_error (Twine (" Failed to parse optimized bitcode loaded from " ) +
265
- Path + " \n " );
283
+ report_fatal_error (
284
+ Twine (" Failed to parse optimized bitcode loaded for Task: " ) +
285
+ Twine (Task) + " \n " );
266
286
267
287
// Restore the original module identifier.
268
288
(*RestoredModule)->setModuleIdentifier (OrigModule.getModuleIdentifier ());
269
289
return std::move (*RestoredModule);
270
290
}
271
291
272
- Error mergeCodeGenData (
273
- const std::unique_ptr<std::vector<llvm::SmallString<0 >>> InputFiles) {
274
-
292
+ Error mergeCodeGenData (ArrayRef<StringRef> CGFiles, stable_hash *CombinedHash) {
275
293
OutlinedHashTreeRecord GlobalOutlineRecord;
276
- for (auto &InputFile : *(InputFiles) ) {
277
- if (InputFile .empty ())
294
+ for (auto File : CGFiles ) {
295
+ if (File .empty ())
278
296
continue ;
279
- StringRef File = StringRef (InputFile.data (), InputFile.size ());
280
297
std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer (
281
298
File, " in-memory object file" , /* RequiresNullTerminator=*/ false );
282
299
Expected<std::unique_ptr<object::ObjectFile>> BinOrErr =
@@ -285,8 +302,8 @@ Error mergeCodeGenData(
285
302
return BinOrErr.takeError ();
286
303
287
304
std::unique_ptr<object::ObjectFile> &Obj = BinOrErr.get ();
288
- if (auto E = CodeGenDataReader::mergeFromObjectFile (Obj. get (),
289
- GlobalOutlineRecord))
305
+ if (auto E = CodeGenDataReader::mergeFromObjectFile (
306
+ Obj. get (), GlobalOutlineRecord, CombinedHash ))
290
307
return E;
291
308
}
292
309
0 commit comments