1 //===-LTOBackend.cpp - LLVM Link Time Optimizer Backend -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the "backend" phase of LTO, i.e. it performs
10 // optimization and code generation on a loaded module. It is generally used
11 // internally by the LTO class but can also be used independently, for example
12 // to implement a standalone ThinLTO backend.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/LTO/LTOBackend.h"
17 #include "llvm/Analysis/AliasAnalysis.h"
18 #include "llvm/Analysis/CGSCCPassManager.h"
19 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
20 #include "llvm/Analysis/TargetLibraryInfo.h"
21 #include "llvm/Analysis/TargetTransformInfo.h"
22 #include "llvm/Bitcode/BitcodeReader.h"
23 #include "llvm/Bitcode/BitcodeWriter.h"
24 #include "llvm/IR/LLVMRemarkStreamer.h"
25 #include "llvm/IR/LegacyPassManager.h"
26 #include "llvm/IR/PassManager.h"
27 #include "llvm/IR/Verifier.h"
28 #include "llvm/LTO/LTO.h"
29 #include "llvm/MC/SubtargetFeature.h"
30 #include "llvm/Object/ModuleSymbolTable.h"
31 #include "llvm/Passes/PassBuilder.h"
32 #include "llvm/Passes/PassPlugin.h"
33 #include "llvm/Passes/StandardInstrumentations.h"
34 #include "llvm/Support/Error.h"
35 #include "llvm/Support/FileSystem.h"
36 #include "llvm/Support/MemoryBuffer.h"
37 #include "llvm/Support/Path.h"
38 #include "llvm/Support/Program.h"
39 #include "llvm/Support/SmallVectorMemoryBuffer.h"
40 #include "llvm/Support/TargetRegistry.h"
41 #include "llvm/Support/ThreadPool.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Transforms/IPO.h"
45 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
46 #include "llvm/Transforms/Scalar/LoopPassManager.h"
47 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
48 #include "llvm/Transforms/Utils/SplitModule.h"
49 
50 using namespace llvm;
51 using namespace lto;
52 
53 #define DEBUG_TYPE "lto-backend"
54 
55 enum class LTOBitcodeEmbedding {
56   DoNotEmbed = 0,
57   EmbedOptimized = 1,
58   EmbedPostMergePreOptimized = 2
59 };
60 
61 static cl::opt<LTOBitcodeEmbedding> EmbedBitcode(
62     "lto-embed-bitcode", cl::init(LTOBitcodeEmbedding::DoNotEmbed),
63     cl::values(clEnumValN(LTOBitcodeEmbedding::DoNotEmbed, "none",
64                           "Do not embed"),
65                clEnumValN(LTOBitcodeEmbedding::EmbedOptimized, "optimized",
66                           "Embed after all optimization passes"),
67                clEnumValN(LTOBitcodeEmbedding::EmbedPostMergePreOptimized,
68                           "post-merge-pre-opt",
69                           "Embed post merge, but before optimizations")),
70     cl::desc("Embed LLVM bitcode in object files produced by LTO"));
71 
72 LLVM_ATTRIBUTE_NORETURN static void reportOpenError(StringRef Path, Twine Msg) {
73   errs() << "failed to open " << Path << ": " << Msg << '\n';
74   errs().flush();
75   exit(1);
76 }
77 
78 Error Config::addSaveTemps(std::string OutputFileName,
79                            bool UseInputModulePath) {
80   ShouldDiscardValueNames = false;
81 
82   std::error_code EC;
83   ResolutionFile = std::make_unique<raw_fd_ostream>(
84       OutputFileName + "resolution.txt", EC, sys::fs::OpenFlags::OF_Text);
85   if (EC) {
86     ResolutionFile.reset();
87     return errorCodeToError(EC);
88   }
89 
90   auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) {
91     // Keep track of the hook provided by the linker, which also needs to run.
92     ModuleHookFn LinkerHook = Hook;
93     Hook = [=](unsigned Task, const Module &M) {
94       // If the linker's hook returned false, we need to pass that result
95       // through.
96       if (LinkerHook && !LinkerHook(Task, M))
97         return false;
98 
99       std::string PathPrefix;
100       // If this is the combined module (not a ThinLTO backend compile) or the
101       // user hasn't requested using the input module's path, emit to a file
102       // named from the provided OutputFileName with the Task ID appended.
103       if (M.getModuleIdentifier() == "ld-temp.o" || !UseInputModulePath) {
104         PathPrefix = OutputFileName;
105         if (Task != (unsigned)-1)
106           PathPrefix += utostr(Task) + ".";
107       } else
108         PathPrefix = M.getModuleIdentifier() + ".";
109       std::string Path = PathPrefix + PathSuffix + ".bc";
110       std::error_code EC;
111       raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::OF_None);
112       // Because -save-temps is a debugging feature, we report the error
113       // directly and exit.
114       if (EC)
115         reportOpenError(Path, EC.message());
116       WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false);
117       return true;
118     };
119   };
120 
121   setHook("0.preopt", PreOptModuleHook);
122   setHook("1.promote", PostPromoteModuleHook);
123   setHook("2.internalize", PostInternalizeModuleHook);
124   setHook("3.import", PostImportModuleHook);
125   setHook("4.opt", PostOptModuleHook);
126   setHook("5.precodegen", PreCodeGenModuleHook);
127 
128   CombinedIndexHook =
129       [=](const ModuleSummaryIndex &Index,
130           const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
131         std::string Path = OutputFileName + "index.bc";
132         std::error_code EC;
133         raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::OF_None);
134         // Because -save-temps is a debugging feature, we report the error
135         // directly and exit.
136         if (EC)
137           reportOpenError(Path, EC.message());
138         WriteIndexToFile(Index, OS);
139 
140         Path = OutputFileName + "index.dot";
141         raw_fd_ostream OSDot(Path, EC, sys::fs::OpenFlags::OF_None);
142         if (EC)
143           reportOpenError(Path, EC.message());
144         Index.exportToDot(OSDot, GUIDPreservedSymbols);
145         return true;
146       };
147 
148   return Error::success();
149 }
150 
151 #define HANDLE_EXTENSION(Ext)                                                  \
152   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
153 #include "llvm/Support/Extension.def"
154 
155 static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins,
156                                 PassBuilder &PB) {
157 #define HANDLE_EXTENSION(Ext)                                                  \
158   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
159 #include "llvm/Support/Extension.def"
160 
161   // Load requested pass plugins and let them register pass builder callbacks
162   for (auto &PluginFN : PassPlugins) {
163     auto PassPlugin = PassPlugin::Load(PluginFN);
164     if (!PassPlugin) {
165       errs() << "Failed to load passes from '" << PluginFN
166              << "'. Request ignored.\n";
167       continue;
168     }
169 
170     PassPlugin->registerPassBuilderCallbacks(PB);
171   }
172 }
173 
174 namespace {
175 
176 std::unique_ptr<TargetMachine>
177 createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
178   StringRef TheTriple = M.getTargetTriple();
179   SubtargetFeatures Features;
180   Features.getDefaultSubtargetFeatures(Triple(TheTriple));
181   for (const std::string &A : Conf.MAttrs)
182     Features.AddFeature(A);
183 
184   Reloc::Model RelocModel;
185   if (Conf.RelocModel)
186     RelocModel = *Conf.RelocModel;
187   else
188     RelocModel =
189         M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_;
190 
191   Optional<CodeModel::Model> CodeModel;
192   if (Conf.CodeModel)
193     CodeModel = *Conf.CodeModel;
194   else
195     CodeModel = M.getCodeModel();
196 
197   return std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
198       TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel,
199       CodeModel, Conf.CGOptLevel));
200 }
201 
202 static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
203                            unsigned OptLevel, bool IsThinLTO,
204                            ModuleSummaryIndex *ExportSummary,
205                            const ModuleSummaryIndex *ImportSummary) {
206   Optional<PGOOptions> PGOOpt;
207   if (!Conf.SampleProfile.empty())
208     PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping,
209                         PGOOptions::SampleUse, PGOOptions::NoCSAction, true);
210   else if (Conf.RunCSIRInstr) {
211     PGOOpt = PGOOptions("", Conf.CSIRProfile, Conf.ProfileRemapping,
212                         PGOOptions::IRUse, PGOOptions::CSIRInstr);
213   } else if (!Conf.CSIRProfile.empty()) {
214     PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping,
215                         PGOOptions::IRUse, PGOOptions::CSIRUse);
216   }
217 
218   PassInstrumentationCallbacks PIC;
219   StandardInstrumentations SI(Conf.DebugPassManager);
220   SI.registerCallbacks(PIC);
221   PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);
222   AAManager AA;
223 
224   // Parse a custom AA pipeline if asked to.
225   if (auto Err = PB.parseAAPipeline(AA, "default"))
226     report_fatal_error("Error parsing default AA pipeline");
227 
228   RegisterPassPlugins(Conf.PassPlugins, PB);
229 
230   LoopAnalysisManager LAM(Conf.DebugPassManager);
231   FunctionAnalysisManager FAM(Conf.DebugPassManager);
232   CGSCCAnalysisManager CGAM(Conf.DebugPassManager);
233   ModuleAnalysisManager MAM(Conf.DebugPassManager);
234 
235   // Register the AA manager first so that our version is the one used.
236   FAM.registerPass([&] { return std::move(AA); });
237 
238   // Register all the basic analyses with the managers.
239   PB.registerModuleAnalyses(MAM);
240   PB.registerCGSCCAnalyses(CGAM);
241   PB.registerFunctionAnalyses(FAM);
242   PB.registerLoopAnalyses(LAM);
243   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
244 
245   ModulePassManager MPM(Conf.DebugPassManager);
246   // FIXME (davide): verify the input.
247 
248   PassBuilder::OptimizationLevel OL;
249 
250   switch (OptLevel) {
251   default:
252     llvm_unreachable("Invalid optimization level");
253   case 0:
254     OL = PassBuilder::OptimizationLevel::O0;
255     break;
256   case 1:
257     OL = PassBuilder::OptimizationLevel::O1;
258     break;
259   case 2:
260     OL = PassBuilder::OptimizationLevel::O2;
261     break;
262   case 3:
263     OL = PassBuilder::OptimizationLevel::O3;
264     break;
265   }
266 
267   if (IsThinLTO)
268     MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager,
269                                          ImportSummary);
270   else
271     MPM = PB.buildLTODefaultPipeline(OL, Conf.DebugPassManager, ExportSummary);
272   MPM.run(Mod, MAM);
273 
274   // FIXME (davide): verify the output.
275 }
276 
277 static void runNewPMCustomPasses(const Config &Conf, Module &Mod,
278                                  TargetMachine *TM, std::string PipelineDesc,
279                                  std::string AAPipelineDesc,
280                                  bool DisableVerify) {
281   PassBuilder PB(TM);
282   AAManager AA;
283 
284   // Parse a custom AA pipeline if asked to.
285   if (!AAPipelineDesc.empty())
286     if (auto Err = PB.parseAAPipeline(AA, AAPipelineDesc))
287       report_fatal_error("unable to parse AA pipeline description '" +
288                          AAPipelineDesc + "': " + toString(std::move(Err)));
289 
290   RegisterPassPlugins(Conf.PassPlugins, PB);
291 
292   LoopAnalysisManager LAM;
293   FunctionAnalysisManager FAM;
294   CGSCCAnalysisManager CGAM;
295   ModuleAnalysisManager MAM;
296 
297   // Register the AA manager first so that our version is the one used.
298   FAM.registerPass([&] { return std::move(AA); });
299 
300   // Register all the basic analyses with the managers.
301   PB.registerModuleAnalyses(MAM);
302   PB.registerCGSCCAnalyses(CGAM);
303   PB.registerFunctionAnalyses(FAM);
304   PB.registerLoopAnalyses(LAM);
305   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
306 
307   ModulePassManager MPM;
308 
309   // Always verify the input.
310   MPM.addPass(VerifierPass());
311 
312   // Now, add all the passes we've been requested to.
313   if (auto Err = PB.parsePassPipeline(MPM, PipelineDesc))
314     report_fatal_error("unable to parse pass pipeline description '" +
315                        PipelineDesc + "': " + toString(std::move(Err)));
316 
317   if (!DisableVerify)
318     MPM.addPass(VerifierPass());
319   MPM.run(Mod, MAM);
320 }
321 
322 static void runOldPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
323                            bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
324                            const ModuleSummaryIndex *ImportSummary) {
325   legacy::PassManager passes;
326   passes.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
327 
328   PassManagerBuilder PMB;
329   PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple()));
330   PMB.Inliner = createFunctionInliningPass();
331   PMB.ExportSummary = ExportSummary;
332   PMB.ImportSummary = ImportSummary;
333   // Unconditionally verify input since it is not verified before this
334   // point and has unknown origin.
335   PMB.VerifyInput = true;
336   PMB.VerifyOutput = !Conf.DisableVerify;
337   PMB.LoopVectorize = true;
338   PMB.SLPVectorize = true;
339   PMB.OptLevel = Conf.OptLevel;
340   PMB.PGOSampleUse = Conf.SampleProfile;
341   PMB.EnablePGOCSInstrGen = Conf.RunCSIRInstr;
342   if (!Conf.RunCSIRInstr && !Conf.CSIRProfile.empty()) {
343     PMB.EnablePGOCSInstrUse = true;
344     PMB.PGOInstrUse = Conf.CSIRProfile;
345   }
346   if (IsThinLTO)
347     PMB.populateThinLTOPassManager(passes);
348   else
349     PMB.populateLTOPassManager(passes);
350   passes.run(Mod);
351 }
352 
353 bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
354          bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
355          const ModuleSummaryIndex *ImportSummary,
356          const std::vector<uint8_t> *CmdArgs = nullptr) {
357   if (EmbedBitcode == LTOBitcodeEmbedding::EmbedPostMergePreOptimized) {
358     // FIXME: the motivation for capturing post-merge bitcode and command line
359     // is replicating the compilation environment from bitcode, without needing
360     // to understand the dependencies (the functions to be imported). This
361     // assumes a clang - based invocation, case in which we have the command
362     // line.
363     // It's not very clear how the above motivation would map in the
364     // linker-based case, so we currently don't plumb the command line args in
365     // that case.
366     if (CmdArgs == nullptr)
367       LLVM_DEBUG(
368           dbgs() << "Post-(Thin)LTO merge bitcode embedding was requested, but "
369                     "command line arguments are not available");
370     llvm::EmbedBitcodeInModule(Mod, llvm::MemoryBufferRef(),
371                                /*EmbedBitcode*/ true,
372                                /*EmbedMarker*/ false, CmdArgs);
373   }
374   // FIXME: Plumb the combined index into the new pass manager.
375   if (!Conf.OptPipeline.empty())
376     runNewPMCustomPasses(Conf, Mod, TM, Conf.OptPipeline, Conf.AAPipeline,
377                          Conf.DisableVerify);
378   else if (Conf.UseNewPM)
379     runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
380                    ImportSummary);
381   else
382     runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
383   return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
384 }
385 
386 void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream,
387              unsigned Task, Module &Mod,
388              const ModuleSummaryIndex &CombinedIndex) {
389   if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod))
390     return;
391 
392   if (EmbedBitcode == LTOBitcodeEmbedding::EmbedOptimized)
393     llvm::EmbedBitcodeInModule(Mod, llvm::MemoryBufferRef(),
394                                /*EmbedBitcode*/ true,
395                                /*EmbedMarker*/ false, /*CmdArgs*/ nullptr);
396 
397   std::unique_ptr<ToolOutputFile> DwoOut;
398   SmallString<1024> DwoFile(Conf.SplitDwarfOutput);
399   if (!Conf.DwoDir.empty()) {
400     std::error_code EC;
401     if (auto EC = llvm::sys::fs::create_directories(Conf.DwoDir))
402       report_fatal_error("Failed to create directory " + Conf.DwoDir + ": " +
403                          EC.message());
404 
405     DwoFile = Conf.DwoDir;
406     sys::path::append(DwoFile, std::to_string(Task) + ".dwo");
407     TM->Options.MCOptions.SplitDwarfFile = std::string(DwoFile);
408   } else
409     TM->Options.MCOptions.SplitDwarfFile = Conf.SplitDwarfFile;
410 
411   if (!DwoFile.empty()) {
412     std::error_code EC;
413     DwoOut = std::make_unique<ToolOutputFile>(DwoFile, EC, sys::fs::OF_None);
414     if (EC)
415       report_fatal_error("Failed to open " + DwoFile + ": " + EC.message());
416   }
417 
418   auto Stream = AddStream(Task);
419   legacy::PassManager CodeGenPasses;
420   CodeGenPasses.add(
421       createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex));
422   if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,
423                               DwoOut ? &DwoOut->os() : nullptr,
424                               Conf.CGFileType))
425     report_fatal_error("Failed to setup codegen");
426   CodeGenPasses.run(Mod);
427 
428   if (DwoOut)
429     DwoOut->keep();
430 }
431 
432 void splitCodeGen(const Config &C, TargetMachine *TM, AddStreamFn AddStream,
433                   unsigned ParallelCodeGenParallelismLevel,
434                   std::unique_ptr<Module> Mod,
435                   const ModuleSummaryIndex &CombinedIndex) {
436   ThreadPool CodegenThreadPool(
437       heavyweight_hardware_concurrency(ParallelCodeGenParallelismLevel));
438   unsigned ThreadCount = 0;
439   const Target *T = &TM->getTarget();
440 
441   SplitModule(
442       std::move(Mod), ParallelCodeGenParallelismLevel,
443       [&](std::unique_ptr<Module> MPart) {
444         // We want to clone the module in a new context to multi-thread the
445         // codegen. We do it by serializing partition modules to bitcode
446         // (while still on the main thread, in order to avoid data races) and
447         // spinning up new threads which deserialize the partitions into
448         // separate contexts.
449         // FIXME: Provide a more direct way to do this in LLVM.
450         SmallString<0> BC;
451         raw_svector_ostream BCOS(BC);
452         WriteBitcodeToFile(*MPart, BCOS);
453 
454         // Enqueue the task
455         CodegenThreadPool.async(
456             [&](const SmallString<0> &BC, unsigned ThreadId) {
457               LTOLLVMContext Ctx(C);
458               Expected<std::unique_ptr<Module>> MOrErr = parseBitcodeFile(
459                   MemoryBufferRef(StringRef(BC.data(), BC.size()), "ld-temp.o"),
460                   Ctx);
461               if (!MOrErr)
462                 report_fatal_error("Failed to read bitcode");
463               std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());
464 
465               std::unique_ptr<TargetMachine> TM =
466                   createTargetMachine(C, T, *MPartInCtx);
467 
468               codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
469                       CombinedIndex);
470             },
471             // Pass BC using std::move to ensure that it get moved rather than
472             // copied into the thread's context.
473             std::move(BC), ThreadCount++);
474       },
475       false);
476 
477   // Because the inner lambda (which runs in a worker thread) captures our local
478   // variables, we need to wait for the worker threads to terminate before we
479   // can leave the function scope.
480   CodegenThreadPool.wait();
481 }
482 
483 Expected<const Target *> initAndLookupTarget(const Config &C, Module &Mod) {
484   if (!C.OverrideTriple.empty())
485     Mod.setTargetTriple(C.OverrideTriple);
486   else if (Mod.getTargetTriple().empty())
487     Mod.setTargetTriple(C.DefaultTriple);
488 
489   std::string Msg;
490   const Target *T = TargetRegistry::lookupTarget(Mod.getTargetTriple(), Msg);
491   if (!T)
492     return make_error<StringError>(Msg, inconvertibleErrorCode());
493   return T;
494 }
495 }
496 
497 Error lto::finalizeOptimizationRemarks(
498     std::unique_ptr<ToolOutputFile> DiagOutputFile) {
499   // Make sure we flush the diagnostic remarks file in case the linker doesn't
500   // call the global destructors before exiting.
501   if (!DiagOutputFile)
502     return Error::success();
503   DiagOutputFile->keep();
504   DiagOutputFile->os().flush();
505   return Error::success();
506 }
507 
508 Error lto::backend(const Config &C, AddStreamFn AddStream,
509                    unsigned ParallelCodeGenParallelismLevel,
510                    std::unique_ptr<Module> Mod,
511                    ModuleSummaryIndex &CombinedIndex) {
512   Expected<const Target *> TOrErr = initAndLookupTarget(C, *Mod);
513   if (!TOrErr)
514     return TOrErr.takeError();
515 
516   std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod);
517 
518   if (!C.CodeGenOnly) {
519     if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false,
520              /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr))
521       return Error::success();
522   }
523 
524   if (ParallelCodeGenParallelismLevel == 1) {
525     codegen(C, TM.get(), AddStream, 0, *Mod, CombinedIndex);
526   } else {
527     splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel,
528                  std::move(Mod), CombinedIndex);
529   }
530   return Error::success();
531 }
532 
533 static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals,
534                             const ModuleSummaryIndex &Index) {
535   std::vector<GlobalValue*> DeadGVs;
536   for (auto &GV : Mod.global_values())
537     if (GlobalValueSummary *GVS = DefinedGlobals.lookup(GV.getGUID()))
538       if (!Index.isGlobalValueLive(GVS)) {
539         DeadGVs.push_back(&GV);
540         convertToDeclaration(GV);
541       }
542 
543   // Now that all dead bodies have been dropped, delete the actual objects
544   // themselves when possible.
545   for (GlobalValue *GV : DeadGVs) {
546     GV->removeDeadConstantUsers();
547     // Might reference something defined in native object (i.e. dropped a
548     // non-prevailing IR def, but we need to keep the declaration).
549     if (GV->use_empty())
550       GV->eraseFromParent();
551   }
552 }
553 
554 Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
555                        Module &Mod, const ModuleSummaryIndex &CombinedIndex,
556                        const FunctionImporter::ImportMapTy &ImportList,
557                        const GVSummaryMapTy &DefinedGlobals,
558                        MapVector<StringRef, BitcodeModule> &ModuleMap,
559                        const std::vector<uint8_t> *CmdArgs) {
560   Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
561   if (!TOrErr)
562     return TOrErr.takeError();
563 
564   std::unique_ptr<TargetMachine> TM = createTargetMachine(Conf, *TOrErr, Mod);
565 
566   // Setup optimization remarks.
567   auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
568       Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
569       Conf.RemarksFormat, Conf.RemarksWithHotness, Task);
570   if (!DiagFileOrErr)
571     return DiagFileOrErr.takeError();
572   auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
573 
574   // Set the partial sample profile ratio in the profile summary module flag of
575   // the module, if applicable.
576   Mod.setPartialSampleProfileRatio(CombinedIndex);
577 
578   if (Conf.CodeGenOnly) {
579     codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
580     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
581   }
582 
583   if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
584     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
585 
586   // When linking an ELF shared object, dso_local should be dropped. We
587   // conservatively do this for -fpic.
588   bool ClearDSOLocalOnDeclarations =
589       TM->getTargetTriple().isOSBinFormatELF() &&
590       TM->getRelocationModel() != Reloc::Static &&
591       Mod.getPIELevel() == PIELevel::Default;
592   renameModuleForThinLTO(Mod, CombinedIndex, ClearDSOLocalOnDeclarations);
593 
594   dropDeadSymbols(Mod, DefinedGlobals, CombinedIndex);
595 
596   thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
597 
598   if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod))
599     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
600 
601   if (!DefinedGlobals.empty())
602     thinLTOInternalizeModule(Mod, DefinedGlobals);
603 
604   if (Conf.PostInternalizeModuleHook &&
605       !Conf.PostInternalizeModuleHook(Task, Mod))
606     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
607 
608   auto ModuleLoader = [&](StringRef Identifier) {
609     assert(Mod.getContext().isODRUniquingDebugTypes() &&
610            "ODR Type uniquing should be enabled on the context");
611     auto I = ModuleMap.find(Identifier);
612     assert(I != ModuleMap.end());
613     return I->second.getLazyModule(Mod.getContext(),
614                                    /*ShouldLazyLoadMetadata=*/true,
615                                    /*IsImporting*/ true);
616   };
617 
618   FunctionImporter Importer(CombinedIndex, ModuleLoader,
619                             ClearDSOLocalOnDeclarations);
620   if (Error Err = Importer.importFunctions(Mod, ImportList).takeError())
621     return Err;
622 
623   if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
624     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
625 
626   if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true,
627            /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
628            CmdArgs))
629     return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
630 
631   codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
632   return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
633 }
634