1515#include " llvm/CGData/CodeGenDataReader.h"
1616#include " llvm/CGData/OutlinedHashTreeRecord.h"
1717#include " llvm/Object/ObjectFile.h"
18+ #include " llvm/Support/Caching.h"
1819#include " llvm/Support/CommandLine.h"
1920#include " llvm/Support/FileSystem.h"
2021#include " llvm/Support/Path.h"
@@ -37,9 +38,6 @@ cl::opt<bool> CodeGenDataThinLTOTwoRounds(
3738 " emits codegen data, while the second round uses the emitted "
3839 " codegen data for further optimizations." ));
3940
40- // Path to where the optimized bitcodes are saved and restored for ThinLTO.
41- static SmallString<128 > CodeGenDataThinLTOTwoRoundsPath;
42-
4341static std::string getCGDataErrString (cgdata_error Err,
4442 const std::string &ErrMsg = " " ) {
4543 std::string Msg;
@@ -224,59 +222,78 @@ void warn(Error E, StringRef Whence) {
224222 }
225223}
226224
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) {
234227 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+ }
238257}
239258
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 );
249271}
250272
251273std::unique_ptr<Module> loadModuleForTwoRounds (BitcodeModule &OrigModule,
252274 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 );
262281 auto RestoredModule = parseBitcodeFile (*FileBuffer, Context);
263282 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 " );
266286
267287 // Restore the original module identifier.
268288 (*RestoredModule)->setModuleIdentifier (OrigModule.getModuleIdentifier ());
269289 return std::move (*RestoredModule);
270290}
271291
272- Error mergeCodeGenData (
273- const std::unique_ptr<std::vector<llvm::SmallString<0 >>> InputFiles) {
274-
292+ Error mergeCodeGenData (ArrayRef<StringRef> CGFiles, stable_hash *CombinedHash) {
275293 OutlinedHashTreeRecord GlobalOutlineRecord;
276- for (auto &InputFile : *(InputFiles) ) {
277- if (InputFile .empty ())
294+ for (auto File : CGFiles ) {
295+ if (File .empty ())
278296 continue ;
279- StringRef File = StringRef (InputFile.data (), InputFile.size ());
280297 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer (
281298 File, " in-memory object file" , /* RequiresNullTerminator=*/ false );
282299 Expected<std::unique_ptr<object::ObjectFile>> BinOrErr =
@@ -285,8 +302,8 @@ Error mergeCodeGenData(
285302 return BinOrErr.takeError ();
286303
287304 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 ))
290307 return E;
291308 }
292309
0 commit comments