xref: /llvm-project-15.0.7/llvm/lib/LTO/LTO.cpp (revision 8a915ed6)
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/SHA1.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetRegistry.h"
31 #include "llvm/Support/ThreadPool.h"
32 #include "llvm/Support/Threading.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include "llvm/Target/TargetMachine.h"
35 #include "llvm/Target/TargetOptions.h"
36 #include "llvm/Transforms/IPO.h"
37 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
38 #include "llvm/Transforms/Utils/SplitModule.h"
39 
40 #include <set>
41 
42 using namespace llvm;
43 using namespace lto;
44 using namespace object;
45 
46 #define DEBUG_TYPE "lto"
47 
48 // Returns a unique hash for the Module considering the current list of
49 // export/import and other global analysis results.
50 // The hash is produced in \p Key.
51 static void computeCacheKey(
52     SmallString<40> &Key, const ModuleSummaryIndex &Index, StringRef ModuleID,
53     const FunctionImporter::ImportMapTy &ImportList,
54     const FunctionImporter::ExportSetTy &ExportList,
55     const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
56     const GVSummaryMapTy &DefinedGlobals) {
57   // Compute the unique hash for this entry.
58   // This is based on the current compiler version, the module itself, the
59   // export list, the hash for every single module in the import list, the
60   // list of ResolvedODR for the module, and the list of preserved symbols.
61   SHA1 Hasher;
62 
63   // Start with the compiler revision
64   Hasher.update(LLVM_VERSION_STRING);
65 #ifdef HAVE_LLVM_REVISION
66   Hasher.update(LLVM_REVISION);
67 #endif
68 
69   // Include the hash for the current module
70   auto ModHash = Index.getModuleHash(ModuleID);
71   Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
72   for (auto F : ExportList)
73     // The export list can impact the internalization, be conservative here
74     Hasher.update(ArrayRef<uint8_t>((uint8_t *)&F, sizeof(F)));
75 
76   // Include the hash for every module we import functions from
77   for (auto &Entry : ImportList) {
78     auto ModHash = Index.getModuleHash(Entry.first());
79     Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash)));
80   }
81 
82   // Include the hash for the resolved ODR.
83   for (auto &Entry : ResolvedODR) {
84     Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first,
85                                     sizeof(GlobalValue::GUID)));
86     Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second,
87                                     sizeof(GlobalValue::LinkageTypes)));
88   }
89 
90   // Include the hash for the linkage type to reflect internalization and weak
91   // resolution.
92   for (auto &GS : DefinedGlobals) {
93     GlobalValue::LinkageTypes Linkage = GS.second->linkage();
94     Hasher.update(
95         ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage)));
96   }
97 
98   Key = toHex(Hasher.result());
99 }
100 
101 // Simple helper to load a module from bitcode
102 std::unique_ptr<Module>
103 llvm::loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context,
104                            bool Lazy) {
105   SMDiagnostic Err;
106   ErrorOr<std::unique_ptr<Module>> ModuleOrErr(nullptr);
107   if (Lazy) {
108     ModuleOrErr =
109         getLazyBitcodeModule(MemoryBuffer::getMemBuffer(Buffer, false), Context,
110                              /* ShouldLazyLoadMetadata */ Lazy);
111   } else {
112     ModuleOrErr = parseBitcodeFile(Buffer, Context);
113   }
114   if (std::error_code EC = ModuleOrErr.getError()) {
115     Err = SMDiagnostic(Buffer.getBufferIdentifier(), SourceMgr::DK_Error,
116                        EC.message());
117     Err.print("ThinLTO", errs());
118     report_fatal_error("Can't load module, abort.");
119   }
120   return std::move(ModuleOrErr.get());
121 }
122 
123 static void thinLTOResolveWeakForLinkerGUID(
124     GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
125     DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias,
126     function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
127         isPrevailing,
128     function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>
129         recordNewLinkage) {
130   for (auto &S : GVSummaryList) {
131     GlobalValue::LinkageTypes OriginalLinkage = S->linkage();
132     if (!GlobalValue::isWeakForLinker(OriginalLinkage))
133       continue;
134     // We need to emit only one of these. The prevailing module will keep it,
135     // but turned into a weak, while the others will drop it when possible.
136     // This is both a compile-time optimization and a correctness
137     // transformation. This is necessary for correctness when we have exported
138     // a reference - we need to convert the linkonce to weak to
139     // ensure a copy is kept to satisfy the exported reference.
140     // FIXME: We may want to split the compile time and correctness
141     // aspects into separate routines.
142     if (isPrevailing(GUID, S.get())) {
143       if (GlobalValue::isLinkOnceLinkage(OriginalLinkage))
144         S->setLinkage(GlobalValue::getWeakLinkage(
145             GlobalValue::isLinkOnceODRLinkage(OriginalLinkage)));
146     }
147     // Alias and aliasee can't be turned into available_externally.
148     else if (!isa<AliasSummary>(S.get()) &&
149              !GlobalInvolvedWithAlias.count(S.get()) &&
150              (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) ||
151               GlobalValue::isWeakODRLinkage(OriginalLinkage)))
152       S->setLinkage(GlobalValue::AvailableExternallyLinkage);
153     if (S->linkage() != OriginalLinkage)
154       recordNewLinkage(S->modulePath(), GUID, S->linkage());
155   }
156 }
157 
158 // Resolve Weak and LinkOnce values in the \p Index.
159 //
160 // We'd like to drop these functions if they are no longer referenced in the
161 // current module. However there is a chance that another module is still
162 // referencing them because of the import. We make sure we always emit at least
163 // one copy.
164 void llvm::thinLTOResolveWeakForLinkerInIndex(
165     ModuleSummaryIndex &Index,
166     function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)>
167         isPrevailing,
168     function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)>
169         recordNewLinkage) {
170   // We won't optimize the globals that are referenced by an alias for now
171   // Ideally we should turn the alias into a global and duplicate the definition
172   // when needed.
173   DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias;
174   for (auto &I : Index)
175     for (auto &S : I.second)
176       if (auto AS = dyn_cast<AliasSummary>(S.get()))
177         GlobalInvolvedWithAlias.insert(&AS->getAliasee());
178 
179   for (auto &I : Index)
180     thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias,
181                                     isPrevailing, recordNewLinkage);
182 }
183 
184 static void thinLTOInternalizeAndPromoteGUID(
185     GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID,
186     function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
187   for (auto &S : GVSummaryList) {
188     if (isExported(S->modulePath(), GUID)) {
189       if (GlobalValue::isLocalLinkage(S->linkage()))
190         S->setLinkage(GlobalValue::ExternalLinkage);
191     } else if (!GlobalValue::isLocalLinkage(S->linkage()))
192       S->setLinkage(GlobalValue::InternalLinkage);
193   }
194 }
195 
196 // Update the linkages in the given \p Index to mark exported values
197 // as external and non-exported values as internal.
198 void llvm::thinLTOInternalizeAndPromoteInIndex(
199     ModuleSummaryIndex &Index,
200     function_ref<bool(StringRef, GlobalValue::GUID)> isExported) {
201   for (auto &I : Index)
202     thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
203 }
204 
205 Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {
206   std::unique_ptr<InputFile> File(new InputFile);
207   std::string Msg;
208   auto DiagHandler = [](const DiagnosticInfo &DI, void *MsgP) {
209     auto *Msg = reinterpret_cast<std::string *>(MsgP);
210     raw_string_ostream OS(*Msg);
211     DiagnosticPrinterRawOStream DP(OS);
212     DI.print(DP);
213   };
214   File->Ctx.setDiagnosticHandler(DiagHandler, static_cast<void *>(&Msg));
215 
216   ErrorOr<std::unique_ptr<object::IRObjectFile>> IRObj =
217       IRObjectFile::create(Object, File->Ctx);
218   if (!Msg.empty())
219     return make_error<StringError>(Msg, inconvertibleErrorCode());
220   if (!IRObj)
221     return errorCodeToError(IRObj.getError());
222   File->Obj = std::move(*IRObj);
223 
224   File->Ctx.setDiagnosticHandler(nullptr, nullptr);
225 
226   for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) {
227     auto P =
228         File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size()));
229     assert(P.second);
230     (void)P;
231     File->Comdats.push_back(C.first());
232   }
233 
234   return std::move(File);
235 }
236 
237 Expected<int> InputFile::Symbol::getComdatIndex() const {
238   if (!GV)
239     return -1;
240   const GlobalObject *GO;
241   if (auto *GA = dyn_cast<GlobalAlias>(GV)) {
242     GO = GA->getBaseObject();
243     if (!GO)
244       return make_error<StringError>("Unable to determine comdat of alias!",
245                                      inconvertibleErrorCode());
246   } else {
247     GO = cast<GlobalObject>(GV);
248   }
249   if (const Comdat *C = GO->getComdat()) {
250     auto I = File->ComdatMap.find(C);
251     assert(I != File->ComdatMap.end());
252     return I->second;
253   }
254   return -1;
255 }
256 
257 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
258                                       Config &Conf)
259     : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
260       Ctx(Conf) {}
261 
262 LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) {
263   if (!Backend)
264     this->Backend =
265         createInProcessThinBackend(llvm::heavyweight_hardware_concurrency());
266 }
267 
268 LTO::LTO(Config Conf, ThinBackend Backend,
269          unsigned ParallelCodeGenParallelismLevel)
270     : Conf(std::move(Conf)),
271       RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
272       ThinLTO(std::move(Backend)) {}
273 
274 // Add the given symbol to the GlobalResolutions map, and resolve its partition.
275 void LTO::addSymbolToGlobalRes(IRObjectFile *Obj,
276                                SmallPtrSet<GlobalValue *, 8> &Used,
277                                const InputFile::Symbol &Sym,
278                                SymbolResolution Res, unsigned Partition) {
279   GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
280 
281   auto &GlobalRes = GlobalResolutions[Sym.getName()];
282   if (GV) {
283     GlobalRes.UnnamedAddr &= GV->hasGlobalUnnamedAddr();
284     if (Res.Prevailing)
285       GlobalRes.IRName = GV->getName();
286   }
287   if (Res.VisibleToRegularObj || (GV && Used.count(GV)) ||
288       (GlobalRes.Partition != GlobalResolution::Unknown &&
289        GlobalRes.Partition != Partition))
290     GlobalRes.Partition = GlobalResolution::External;
291   else
292     GlobalRes.Partition = Partition;
293 }
294 
295 static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,
296                                   ArrayRef<SymbolResolution> Res) {
297   StringRef Path = Input->getMemoryBufferRef().getBufferIdentifier();
298   OS << Path << '\n';
299   auto ResI = Res.begin();
300   for (const InputFile::Symbol &Sym : Input->symbols()) {
301     assert(ResI != Res.end());
302     SymbolResolution Res = *ResI++;
303 
304     OS << "-r=" << Path << ',' << Sym.getName() << ',';
305     if (Res.Prevailing)
306       OS << 'p';
307     if (Res.FinalDefinitionInLinkageUnit)
308       OS << 'l';
309     if (Res.VisibleToRegularObj)
310       OS << 'x';
311     OS << '\n';
312   }
313   assert(ResI == Res.end());
314 }
315 
316 Error LTO::add(std::unique_ptr<InputFile> Input,
317                ArrayRef<SymbolResolution> Res) {
318   assert(!CalledGetMaxTasks);
319 
320   if (Conf.ResolutionFile)
321     writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);
322 
323   // FIXME: move to backend
324   Module &M = Input->Obj->getModule();
325   if (!Conf.OverrideTriple.empty())
326     M.setTargetTriple(Conf.OverrideTriple);
327   else if (M.getTargetTriple().empty())
328     M.setTargetTriple(Conf.DefaultTriple);
329 
330   MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef();
331   bool HasThinLTOSummary = hasGlobalValueSummary(MBRef, Conf.DiagHandler);
332 
333   if (HasThinLTOSummary)
334     return addThinLTO(std::move(Input), Res);
335   else
336     return addRegularLTO(std::move(Input), Res);
337 }
338 
339 // Add a regular LTO object to the link.
340 Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input,
341                          ArrayRef<SymbolResolution> Res) {
342   if (!RegularLTO.CombinedModule) {
343     RegularLTO.CombinedModule =
344         llvm::make_unique<Module>("ld-temp.o", RegularLTO.Ctx);
345     RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule);
346   }
347   ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
348       IRObjectFile::create(Input->Obj->getMemoryBufferRef(), RegularLTO.Ctx);
349   if (!ObjOrErr)
350     return errorCodeToError(ObjOrErr.getError());
351   std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr);
352 
353   Module &M = Obj->getModule();
354   M.materializeMetadata();
355   UpgradeDebugInfo(M);
356 
357   SmallPtrSet<GlobalValue *, 8> Used;
358   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
359 
360   std::vector<GlobalValue *> Keep;
361 
362   for (GlobalVariable &GV : M.globals())
363     if (GV.hasAppendingLinkage())
364       Keep.push_back(&GV);
365 
366   auto ResI = Res.begin();
367   for (const InputFile::Symbol &Sym :
368        make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr),
369                   InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) {
370     assert(ResI != Res.end());
371     SymbolResolution Res = *ResI++;
372     addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0);
373 
374     GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
375     if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
376       continue;
377     if (Res.Prevailing && GV) {
378       Keep.push_back(GV);
379       switch (GV->getLinkage()) {
380       default:
381         break;
382       case GlobalValue::LinkOnceAnyLinkage:
383         GV->setLinkage(GlobalValue::WeakAnyLinkage);
384         break;
385       case GlobalValue::LinkOnceODRLinkage:
386         GV->setLinkage(GlobalValue::WeakODRLinkage);
387         break;
388       }
389     }
390     // Common resolution: collect the maximum size/alignment over all commons.
391     // We also record if we see an instance of a common as prevailing, so that
392     // if none is prevailing we can ignore it later.
393     if (Sym.getFlags() & object::BasicSymbolRef::SF_Common) {
394       auto &CommonRes = RegularLTO.Commons[Sym.getIRName()];
395       CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
396       CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment());
397       CommonRes.Prevailing |= Res.Prevailing;
398     }
399 
400     // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit.
401   }
402   assert(ResI == Res.end());
403 
404   return RegularLTO.Mover->move(Obj->takeModule(), Keep,
405                                 [](GlobalValue &, IRMover::ValueAdder) {},
406                                 /* LinkModuleInlineAsm */ true);
407 }
408 
409 // Add a ThinLTO object to the link.
410 Error LTO::addThinLTO(std::unique_ptr<InputFile> Input,
411                       ArrayRef<SymbolResolution> Res) {
412   Module &M = Input->Obj->getModule();
413   SmallPtrSet<GlobalValue *, 8> Used;
414   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
415 
416   MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef();
417   ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>>
418       SummaryObjOrErr =
419           object::ModuleSummaryIndexObjectFile::create(MBRef, Conf.DiagHandler);
420   if (!SummaryObjOrErr)
421     return errorCodeToError(SummaryObjOrErr.getError());
422   ThinLTO.CombinedIndex.mergeFrom((*SummaryObjOrErr)->takeIndex(),
423                                   ThinLTO.ModuleMap.size());
424 
425   auto ResI = Res.begin();
426   for (const InputFile::Symbol &Sym : Input->symbols()) {
427     assert(ResI != Res.end());
428     SymbolResolution Res = *ResI++;
429     addSymbolToGlobalRes(Input->Obj.get(), Used, Sym, Res,
430                          ThinLTO.ModuleMap.size() + 1);
431 
432     GlobalValue *GV = Input->Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
433     if (Res.Prevailing && GV)
434       ThinLTO.PrevailingModuleForGUID[GV->getGUID()] =
435           MBRef.getBufferIdentifier();
436   }
437   assert(ResI == Res.end());
438 
439   ThinLTO.ModuleMap[MBRef.getBufferIdentifier()] = MBRef;
440   return Error();
441 }
442 
443 unsigned LTO::getMaxTasks() const {
444   CalledGetMaxTasks = true;
445   return RegularLTO.ParallelCodeGenParallelismLevel + ThinLTO.ModuleMap.size();
446 }
447 
448 Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) {
449   // Save the status of having a regularLTO combined module, as
450   // this is needed for generating the ThinLTO Task ID, and
451   // the CombinedModule will be moved at the end of runRegularLTO.
452   bool HasRegularLTO = RegularLTO.CombinedModule != nullptr;
453   // Invoke regular LTO if there was a regular LTO module to start with.
454   if (HasRegularLTO)
455     if (auto E = runRegularLTO(AddStream))
456       return E;
457   return runThinLTO(AddStream, Cache, HasRegularLTO);
458 }
459 
460 Error LTO::runRegularLTO(AddStreamFn AddStream) {
461   // Make sure commons have the right size/alignment: we kept the largest from
462   // all the prevailing when adding the inputs, and we apply it here.
463   const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout();
464   for (auto &I : RegularLTO.Commons) {
465     if (!I.second.Prevailing)
466       // Don't do anything if no instance of this common was prevailing.
467       continue;
468     GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first);
469     if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) {
470       // Don't create a new global if the type is already correct, just make
471       // sure the alignment is correct.
472       OldGV->setAlignment(I.second.Align);
473       continue;
474     }
475     ArrayType *Ty =
476         ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size);
477     auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false,
478                                   GlobalValue::CommonLinkage,
479                                   ConstantAggregateZero::get(Ty), "");
480     GV->setAlignment(I.second.Align);
481     if (OldGV) {
482       OldGV->replaceAllUsesWith(ConstantExpr::getBitCast(GV, OldGV->getType()));
483       GV->takeName(OldGV);
484       OldGV->eraseFromParent();
485     } else {
486       GV->setName(I.first);
487     }
488   }
489 
490   if (Conf.PreOptModuleHook &&
491       !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule))
492     return Error();
493 
494   if (!Conf.CodeGenOnly) {
495     for (const auto &R : GlobalResolutions) {
496       if (R.second.IRName.empty())
497         continue;
498       if (R.second.Partition != 0 &&
499           R.second.Partition != GlobalResolution::External)
500         continue;
501 
502       GlobalValue *GV =
503           RegularLTO.CombinedModule->getNamedValue(R.second.IRName);
504       // Ignore symbols defined in other partitions.
505       if (!GV || GV->hasLocalLinkage())
506         continue;
507       GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global
508                                               : GlobalValue::UnnamedAddr::None);
509       if (R.second.Partition == 0)
510         GV->setLinkage(GlobalValue::InternalLinkage);
511     }
512 
513     if (Conf.PostInternalizeModuleHook &&
514         !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule))
515       return Error();
516   }
517   return backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel,
518                  std::move(RegularLTO.CombinedModule));
519 }
520 
521 /// This class defines the interface to the ThinLTO backend.
522 class lto::ThinBackendProc {
523 protected:
524   Config &Conf;
525   ModuleSummaryIndex &CombinedIndex;
526   const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries;
527 
528 public:
529   ThinBackendProc(Config &Conf, ModuleSummaryIndex &CombinedIndex,
530                   const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries)
531       : Conf(Conf), CombinedIndex(CombinedIndex),
532         ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) {}
533 
534   virtual ~ThinBackendProc() {}
535   virtual Error start(
536       unsigned Task, MemoryBufferRef MBRef,
537       const FunctionImporter::ImportMapTy &ImportList,
538       const FunctionImporter::ExportSetTy &ExportList,
539       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
540       MapVector<StringRef, MemoryBufferRef> &ModuleMap) = 0;
541   virtual Error wait() = 0;
542 };
543 
544 class InProcessThinBackend : public ThinBackendProc {
545   ThreadPool BackendThreadPool;
546   AddStreamFn AddStream;
547   NativeObjectCache Cache;
548 
549   Optional<Error> Err;
550   std::mutex ErrMu;
551 
552 public:
553   InProcessThinBackend(
554       Config &Conf, ModuleSummaryIndex &CombinedIndex,
555       unsigned ThinLTOParallelismLevel,
556       const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
557       AddStreamFn AddStream, NativeObjectCache Cache)
558       : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries),
559         BackendThreadPool(ThinLTOParallelismLevel),
560         AddStream(std::move(AddStream)), Cache(std::move(Cache)) {}
561 
562   Error runThinLTOBackendThread(
563       AddStreamFn AddStream, NativeObjectCache Cache, unsigned Task,
564       MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex,
565       const FunctionImporter::ImportMapTy &ImportList,
566       const FunctionImporter::ExportSetTy &ExportList,
567       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
568       const GVSummaryMapTy &DefinedGlobals,
569       MapVector<StringRef, MemoryBufferRef> &ModuleMap) {
570     auto RunThinBackend = [&](AddStreamFn AddStream) {
571       LTOLLVMContext BackendContext(Conf);
572       ErrorOr<std::unique_ptr<Module>> MOrErr =
573           parseBitcodeFile(MBRef, BackendContext);
574       assert(MOrErr && "Unable to load module in thread?");
575 
576       return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex,
577                          ImportList, DefinedGlobals, ModuleMap);
578     };
579 
580     auto ModuleID = MBRef.getBufferIdentifier();
581 
582     if (!Cache || !CombinedIndex.modulePaths().count(ModuleID) ||
583         all_of(CombinedIndex.getModuleHash(ModuleID),
584                [](uint32_t V) { return V == 0; }))
585       // Cache disabled or no entry for this module in the combined index or
586       // no module hash.
587       return RunThinBackend(AddStream);
588 
589     SmallString<40> Key;
590     // The module may be cached, this helps handling it.
591     computeCacheKey(Key, CombinedIndex, ModuleID, ImportList, ExportList,
592                     ResolvedODR, DefinedGlobals);
593     if (AddStreamFn CacheAddStream = Cache(Task, Key))
594       return RunThinBackend(CacheAddStream);
595 
596     return Error();
597   }
598 
599   Error start(
600       unsigned Task, MemoryBufferRef MBRef,
601       const FunctionImporter::ImportMapTy &ImportList,
602       const FunctionImporter::ExportSetTy &ExportList,
603       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
604       MapVector<StringRef, MemoryBufferRef> &ModuleMap) override {
605     StringRef ModulePath = MBRef.getBufferIdentifier();
606     assert(ModuleToDefinedGVSummaries.count(ModulePath));
607     const GVSummaryMapTy &DefinedGlobals =
608         ModuleToDefinedGVSummaries.find(ModulePath)->second;
609     BackendThreadPool.async(
610         [=](MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex,
611             const FunctionImporter::ImportMapTy &ImportList,
612             const FunctionImporter::ExportSetTy &ExportList,
613             const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
614                 &ResolvedODR,
615             const GVSummaryMapTy &DefinedGlobals,
616             MapVector<StringRef, MemoryBufferRef> &ModuleMap) {
617           Error E = runThinLTOBackendThread(
618               AddStream, Cache, Task, MBRef, CombinedIndex, ImportList,
619               ExportList, ResolvedODR, DefinedGlobals, ModuleMap);
620           if (E) {
621             std::unique_lock<std::mutex> L(ErrMu);
622             if (Err)
623               Err = joinErrors(std::move(*Err), std::move(E));
624             else
625               Err = std::move(E);
626           }
627         },
628         MBRef, std::ref(CombinedIndex), std::ref(ImportList),
629         std::ref(ExportList), std::ref(ResolvedODR), std::ref(DefinedGlobals),
630         std::ref(ModuleMap));
631     return Error();
632   }
633 
634   Error wait() override {
635     BackendThreadPool.wait();
636     if (Err)
637       return std::move(*Err);
638     else
639       return Error();
640   }
641 };
642 
643 ThinBackend lto::createInProcessThinBackend(unsigned ParallelismLevel) {
644   return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex,
645              const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
646              AddStreamFn AddStream, NativeObjectCache Cache) {
647     return llvm::make_unique<InProcessThinBackend>(
648         Conf, CombinedIndex, ParallelismLevel, ModuleToDefinedGVSummaries,
649         AddStream, Cache);
650   };
651 }
652 
653 // Given the original \p Path to an output file, replace any path
654 // prefix matching \p OldPrefix with \p NewPrefix. Also, create the
655 // resulting directory if it does not yet exist.
656 std::string lto::getThinLTOOutputFile(const std::string &Path,
657                                       const std::string &OldPrefix,
658                                       const std::string &NewPrefix) {
659   if (OldPrefix.empty() && NewPrefix.empty())
660     return Path;
661   SmallString<128> NewPath(Path);
662   llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
663   StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
664   if (!ParentPath.empty()) {
665     // Make sure the new directory exists, creating it if necessary.
666     if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
667       llvm::errs() << "warning: could not create directory '" << ParentPath
668                    << "': " << EC.message() << '\n';
669   }
670   return NewPath.str();
671 }
672 
673 class WriteIndexesThinBackend : public ThinBackendProc {
674   std::string OldPrefix, NewPrefix;
675   bool ShouldEmitImportsFiles;
676 
677   std::string LinkedObjectsFileName;
678   std::unique_ptr<llvm::raw_fd_ostream> LinkedObjectsFile;
679 
680 public:
681   WriteIndexesThinBackend(
682       Config &Conf, ModuleSummaryIndex &CombinedIndex,
683       const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
684       std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles,
685       std::string LinkedObjectsFileName)
686       : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries),
687         OldPrefix(OldPrefix), NewPrefix(NewPrefix),
688         ShouldEmitImportsFiles(ShouldEmitImportsFiles),
689         LinkedObjectsFileName(LinkedObjectsFileName) {}
690 
691   Error start(
692       unsigned Task, MemoryBufferRef MBRef,
693       const FunctionImporter::ImportMapTy &ImportList,
694       const FunctionImporter::ExportSetTy &ExportList,
695       const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
696       MapVector<StringRef, MemoryBufferRef> &ModuleMap) override {
697     StringRef ModulePath = MBRef.getBufferIdentifier();
698     std::string NewModulePath =
699         getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
700 
701     std::error_code EC;
702     if (!LinkedObjectsFileName.empty()) {
703       if (!LinkedObjectsFile) {
704         LinkedObjectsFile = llvm::make_unique<raw_fd_ostream>(
705             LinkedObjectsFileName, EC, sys::fs::OpenFlags::F_None);
706         if (EC)
707           return errorCodeToError(EC);
708       }
709       *LinkedObjectsFile << NewModulePath << '\n';
710     }
711 
712     std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
713     gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries,
714                                      ImportList, ModuleToSummariesForIndex);
715 
716     raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
717                       sys::fs::OpenFlags::F_None);
718     if (EC)
719       return errorCodeToError(EC);
720     WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex);
721 
722     if (ShouldEmitImportsFiles)
723       return errorCodeToError(
724           EmitImportsFiles(ModulePath, NewModulePath + ".imports", ImportList));
725     return Error();
726   }
727 
728   Error wait() override { return Error(); }
729 };
730 
731 ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix,
732                                                std::string NewPrefix,
733                                                bool ShouldEmitImportsFiles,
734                                                std::string LinkedObjectsFile) {
735   return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex,
736              const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
737              AddStreamFn AddStream, NativeObjectCache Cache) {
738     return llvm::make_unique<WriteIndexesThinBackend>(
739         Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix,
740         ShouldEmitImportsFiles, LinkedObjectsFile);
741   };
742 }
743 
744 Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
745                       bool HasRegularLTO) {
746   if (ThinLTO.ModuleMap.empty())
747     return Error();
748 
749   if (Conf.CombinedIndexHook && !Conf.CombinedIndexHook(ThinLTO.CombinedIndex))
750     return Error();
751 
752   // Collect for each module the list of function it defines (GUID ->
753   // Summary).
754   StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
755       ModuleToDefinedGVSummaries(ThinLTO.ModuleMap.size());
756   ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule(
757       ModuleToDefinedGVSummaries);
758   // Create entries for any modules that didn't have any GV summaries
759   // (either they didn't have any GVs to start with, or we suppressed
760   // generation of the summaries because they e.g. had inline assembly
761   // uses that couldn't be promoted/renamed on export). This is so
762   // InProcessThinBackend::start can still launch a backend thread, which
763   // is passed the map of summaries for the module, without any special
764   // handling for this case.
765   for (auto &Mod : ThinLTO.ModuleMap)
766     if (!ModuleToDefinedGVSummaries.count(Mod.first))
767       ModuleToDefinedGVSummaries.try_emplace(Mod.first);
768 
769   StringMap<FunctionImporter::ImportMapTy> ImportLists(
770       ThinLTO.ModuleMap.size());
771   StringMap<FunctionImporter::ExportSetTy> ExportLists(
772       ThinLTO.ModuleMap.size());
773   StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
774 
775   if (Conf.OptLevel > 0) {
776     ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
777                              ImportLists, ExportLists);
778 
779     std::set<GlobalValue::GUID> ExportedGUIDs;
780     for (auto &Res : GlobalResolutions) {
781       if (!Res.second.IRName.empty() &&
782           Res.second.Partition == GlobalResolution::External)
783         ExportedGUIDs.insert(GlobalValue::getGUID(Res.second.IRName));
784     }
785 
786     auto isPrevailing = [&](GlobalValue::GUID GUID,
787                             const GlobalValueSummary *S) {
788       return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath();
789     };
790     auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
791       const auto &ExportList = ExportLists.find(ModuleIdentifier);
792       return (ExportList != ExportLists.end() &&
793               ExportList->second.count(GUID)) ||
794              ExportedGUIDs.count(GUID);
795     };
796     thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported);
797 
798     auto recordNewLinkage = [&](StringRef ModuleIdentifier,
799                                 GlobalValue::GUID GUID,
800                                 GlobalValue::LinkageTypes NewLinkage) {
801       ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
802     };
803 
804     thinLTOResolveWeakForLinkerInIndex(ThinLTO.CombinedIndex, isPrevailing,
805                                        recordNewLinkage);
806   }
807 
808   std::unique_ptr<ThinBackendProc> BackendProc =
809       ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
810                       AddStream, Cache);
811 
812   // Partition numbers for ThinLTO jobs start at 1 (see comments for
813   // GlobalResolution in LTO.h). Task numbers, however, start at
814   // ParallelCodeGenParallelismLevel if an LTO module is present, as tasks 0
815   // through ParallelCodeGenParallelismLevel-1 are reserved for parallel code
816   // generation partitions.
817   unsigned Task =
818       HasRegularLTO ? RegularLTO.ParallelCodeGenParallelismLevel : 0;
819   unsigned Partition = 1;
820 
821   for (auto &Mod : ThinLTO.ModuleMap) {
822     if (Error E = BackendProc->start(Task, Mod.second, ImportLists[Mod.first],
823                                      ExportLists[Mod.first],
824                                      ResolvedODR[Mod.first], ThinLTO.ModuleMap))
825       return E;
826 
827     ++Task;
828     ++Partition;
829   }
830 
831   return BackendProc->wait();
832 }
833