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,45 @@ 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 () {
234- assert (CodeGenDataThinLTOTwoRounds);
235- if (auto EC = llvm::sys::fs::createUniqueDirectory (
236- " cgdata" , CodeGenDataThinLTOTwoRoundsPath))
237- report_fatal_error (Twine (" Failed to create directory: " ) + EC.message ());
238- }
239-
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 );
225+ void saveModuleForTwoRounds (const Module &TheModule, unsigned Task,
226+ AddStreamFn AddStream) {
227+ LLVM_DEBUG (dbgs () << " Saving module: " << TheModule.getModuleIdentifier ()
228+ << " in Task " << Task << " \n " );
229+ Expected<std::unique_ptr<CachedFileStream>> StreamOrErr =
230+ AddStream (Task, TheModule.getModuleIdentifier ());
231+ if (Error Err = StreamOrErr.takeError ())
232+ report_fatal_error (std::move (Err));
233+ std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
234+
235+ WriteBitcodeToFile (TheModule, *Stream->OS ,
236+ /* ShouldPreserveUseListOrder=*/ true );
249237}
250238
251239std::unique_ptr<Module> loadModuleForTwoRounds (BitcodeModule &OrigModule,
252240 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);
241+ LLVMContext &Context,
242+ ArrayRef<StringRef> IRFiles) {
243+ LLVM_DEBUG (dbgs () << " Loading module: " << OrigModule.getModuleIdentifier ()
244+ << " in Task " << Task << " \n " );
245+ auto FileBuffer = MemoryBuffer::getMemBuffer (
246+ IRFiles[Task], " in-memory IR file" , /* RequiresNullTerminator=*/ false );
262247 auto RestoredModule = parseBitcodeFile (*FileBuffer, Context);
263248 if (!RestoredModule)
264- report_fatal_error (Twine (" Failed to parse optimized bitcode loaded from " ) +
265- Path + " \n " );
249+ report_fatal_error (
250+ Twine (" Failed to parse optimized bitcode loaded for Task: " ) +
251+ Twine (Task) + " \n " );
266252
267253 // Restore the original module identifier.
268254 (*RestoredModule)->setModuleIdentifier (OrigModule.getModuleIdentifier ());
269255 return std::move (*RestoredModule);
270256}
271257
272- Error mergeCodeGenData (
273- const std::unique_ptr<std::vector<llvm::SmallString<0 >>> InputFiles) {
274-
258+ Expected<stable_hash> mergeCodeGenData (ArrayRef<StringRef> ObjFiles) {
275259 OutlinedHashTreeRecord GlobalOutlineRecord;
276- for (auto &InputFile : *(InputFiles)) {
277- if (InputFile.empty ())
260+ stable_hash CombinedHash = 0 ;
261+ for (auto File : ObjFiles) {
262+ if (File.empty ())
278263 continue ;
279- StringRef File = StringRef (InputFile.data (), InputFile.size ());
280264 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer (
281265 File, " in-memory object file" , /* RequiresNullTerminator=*/ false );
282266 Expected<std::unique_ptr<object::ObjectFile>> BinOrErr =
@@ -285,15 +269,15 @@ Error mergeCodeGenData(
285269 return BinOrErr.takeError ();
286270
287271 std::unique_ptr<object::ObjectFile> &Obj = BinOrErr.get ();
288- if (auto E = CodeGenDataReader::mergeFromObjectFile (Obj. get (),
289- GlobalOutlineRecord))
272+ if (auto E = CodeGenDataReader::mergeFromObjectFile (
273+ Obj. get (), GlobalOutlineRecord, &CombinedHash ))
290274 return E;
291275 }
292276
293277 if (!GlobalOutlineRecord.empty ())
294278 cgdata::publishOutlinedHashTree (std::move (GlobalOutlineRecord.HashTree ));
295279
296- return Error::success () ;
280+ return CombinedHash ;
297281}
298282
299283} // end namespace cgdata
0 commit comments