1 //===-LTO.cpp - LLVM Link Time Optimizer ----------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements functions and classes used to support LTO. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/LTO/LTO.h" 15 #include "llvm/Analysis/TargetLibraryInfo.h" 16 #include "llvm/Analysis/TargetTransformInfo.h" 17 #include "llvm/Bitcode/ReaderWriter.h" 18 #include "llvm/CodeGen/Analysis.h" 19 #include "llvm/IR/AutoUpgrade.h" 20 #include "llvm/IR/DiagnosticPrinter.h" 21 #include "llvm/IR/LegacyPassManager.h" 22 #include "llvm/LTO/LTOBackend.h" 23 #include "llvm/Linker/IRMover.h" 24 #include "llvm/Object/ModuleSummaryIndexObjectFile.h" 25 #include "llvm/Support/ManagedStatic.h" 26 #include "llvm/Support/MemoryBuffer.h" 27 #include "llvm/Support/Path.h" 28 #include "llvm/Support/SourceMgr.h" 29 #include "llvm/Support/TargetRegistry.h" 30 #include "llvm/Support/ThreadPool.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include "llvm/Target/TargetMachine.h" 33 #include "llvm/Target/TargetOptions.h" 34 #include "llvm/Transforms/IPO.h" 35 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 36 #include "llvm/Transforms/Utils/SplitModule.h" 37 38 #include <set> 39 40 using namespace llvm; 41 using namespace lto; 42 using namespace object; 43 44 // Simple helper to load a module from bitcode 45 std::unique_ptr<Module> 46 llvm::loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context, 47 bool Lazy) { 48 SMDiagnostic Err; 49 ErrorOr<std::unique_ptr<Module>> ModuleOrErr(nullptr); 50 if (Lazy) { 51 ModuleOrErr = 52 getLazyBitcodeModule(MemoryBuffer::getMemBuffer(Buffer, false), Context, 53 /* ShouldLazyLoadMetadata */ Lazy); 54 } else { 55 ModuleOrErr = parseBitcodeFile(Buffer, Context); 56 } 57 if (std::error_code EC = ModuleOrErr.getError()) { 58 Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error, 59 EC.message()); 60 Err.print("ThinLTO", errs()); 61 report_fatal_error("Can't load module, abort."); 62 } 63 return std::move(ModuleOrErr.get()); 64 } 65 66 static void thinLTOResolveWeakForLinkerGUID( 67 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 68 DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, 69 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 70 isPrevailing, 71 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 72 recordNewLinkage) { 73 for (auto &S : GVSummaryList) { 74 if (GlobalInvolvedWithAlias.count(S.get())) 75 continue; 76 GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); 77 if (!GlobalValue::isWeakForLinker(OriginalLinkage)) 78 continue; 79 // We need to emit only one of these. The prevailing module will keep it, 80 // but turned into a weak, while the others will drop it when possible. 81 if (isPrevailing(GUID, S.get())) { 82 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) 83 S->setLinkage(GlobalValue::getWeakLinkage( 84 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); 85 } 86 // Alias can't be turned into available_externally. 87 else if (!isa<AliasSummary>(S.get()) && 88 (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) || 89 GlobalValue::isWeakODRLinkage(OriginalLinkage))) 90 S->setLinkage(GlobalValue::AvailableExternallyLinkage); 91 if (S->linkage() != OriginalLinkage) 92 recordNewLinkage(S->modulePath(), GUID, S->linkage()); 93 } 94 } 95 96 // Resolve Weak and LinkOnce values in the \p Index. 97 // 98 // We'd like to drop these functions if they are no longer referenced in the 99 // current module. However there is a chance that another module is still 100 // referencing them because of the import. We make sure we always emit at least 101 // one copy. 102 void llvm::thinLTOResolveWeakForLinkerInIndex( 103 ModuleSummaryIndex &Index, 104 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 105 isPrevailing, 106 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 107 recordNewLinkage) { 108 // We won't optimize the globals that are referenced by an alias for now 109 // Ideally we should turn the alias into a global and duplicate the definition 110 // when needed. 111 DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; 112 for (auto &I : Index) 113 for (auto &S : I.second) 114 if (auto AS = dyn_cast<AliasSummary>(S.get())) 115 GlobalInvolvedWithAlias.insert(&AS->getAliasee()); 116 117 for (auto &I : Index) 118 thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias, 119 isPrevailing, recordNewLinkage); 120 } 121 122 static void thinLTOInternalizeAndPromoteGUID( 123 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 124 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 125 for (auto &S : GVSummaryList) { 126 if (isExported(S->modulePath(), GUID)) { 127 if (GlobalValue::isLocalLinkage(S->linkage())) 128 S->setLinkage(GlobalValue::ExternalLinkage); 129 } else if (!GlobalValue::isLocalLinkage(S->linkage())) 130 S->setLinkage(GlobalValue::InternalLinkage); 131 } 132 } 133 134 // Update the linkages in the given \p Index to mark exported values 135 // as external and non-exported values as internal. 136 void llvm::thinLTOInternalizeAndPromoteInIndex( 137 ModuleSummaryIndex &Index, 138 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 139 for (auto &I : Index) 140 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); 141 } 142 143 Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { 144 std::unique_ptr<InputFile> File(new InputFile); 145 std::string Msg; 146 auto DiagHandler = [](const DiagnosticInfo &DI, void *MsgP) { 147 auto *Msg = reinterpret_cast<std::string *>(MsgP); 148 raw_string_ostream OS(*Msg); 149 DiagnosticPrinterRawOStream DP(OS); 150 DI.print(DP); 151 }; 152 File->Ctx.setDiagnosticHandler(DiagHandler, static_cast<void *>(&Msg)); 153 154 ErrorOr<std::unique_ptr<object::IRObjectFile>> IRObj = 155 IRObjectFile::create(Object, File->Ctx); 156 if (!Msg.empty()) 157 return make_error<StringError>(Msg, inconvertibleErrorCode()); 158 if (!IRObj) 159 return errorCodeToError(IRObj.getError()); 160 File->Obj = std::move(*IRObj); 161 162 File->Ctx.setDiagnosticHandler(nullptr, nullptr); 163 164 return std::move(File); 165 } 166 167 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, 168 Config &Conf) 169 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), 170 Ctx(Conf), CombinedModule(llvm::make_unique<Module>("ld-temp.o", Ctx)), 171 Mover(*CombinedModule) {} 172 173 LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) { 174 if (!Backend) 175 this->Backend = createInProcessThinBackend(thread::hardware_concurrency()); 176 } 177 178 LTO::LTO(Config Conf, ThinBackend Backend, 179 unsigned ParallelCodeGenParallelismLevel) 180 : Conf(std::move(Conf)), 181 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf), 182 ThinLTO(Backend) {} 183 184 // Add the given symbol to the GlobalResolutions map, and resolve its partition. 185 void LTO::addSymbolToGlobalRes(IRObjectFile *Obj, 186 SmallPtrSet<GlobalValue *, 8> &Used, 187 const InputFile::Symbol &Sym, 188 SymbolResolution Res, unsigned Partition) { 189 GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 190 191 auto &GlobalRes = GlobalResolutions[Sym.getName()]; 192 if (GV) { 193 GlobalRes.UnnamedAddr &= GV->hasGlobalUnnamedAddr(); 194 if (Res.Prevailing) 195 GlobalRes.IRName = GV->getName(); 196 } 197 if (Res.VisibleToRegularObj || (GV && Used.count(GV)) || 198 (GlobalRes.Partition != GlobalResolution::Unknown && 199 GlobalRes.Partition != Partition)) 200 GlobalRes.Partition = GlobalResolution::External; 201 else 202 GlobalRes.Partition = Partition; 203 } 204 205 void LTO::writeToResolutionFile(InputFile *Input, 206 ArrayRef<SymbolResolution> Res) { 207 StringRef Path = Input->Obj->getMemoryBufferRef().getBufferIdentifier(); 208 *Conf.ResolutionFile << Path << '\n'; 209 auto ResI = Res.begin(); 210 for (const InputFile::Symbol &Sym : Input->symbols()) { 211 assert(ResI != Res.end()); 212 SymbolResolution Res = *ResI++; 213 214 *Conf.ResolutionFile << "-r=" << Path << ',' << Sym.getName() << ','; 215 if (Res.Prevailing) 216 *Conf.ResolutionFile << 'p'; 217 if (Res.FinalDefinitionInLinkageUnit) 218 *Conf.ResolutionFile << 'l'; 219 if (Res.VisibleToRegularObj) 220 *Conf.ResolutionFile << 'x'; 221 *Conf.ResolutionFile << '\n'; 222 } 223 assert(ResI == Res.end()); 224 } 225 226 Error LTO::add(std::unique_ptr<InputFile> Input, 227 ArrayRef<SymbolResolution> Res) { 228 assert(!CalledGetMaxTasks); 229 230 if (Conf.ResolutionFile) 231 writeToResolutionFile(Input.get(), Res); 232 233 Module &M = Input->Obj->getModule(); 234 SmallPtrSet<GlobalValue *, 8> Used; 235 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 236 237 if (!Conf.OverrideTriple.empty()) 238 M.setTargetTriple(Conf.OverrideTriple); 239 else if (M.getTargetTriple().empty()) 240 M.setTargetTriple(Conf.DefaultTriple); 241 242 MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); 243 bool HasThinLTOSummary = hasGlobalValueSummary(MBRef, Conf.DiagHandler); 244 245 if (HasThinLTOSummary) 246 return addThinLTO(std::move(Input), Res); 247 else 248 return addRegularLTO(std::move(Input), Res); 249 } 250 251 // Add a regular LTO object to the link. 252 Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, 253 ArrayRef<SymbolResolution> Res) { 254 RegularLTO.HasModule = true; 255 256 ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr = 257 IRObjectFile::create(Input->Obj->getMemoryBufferRef(), RegularLTO.Ctx); 258 if (!ObjOrErr) 259 return errorCodeToError(ObjOrErr.getError()); 260 std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr); 261 262 Module &M = Obj->getModule(); 263 M.materializeMetadata(); 264 UpgradeDebugInfo(M); 265 266 SmallPtrSet<GlobalValue *, 8> Used; 267 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 268 269 std::vector<GlobalValue *> Keep; 270 271 for (GlobalVariable &GV : M.globals()) 272 if (GV.hasAppendingLinkage()) 273 Keep.push_back(&GV); 274 275 auto ResI = Res.begin(); 276 for (const InputFile::Symbol &Sym : 277 make_range(InputFile::symbol_iterator(Obj->symbol_begin()), 278 InputFile::symbol_iterator(Obj->symbol_end()))) { 279 assert(ResI != Res.end()); 280 SymbolResolution Res = *ResI++; 281 addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0); 282 283 GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 284 if (Res.Prevailing && GV) { 285 Keep.push_back(GV); 286 switch (GV->getLinkage()) { 287 default: 288 break; 289 case GlobalValue::LinkOnceAnyLinkage: 290 GV->setLinkage(GlobalValue::WeakAnyLinkage); 291 break; 292 case GlobalValue::LinkOnceODRLinkage: 293 GV->setLinkage(GlobalValue::WeakODRLinkage); 294 break; 295 } 296 } 297 298 // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit. 299 } 300 assert(ResI == Res.end()); 301 302 return RegularLTO.Mover.move(Obj->takeModule(), Keep, 303 [](GlobalValue &, IRMover::ValueAdder) {}); 304 } 305 306 // Add a ThinLTO object to the link. 307 Error LTO::addThinLTO(std::unique_ptr<InputFile> Input, 308 ArrayRef<SymbolResolution> Res) { 309 Module &M = Input->Obj->getModule(); 310 SmallPtrSet<GlobalValue *, 8> Used; 311 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 312 313 // We need to initialize the target info for the combined regular LTO module 314 // in case we have no regular LTO objects. In that case we still need to build 315 // it as usual because the client may want to add symbol definitions to it. 316 if (RegularLTO.CombinedModule->getTargetTriple().empty()) { 317 RegularLTO.CombinedModule->setTargetTriple(M.getTargetTriple()); 318 RegularLTO.CombinedModule->setDataLayout(M.getDataLayout()); 319 } 320 321 MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); 322 ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> 323 SummaryObjOrErr = 324 object::ModuleSummaryIndexObjectFile::create(MBRef, Conf.DiagHandler); 325 if (!SummaryObjOrErr) 326 return errorCodeToError(SummaryObjOrErr.getError()); 327 ThinLTO.CombinedIndex.mergeFrom((*SummaryObjOrErr)->takeIndex(), 328 ThinLTO.ModuleMap.size()); 329 330 auto ResI = Res.begin(); 331 for (const InputFile::Symbol &Sym : Input->symbols()) { 332 assert(ResI != Res.end()); 333 SymbolResolution Res = *ResI++; 334 addSymbolToGlobalRes(Input->Obj.get(), Used, Sym, Res, 335 ThinLTO.ModuleMap.size() + 1); 336 337 GlobalValue *GV = Input->Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 338 if (Res.Prevailing && GV) 339 ThinLTO.PrevailingModuleForGUID[GV->getGUID()] = 340 MBRef.getBufferIdentifier(); 341 } 342 assert(ResI == Res.end()); 343 344 ThinLTO.ModuleMap[MBRef.getBufferIdentifier()] = MBRef; 345 return Error(); 346 } 347 348 unsigned LTO::getMaxTasks() const { 349 CalledGetMaxTasks = true; 350 return RegularLTO.ParallelCodeGenParallelismLevel + ThinLTO.ModuleMap.size(); 351 } 352 353 Error LTO::run(AddOutputFn AddOutput) { 354 // Invoke regular LTO if there was a regular LTO module to start with, 355 // or if there are any hooks that the linker may have used to add 356 // its own resolved symbols to the combined module. 357 if (RegularLTO.HasModule || Conf.PreOptModuleHook || 358 Conf.PostInternalizeModuleHook || Conf.PostOptModuleHook || 359 Conf.PreCodeGenModuleHook) 360 if (auto E = runRegularLTO(AddOutput)) 361 return E; 362 return runThinLTO(AddOutput); 363 } 364 365 Error LTO::runRegularLTO(AddOutputFn AddOutput) { 366 if (Conf.PreOptModuleHook && 367 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule)) 368 return Error(); 369 370 for (const auto &R : GlobalResolutions) { 371 if (R.second.IRName.empty()) 372 continue; 373 if (R.second.Partition != 0 && 374 R.second.Partition != GlobalResolution::External) 375 continue; 376 377 GlobalValue *GV = RegularLTO.CombinedModule->getNamedValue(R.second.IRName); 378 // Ignore symbols defined in other partitions. 379 if (!GV || GV->hasLocalLinkage()) 380 continue; 381 GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global 382 : GlobalValue::UnnamedAddr::None); 383 if (R.second.Partition == 0) 384 GV->setLinkage(GlobalValue::InternalLinkage); 385 } 386 387 if (Conf.PostInternalizeModuleHook && 388 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) 389 return Error(); 390 391 return backend(Conf, AddOutput, RegularLTO.ParallelCodeGenParallelismLevel, 392 std::move(RegularLTO.CombinedModule)); 393 } 394 395 /// This class defines the interface to the ThinLTO backend. 396 class lto::ThinBackendProc { 397 protected: 398 Config &Conf; 399 ModuleSummaryIndex &CombinedIndex; 400 AddOutputFn AddOutput; 401 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries; 402 403 public: 404 ThinBackendProc(Config &Conf, ModuleSummaryIndex &CombinedIndex, 405 AddOutputFn AddOutput, 406 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) 407 : Conf(Conf), CombinedIndex(CombinedIndex), AddOutput(AddOutput), 408 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) {} 409 410 virtual ~ThinBackendProc() {} 411 virtual Error start(unsigned Task, MemoryBufferRef MBRef, 412 const FunctionImporter::ImportMapTy &ImportList, 413 MapVector<StringRef, MemoryBufferRef> &ModuleMap) = 0; 414 virtual Error wait() = 0; 415 }; 416 417 class InProcessThinBackend : public ThinBackendProc { 418 ThreadPool BackendThreadPool; 419 420 Optional<Error> Err; 421 std::mutex ErrMu; 422 423 public: 424 InProcessThinBackend(Config &Conf, ModuleSummaryIndex &CombinedIndex, 425 unsigned ThinLTOParallelismLevel, 426 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 427 AddOutputFn AddOutput) 428 : ThinBackendProc(Conf, CombinedIndex, AddOutput, 429 ModuleToDefinedGVSummaries), 430 BackendThreadPool(ThinLTOParallelismLevel) {} 431 432 Error 433 runThinLTOBackendThread(AddOutputFn AddOutput, unsigned Task, 434 MemoryBufferRef MBRef, 435 ModuleSummaryIndex &CombinedIndex, 436 const FunctionImporter::ImportMapTy &ImportList, 437 const GVSummaryMapTy &DefinedGlobals, 438 MapVector<StringRef, MemoryBufferRef> &ModuleMap) { 439 LLVMContext BackendContext; 440 441 ErrorOr<std::unique_ptr<Module>> MOrErr = 442 parseBitcodeFile(MBRef, BackendContext); 443 assert(MOrErr && "Unable to load module in thread?"); 444 445 return thinBackend(Conf, Task, AddOutput, **MOrErr, CombinedIndex, 446 ImportList, DefinedGlobals, ModuleMap); 447 } 448 449 Error start(unsigned Task, MemoryBufferRef MBRef, 450 const FunctionImporter::ImportMapTy &ImportList, 451 MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { 452 StringRef ModulePath = MBRef.getBufferIdentifier(); 453 BackendThreadPool.async( 454 [=](MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex, 455 const FunctionImporter::ImportMapTy &ImportList, 456 GVSummaryMapTy &DefinedGlobals, 457 MapVector<StringRef, MemoryBufferRef> &ModuleMap) { 458 Error E = 459 runThinLTOBackendThread(AddOutput, Task, MBRef, CombinedIndex, 460 ImportList, DefinedGlobals, ModuleMap); 461 if (E) { 462 std::unique_lock<std::mutex> L(ErrMu); 463 if (Err) 464 Err = joinErrors(std::move(*Err), std::move(E)); 465 else 466 Err = std::move(E); 467 } 468 }, 469 MBRef, std::ref(CombinedIndex), std::ref(ImportList), 470 std::ref(ModuleToDefinedGVSummaries[ModulePath]), std::ref(ModuleMap)); 471 return Error(); 472 } 473 474 Error wait() override { 475 BackendThreadPool.wait(); 476 if (Err) 477 return std::move(*Err); 478 else 479 return Error(); 480 } 481 }; 482 483 ThinBackend lto::createInProcessThinBackend(unsigned ParallelismLevel) { 484 return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, 485 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 486 AddOutputFn AddOutput) { 487 return llvm::make_unique<InProcessThinBackend>( 488 Conf, CombinedIndex, ParallelismLevel, ModuleToDefinedGVSummaries, 489 AddOutput); 490 }; 491 } 492 493 class WriteIndexesThinBackend : public ThinBackendProc { 494 std::string OldPrefix, NewPrefix; 495 bool ShouldEmitImportsFiles; 496 497 std::string LinkedObjectsFileName; 498 std::unique_ptr<llvm::raw_fd_ostream> LinkedObjectsFile; 499 500 public: 501 WriteIndexesThinBackend(Config &Conf, ModuleSummaryIndex &CombinedIndex, 502 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 503 AddOutputFn AddOutput, std::string OldPrefix, 504 std::string NewPrefix, bool ShouldEmitImportsFiles, 505 std::string LinkedObjectsFileName) 506 : ThinBackendProc(Conf, CombinedIndex, AddOutput, 507 ModuleToDefinedGVSummaries), 508 OldPrefix(OldPrefix), NewPrefix(NewPrefix), 509 ShouldEmitImportsFiles(ShouldEmitImportsFiles), 510 LinkedObjectsFileName(LinkedObjectsFileName) {} 511 512 /// Given the original \p Path to an output file, replace any path 513 /// prefix matching \p OldPrefix with \p NewPrefix. Also, create the 514 /// resulting directory if it does not yet exist. 515 std::string getThinLTOOutputFile(const std::string &Path, 516 const std::string &OldPrefix, 517 const std::string &NewPrefix) { 518 if (OldPrefix.empty() && NewPrefix.empty()) 519 return Path; 520 SmallString<128> NewPath(Path); 521 llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix); 522 StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str()); 523 if (!ParentPath.empty()) { 524 // Make sure the new directory exists, creating it if necessary. 525 if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath)) 526 llvm::errs() << "warning: could not create directory '" << ParentPath 527 << "': " << EC.message() << '\n'; 528 } 529 return NewPath.str(); 530 } 531 532 Error start(unsigned Task, MemoryBufferRef MBRef, 533 const FunctionImporter::ImportMapTy &ImportList, 534 MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { 535 StringRef ModulePath = MBRef.getBufferIdentifier(); 536 std::string NewModulePath = 537 getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix); 538 539 std::error_code EC; 540 if (!LinkedObjectsFileName.empty()) { 541 if (!LinkedObjectsFile) { 542 LinkedObjectsFile = llvm::make_unique<raw_fd_ostream>( 543 LinkedObjectsFileName, EC, sys::fs::OpenFlags::F_None); 544 if (EC) 545 return errorCodeToError(EC); 546 } 547 *LinkedObjectsFile << NewModulePath << '\n'; 548 } 549 550 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex; 551 gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries, 552 ImportList, ModuleToSummariesForIndex); 553 554 raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC, 555 sys::fs::OpenFlags::F_None); 556 if (EC) 557 return errorCodeToError(EC); 558 WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); 559 560 if (ShouldEmitImportsFiles) 561 return errorCodeToError( 562 EmitImportsFiles(ModulePath, NewModulePath + ".imports", ImportList)); 563 return Error(); 564 } 565 566 Error wait() override { return Error(); } 567 }; 568 569 ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix, 570 std::string NewPrefix, 571 bool ShouldEmitImportsFiles, 572 std::string LinkedObjectsFile) { 573 return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, 574 StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 575 AddOutputFn AddOutput) { 576 return llvm::make_unique<WriteIndexesThinBackend>( 577 Conf, CombinedIndex, ModuleToDefinedGVSummaries, AddOutput, OldPrefix, 578 NewPrefix, ShouldEmitImportsFiles, LinkedObjectsFile); 579 }; 580 } 581 582 Error LTO::runThinLTO(AddOutputFn AddOutput) { 583 if (ThinLTO.ModuleMap.empty()) 584 return Error(); 585 586 if (Conf.CombinedIndexHook && !Conf.CombinedIndexHook(ThinLTO.CombinedIndex)) 587 return Error(); 588 589 // Collect for each module the list of function it defines (GUID -> 590 // Summary). 591 StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> 592 ModuleToDefinedGVSummaries(ThinLTO.ModuleMap.size()); 593 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule( 594 ModuleToDefinedGVSummaries); 595 596 StringMap<FunctionImporter::ImportMapTy> ImportLists( 597 ThinLTO.ModuleMap.size()); 598 StringMap<FunctionImporter::ExportSetTy> ExportLists( 599 ThinLTO.ModuleMap.size()); 600 ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, 601 ImportLists, ExportLists); 602 603 std::set<GlobalValue::GUID> ExportedGUIDs; 604 for (auto &Res : GlobalResolutions) { 605 if (!Res.second.IRName.empty() && 606 Res.second.Partition == GlobalResolution::External) 607 ExportedGUIDs.insert(GlobalValue::getGUID(Res.second.IRName)); 608 } 609 610 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) { 611 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath(); 612 }; 613 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { 614 const auto &ExportList = ExportLists.find(ModuleIdentifier); 615 return (ExportList != ExportLists.end() && 616 ExportList->second.count(GUID)) || 617 ExportedGUIDs.count(GUID); 618 }; 619 thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); 620 thinLTOResolveWeakForLinkerInIndex( 621 ThinLTO.CombinedIndex, isPrevailing, 622 [](StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes) {}); 623 624 std::unique_ptr<ThinBackendProc> BackendProc = ThinLTO.Backend( 625 Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, AddOutput); 626 627 // Partition numbers for ThinLTO jobs start at 1 (see comments for 628 // GlobalResolution in LTO.h). Task numbers, however, start at 629 // ParallelCodeGenParallelismLevel, as tasks 0 through 630 // ParallelCodeGenParallelismLevel-1 are reserved for parallel code generation 631 // partitions. 632 unsigned Task = RegularLTO.ParallelCodeGenParallelismLevel; 633 unsigned Partition = 1; 634 635 for (auto &Mod : ThinLTO.ModuleMap) { 636 if (Error E = BackendProc->start(Task, Mod.second, ImportLists[Mod.first], 637 ThinLTO.ModuleMap)) 638 return E; 639 640 ++Task; 641 ++Partition; 642 } 643 644 return BackendProc->wait(); 645 } 646