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