1 //===-ThinLTOCodeGenerator.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 the Thin Link Time Optimization library. This library is 11 // intended to be used by linker to optimize code at link time. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/LTO/ThinLTOCodeGenerator.h" 16 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/Analysis/ModuleSummaryAnalysis.h" 20 #include "llvm/Analysis/TargetLibraryInfo.h" 21 #include "llvm/Analysis/TargetTransformInfo.h" 22 #include "llvm/Bitcode/BitcodeWriterPass.h" 23 #include "llvm/Bitcode/ReaderWriter.h" 24 #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" 25 #include "llvm/IR/DiagnosticPrinter.h" 26 #include "llvm/IR/LLVMContext.h" 27 #include "llvm/IR/LegacyPassManager.h" 28 #include "llvm/IR/Mangler.h" 29 #include "llvm/IRReader/IRReader.h" 30 #include "llvm/Linker/Linker.h" 31 #include "llvm/MC/SubtargetFeature.h" 32 #include "llvm/Object/ModuleSummaryIndexObjectFile.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/SourceMgr.h" 35 #include "llvm/Support/TargetRegistry.h" 36 #include "llvm/Support/ThreadPool.h" 37 #include "llvm/Target/TargetMachine.h" 38 #include "llvm/Transforms/IPO.h" 39 #include "llvm/Transforms/IPO/FunctionImport.h" 40 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 41 #include "llvm/Transforms/ObjCARC.h" 42 #include "llvm/Transforms/Utils/FunctionImportUtils.h" 43 44 using namespace llvm; 45 46 #define DEBUG_TYPE "thinlto" 47 48 namespace llvm { 49 // Flags -discard-value-names, defined in LTOCodeGenerator.cpp 50 extern cl::opt<bool> LTODiscardValueNames; 51 } 52 53 namespace { 54 55 static cl::opt<int> ThreadCount("threads", 56 cl::init(std::thread::hardware_concurrency())); 57 58 static void diagnosticHandler(const DiagnosticInfo &DI) { 59 DiagnosticPrinterRawOStream DP(errs()); 60 DI.print(DP); 61 errs() << '\n'; 62 } 63 64 // Simple helper to load a module from bitcode 65 static std::unique_ptr<Module> 66 loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context, 67 bool Lazy) { 68 SMDiagnostic Err; 69 ErrorOr<std::unique_ptr<Module>> ModuleOrErr(nullptr); 70 if (Lazy) { 71 ModuleOrErr = 72 getLazyBitcodeModule(MemoryBuffer::getMemBuffer(Buffer, false), Context, 73 /* ShouldLazyLoadMetadata */ Lazy); 74 } else { 75 ModuleOrErr = parseBitcodeFile(Buffer, Context); 76 } 77 if (std::error_code EC = ModuleOrErr.getError()) { 78 Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error, 79 EC.message()); 80 Err.print("ThinLTO", errs()); 81 report_fatal_error("Can't load module, abort."); 82 } 83 return std::move(ModuleOrErr.get()); 84 } 85 86 // Simple helper to save temporary files for debug. 87 static void saveTempBitcode(const Module &TheModule, StringRef TempDir, 88 unsigned count, StringRef Suffix) { 89 if (TempDir.empty()) 90 return; 91 // User asked to save temps, let dump the bitcode file after import. 92 auto SaveTempPath = TempDir + llvm::utostr(count) + Suffix; 93 std::error_code EC; 94 raw_fd_ostream OS(SaveTempPath.str(), EC, sys::fs::F_None); 95 if (EC) 96 report_fatal_error(Twine("Failed to open ") + SaveTempPath + 97 " to save optimized bitcode\n"); 98 WriteBitcodeToFile(&TheModule, OS, /* ShouldPreserveUseListOrder */ true); 99 } 100 101 bool IsFirstDefinitionForLinker(const GlobalValueInfoList &GVInfo, 102 const ModuleSummaryIndex &Index, 103 StringRef ModulePath) { 104 // Get the first *linker visible* definition for this global in the summary 105 // list. 106 auto FirstDefForLinker = llvm::find_if( 107 GVInfo, [](const std::unique_ptr<GlobalValueInfo> &FuncInfo) { 108 auto Linkage = FuncInfo->summary()->linkage(); 109 return !GlobalValue::isAvailableExternallyLinkage(Linkage); 110 }); 111 // If \p GV is not the first definition, give up... 112 if ((*FirstDefForLinker)->summary()->modulePath() != ModulePath) 113 return false; 114 // If there is any strong definition anywhere, do not bother emitting this. 115 if (llvm::any_of( 116 GVInfo, [](const std::unique_ptr<GlobalValueInfo> &FuncInfo) { 117 auto Linkage = FuncInfo->summary()->linkage(); 118 return !GlobalValue::isAvailableExternallyLinkage(Linkage) && 119 !GlobalValue::isWeakForLinker(Linkage); 120 })) 121 return false; 122 return true; 123 } 124 125 static GlobalValue::LinkageTypes ResolveODR(const ModuleSummaryIndex &Index, 126 StringRef ModuleIdentifier, 127 GlobalValue::GUID GUID, 128 const GlobalValueSummary &GV) { 129 auto HasMultipleCopies = 130 [&](const GlobalValueInfoList &GVInfo) { return GVInfo.size() > 1; }; 131 132 auto OriginalLinkage = GV.linkage(); 133 switch (OriginalLinkage) { 134 case GlobalValue::ExternalLinkage: 135 case GlobalValue::AvailableExternallyLinkage: 136 case GlobalValue::AppendingLinkage: 137 case GlobalValue::InternalLinkage: 138 case GlobalValue::PrivateLinkage: 139 case GlobalValue::ExternalWeakLinkage: 140 case GlobalValue::CommonLinkage: 141 case GlobalValue::LinkOnceAnyLinkage: 142 case GlobalValue::WeakAnyLinkage: 143 break; 144 case GlobalValue::LinkOnceODRLinkage: 145 case GlobalValue::WeakODRLinkage: { 146 auto &GVInfo = Index.findGlobalValueInfoList(GUID)->second; 147 // We need to emit only one of these, the first module will keep 148 // it, but turned into a weak while the others will drop it. 149 if (!HasMultipleCopies(GVInfo)) 150 break; 151 if (IsFirstDefinitionForLinker(GVInfo, Index, ModuleIdentifier)) 152 return GlobalValue::WeakODRLinkage; 153 else 154 return GlobalValue::AvailableExternallyLinkage; 155 break; 156 } 157 } 158 return OriginalLinkage; 159 } 160 161 /// Resolve LinkOnceODR and WeakODR. 162 /// 163 /// We'd like to drop these function if they are no longer referenced in the 164 /// current module. However there is a chance that another module is still 165 /// referencing them because of the import. We make sure we always emit at least 166 /// one copy. 167 static void ResolveODR( 168 const ModuleSummaryIndex &Index, 169 const std::map<GlobalValue::GUID, GlobalValueSummary *> &DefinedGlobals, 170 StringRef ModuleIdentifier, 171 DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR) { 172 if (Index.modulePaths().size() == 1) 173 // Nothing to do if we don't have multiple modules 174 return; 175 176 // We won't optimize the globals that are referenced by an alias for now 177 // Ideally we should turn the alias into a global and duplicate the definition 178 // when needed. 179 DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; 180 for (auto &GA : DefinedGlobals) { 181 if (auto AS = dyn_cast<AliasSummary>(GA.second)) 182 GlobalInvolvedWithAlias.insert(&AS->getAliasee()); 183 } 184 185 for (auto &GV : DefinedGlobals) { 186 if (GlobalInvolvedWithAlias.count(GV.second)) 187 continue; 188 auto NewLinkage = ResolveODR(Index, ModuleIdentifier, GV.first, *GV.second); 189 if (NewLinkage != GV.second->linkage()) { 190 ResolvedODR[GV.first] = NewLinkage; 191 } 192 } 193 } 194 195 /// Fixup linkage, see ResolveODR() above. 196 void fixupODR( 197 Module &TheModule, 198 const DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR) { 199 // Process functions and global now 200 for (auto &GV : TheModule) { 201 auto NewLinkage = ResolvedODR.find(GV.getGUID()); 202 if (NewLinkage == ResolvedODR.end()) 203 continue; 204 DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " 205 << GV.getLinkage() << " to " << NewLinkage->second << "\n"); 206 GV.setLinkage(NewLinkage->second); 207 } 208 for (auto &GV : TheModule.globals()) { 209 auto NewLinkage = ResolvedODR.find(GV.getGUID()); 210 if (NewLinkage == ResolvedODR.end()) 211 continue; 212 DEBUG(dbgs() << "ODR fixing up linkage for `" << GV.getName() << "` from " 213 << GV.getLinkage() << " to " << NewLinkage->second << "\n"); 214 GV.setLinkage(NewLinkage->second); 215 } 216 } 217 218 static StringMap<MemoryBufferRef> 219 generateModuleMap(const std::vector<MemoryBufferRef> &Modules) { 220 StringMap<MemoryBufferRef> ModuleMap; 221 for (auto &ModuleBuffer : Modules) { 222 assert(ModuleMap.find(ModuleBuffer.getBufferIdentifier()) == 223 ModuleMap.end() && 224 "Expect unique Buffer Identifier"); 225 ModuleMap[ModuleBuffer.getBufferIdentifier()] = ModuleBuffer; 226 } 227 return ModuleMap; 228 } 229 230 /// Provide a "loader" for the FunctionImporter to access function from other 231 /// modules. 232 class ModuleLoader { 233 /// The context that will be used for importing. 234 LLVMContext &Context; 235 236 /// Map from Module identifier to MemoryBuffer. Used by clients like the 237 /// FunctionImported to request loading a Module. 238 StringMap<MemoryBufferRef> &ModuleMap; 239 240 public: 241 ModuleLoader(LLVMContext &Context, StringMap<MemoryBufferRef> &ModuleMap) 242 : Context(Context), ModuleMap(ModuleMap) {} 243 244 /// Load a module on demand. 245 std::unique_ptr<Module> operator()(StringRef Identifier) { 246 return loadModuleFromBuffer(ModuleMap[Identifier], Context, /*Lazy*/ true); 247 } 248 }; 249 250 static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index) { 251 if (renameModuleForThinLTO(TheModule, Index)) 252 report_fatal_error("renameModuleForThinLTO failed"); 253 } 254 255 static void 256 crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index, 257 StringMap<MemoryBufferRef> &ModuleMap, 258 const FunctionImporter::ImportMapTy &ImportList) { 259 ModuleLoader Loader(TheModule.getContext(), ModuleMap); 260 FunctionImporter Importer(Index, Loader); 261 Importer.importFunctions(TheModule, ImportList); 262 } 263 264 static void optimizeModule(Module &TheModule, TargetMachine &TM) { 265 // Populate the PassManager 266 PassManagerBuilder PMB; 267 PMB.LibraryInfo = new TargetLibraryInfoImpl(TM.getTargetTriple()); 268 PMB.Inliner = createFunctionInliningPass(); 269 // FIXME: should get it from the bitcode? 270 PMB.OptLevel = 3; 271 PMB.LoopVectorize = true; 272 PMB.SLPVectorize = true; 273 PMB.VerifyInput = true; 274 PMB.VerifyOutput = false; 275 276 legacy::PassManager PM; 277 278 // Add the TTI (required to inform the vectorizer about register size for 279 // instance) 280 PM.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); 281 282 // Add optimizations 283 PMB.populateThinLTOPassManager(PM); 284 285 PM.run(TheModule); 286 } 287 288 std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule, 289 TargetMachine &TM) { 290 SmallVector<char, 128> OutputBuffer; 291 292 // CodeGen 293 { 294 raw_svector_ostream OS(OutputBuffer); 295 legacy::PassManager PM; 296 297 // If the bitcode files contain ARC code and were compiled with optimization, 298 // the ObjCARCContractPass must be run, so do it unconditionally here. 299 PM.add(createObjCARCContractPass()); 300 301 // Setup the codegen now. 302 if (TM.addPassesToEmitFile(PM, OS, TargetMachine::CGFT_ObjectFile, 303 /* DisableVerify */ true)) 304 report_fatal_error("Failed to setup codegen"); 305 306 // Run codegen now. resulting binary is in OutputBuffer. 307 PM.run(TheModule); 308 } 309 return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer)); 310 } 311 312 static std::unique_ptr<MemoryBuffer> ProcessThinLTOModule( 313 Module &TheModule, const ModuleSummaryIndex &Index, 314 StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM, 315 const FunctionImporter::ImportMapTy &ImportList, 316 DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 317 ThinLTOCodeGenerator::CachingOptions CacheOptions, bool DisableCodeGen, 318 StringRef SaveTempsDir, unsigned count) { 319 320 // Save temps: after IPO. 321 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.IPO.bc"); 322 323 // "Benchmark"-like optimization: single-source case 324 bool SingleModule = (ModuleMap.size() == 1); 325 326 if (!SingleModule) { 327 promoteModule(TheModule, Index); 328 329 // Resolve the LinkOnce/Weak ODR, trying to turn them into 330 // "available_externally" when possible. 331 // This is a compile-time optimization. 332 fixupODR(TheModule, ResolvedODR); 333 334 // Save temps: after promotion. 335 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.promoted.bc"); 336 337 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList); 338 339 // Save temps: after cross-module import. 340 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc"); 341 } 342 343 optimizeModule(TheModule, TM); 344 345 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.opt.bc"); 346 347 if (DisableCodeGen) { 348 // Configured to stop before CodeGen, serialize the bitcode and return. 349 SmallVector<char, 128> OutputBuffer; 350 { 351 raw_svector_ostream OS(OutputBuffer); 352 ModuleSummaryIndexBuilder IndexBuilder(&TheModule); 353 WriteBitcodeToFile(&TheModule, OS, true, &IndexBuilder.getIndex()); 354 } 355 return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer)); 356 } 357 358 return codegenModule(TheModule, TM); 359 } 360 361 // Initialize the TargetMachine builder for a given Triple 362 static void initTMBuilder(TargetMachineBuilder &TMBuilder, 363 const Triple &TheTriple) { 364 // Set a default CPU for Darwin triples (copied from LTOCodeGenerator). 365 // FIXME this looks pretty terrible... 366 if (TMBuilder.MCpu.empty() && TheTriple.isOSDarwin()) { 367 if (TheTriple.getArch() == llvm::Triple::x86_64) 368 TMBuilder.MCpu = "core2"; 369 else if (TheTriple.getArch() == llvm::Triple::x86) 370 TMBuilder.MCpu = "yonah"; 371 else if (TheTriple.getArch() == llvm::Triple::aarch64) 372 TMBuilder.MCpu = "cyclone"; 373 } 374 TMBuilder.TheTriple = std::move(TheTriple); 375 } 376 377 } // end anonymous namespace 378 379 void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) { 380 MemoryBufferRef Buffer(Data, Identifier); 381 if (Modules.empty()) { 382 // First module added, so initialize the triple and some options 383 LLVMContext Context; 384 Triple TheTriple(getBitcodeTargetTriple(Buffer, Context)); 385 initTMBuilder(TMBuilder, Triple(TheTriple)); 386 } 387 #ifndef NDEBUG 388 else { 389 LLVMContext Context; 390 assert(TMBuilder.TheTriple.str() == 391 getBitcodeTargetTriple(Buffer, Context) && 392 "ThinLTO modules with different triple not supported"); 393 } 394 #endif 395 Modules.push_back(Buffer); 396 } 397 398 void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) { 399 PreservedSymbols.insert(Name); 400 } 401 402 void ThinLTOCodeGenerator::crossReferenceSymbol(StringRef Name) { 403 CrossReferencedSymbols.insert(Name); 404 } 405 406 // TargetMachine factory 407 std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const { 408 std::string ErrMsg; 409 const Target *TheTarget = 410 TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg); 411 if (!TheTarget) { 412 report_fatal_error("Can't load target for this Triple: " + ErrMsg); 413 } 414 415 // Use MAttr as the default set of features. 416 SubtargetFeatures Features(MAttr); 417 Features.getDefaultSubtargetFeatures(TheTriple); 418 std::string FeatureStr = Features.getString(); 419 return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 420 TheTriple.str(), MCpu, FeatureStr, Options, RelocModel, 421 CodeModel::Default, CGOptLevel)); 422 } 423 424 /** 425 * Produce the combined summary index from all the bitcode files: 426 * "thin-link". 427 */ 428 std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() { 429 std::unique_ptr<ModuleSummaryIndex> CombinedIndex; 430 uint64_t NextModuleId = 0; 431 for (auto &ModuleBuffer : Modules) { 432 ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr = 433 object::ModuleSummaryIndexObjectFile::create(ModuleBuffer, 434 diagnosticHandler, false); 435 if (std::error_code EC = ObjOrErr.getError()) { 436 // FIXME diagnose 437 errs() << "error: can't create ModuleSummaryIndexObjectFile for buffer: " 438 << EC.message() << "\n"; 439 return nullptr; 440 } 441 auto Index = (*ObjOrErr)->takeIndex(); 442 if (CombinedIndex) { 443 CombinedIndex->mergeFrom(std::move(Index), ++NextModuleId); 444 } else { 445 CombinedIndex = std::move(Index); 446 } 447 } 448 return CombinedIndex; 449 } 450 451 /** 452 * Perform promotion and renaming of exported internal functions. 453 */ 454 void ThinLTOCodeGenerator::promote(Module &TheModule, 455 ModuleSummaryIndex &Index) { 456 auto ModuleIdentifier = TheModule.getModuleIdentifier(); 457 // Collect for each module the list of function it defines (GUID -> Summary). 458 StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> 459 ModuleToDefinedGVSummaries; 460 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); 461 462 // Resolve the LinkOnceODR, trying to turn them into "available_externally" 463 // where possible. 464 // This is a compile-time optimization. 465 DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR; 466 ResolveODR(Index, ModuleToDefinedGVSummaries[ModuleIdentifier], 467 ModuleIdentifier, ResolvedODR); 468 fixupODR(TheModule, ResolvedODR); 469 470 promoteModule(TheModule, Index); 471 } 472 473 /** 474 * Perform cross-module importing for the module identified by ModuleIdentifier. 475 */ 476 void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule, 477 ModuleSummaryIndex &Index) { 478 auto ModuleMap = generateModuleMap(Modules); 479 auto ModuleCount = Index.modulePaths().size(); 480 481 // Collect for each module the list of function it defines (GUID -> Summary). 482 StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> 483 ModuleToDefinedGVSummaries(ModuleCount); 484 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); 485 486 // Generate import/export list 487 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); 488 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount); 489 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists, 490 ExportLists); 491 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()]; 492 493 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList); 494 } 495 496 /** 497 * Perform post-importing ThinLTO optimizations. 498 */ 499 void ThinLTOCodeGenerator::optimize(Module &TheModule) { 500 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); 501 optimizeModule(TheModule, *TMBuilder.create()); 502 } 503 504 /** 505 * Perform ThinLTO CodeGen. 506 */ 507 std::unique_ptr<MemoryBuffer> ThinLTOCodeGenerator::codegen(Module &TheModule) { 508 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple())); 509 return codegenModule(TheModule, *TMBuilder.create()); 510 } 511 512 // Main entry point for the ThinLTO processing 513 void ThinLTOCodeGenerator::run() { 514 if (CodeGenOnly) { 515 // Perform only parallel codegen and return. 516 ThreadPool Pool; 517 assert(ProducedBinaries.empty() && "The generator should not be reused"); 518 ProducedBinaries.resize(Modules.size()); 519 int count = 0; 520 for (auto &ModuleBuffer : Modules) { 521 Pool.async([&](int count) { 522 LLVMContext Context; 523 Context.setDiscardValueNames(LTODiscardValueNames); 524 525 // Parse module now 526 auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false); 527 528 // CodeGen 529 ProducedBinaries[count] = codegen(*TheModule); 530 }, count++); 531 } 532 533 return; 534 } 535 536 // Sequential linking phase 537 auto Index = linkCombinedIndex(); 538 539 // Save temps: index. 540 if (!SaveTempsDir.empty()) { 541 auto SaveTempPath = SaveTempsDir + "index.bc"; 542 std::error_code EC; 543 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::F_None); 544 if (EC) 545 report_fatal_error(Twine("Failed to open ") + SaveTempPath + 546 " to save optimized bitcode\n"); 547 WriteIndexToFile(*Index, OS); 548 } 549 550 // Prepare the resulting object vector 551 assert(ProducedBinaries.empty() && "The generator should not be reused"); 552 ProducedBinaries.resize(Modules.size()); 553 554 // Prepare the module map. 555 auto ModuleMap = generateModuleMap(Modules); 556 auto ModuleCount = Modules.size(); 557 558 // Collect for each module the list of function it defines (GUID -> Summary). 559 StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> 560 ModuleToDefinedGVSummaries(ModuleCount); 561 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); 562 563 // Collect the import/export lists for all modules from the call-graph in the 564 // combined index. 565 StringMap<FunctionImporter::ImportMapTy> ImportLists(ModuleCount); 566 StringMap<FunctionImporter::ExportSetTy> ExportLists(ModuleCount); 567 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries, ImportLists, 568 ExportLists); 569 570 // Parallel optimizer + codegen 571 { 572 ThreadPool Pool(ThreadCount); 573 int count = 0; 574 for (auto &ModuleBuffer : Modules) { 575 Pool.async([&](int count) { 576 LLVMContext Context; 577 Context.setDiscardValueNames(LTODiscardValueNames); 578 auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier(); 579 580 DenseMap<GlobalValue::GUID, GlobalValue::LinkageTypes> ResolvedODR; 581 ResolveODR(*Index, ModuleToDefinedGVSummaries[ModuleIdentifier], 582 ModuleIdentifier, ResolvedODR); 583 584 // Parse module now 585 auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false); 586 587 // Save temps: original file. 588 if (!SaveTempsDir.empty()) { 589 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc"); 590 } 591 592 auto &ImportList = ImportLists[ModuleIdentifier]; 593 ProducedBinaries[count] = ProcessThinLTOModule( 594 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList, 595 ResolvedODR, CacheOptions, DisableCodeGen, SaveTempsDir, count); 596 }, count); 597 count++; 598 } 599 } 600 601 // If statistics were requested, print them out now. 602 if (llvm::AreStatisticsEnabled()) 603 llvm::PrintStatistics(); 604 } 605