xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-lto/llvm-lto.cpp (revision 924226fba12cc9a228c73b956e1b7fa24c60b055)
1 //===- llvm-lto: a simple command-line program to link modules with LTO ---===//
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 program takes in a list of bitcode files, links them, performs link-time
10 // optimization, and outputs an object file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm-c/lto.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSet.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/Bitcode/BitcodeReader.h"
23 #include "llvm/Bitcode/BitcodeWriter.h"
24 #include "llvm/CodeGen/CommandFlags.h"
25 #include "llvm/IR/DiagnosticInfo.h"
26 #include "llvm/IR/DiagnosticPrinter.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/ModuleSummaryIndex.h"
30 #include "llvm/IR/Verifier.h"
31 #include "llvm/IRReader/IRReader.h"
32 #include "llvm/LTO/legacy/LTOCodeGenerator.h"
33 #include "llvm/LTO/legacy/LTOModule.h"
34 #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h"
35 #include "llvm/Support/Allocator.h"
36 #include "llvm/Support/Casting.h"
37 #include "llvm/Support/CommandLine.h"
38 #include "llvm/Support/Error.h"
39 #include "llvm/Support/ErrorHandling.h"
40 #include "llvm/Support/ErrorOr.h"
41 #include "llvm/Support/FileSystem.h"
42 #include "llvm/Support/InitLLVM.h"
43 #include "llvm/Support/MemoryBuffer.h"
44 #include "llvm/Support/Path.h"
45 #include "llvm/Support/SourceMgr.h"
46 #include "llvm/Support/TargetSelect.h"
47 #include "llvm/Support/ToolOutputFile.h"
48 #include "llvm/Support/raw_ostream.h"
49 #include "llvm/Support/WithColor.h"
50 #include "llvm/Target/TargetOptions.h"
51 #include <algorithm>
52 #include <cassert>
53 #include <cstdint>
54 #include <cstdlib>
55 #include <list>
56 #include <map>
57 #include <memory>
58 #include <string>
59 #include <system_error>
60 #include <tuple>
61 #include <utility>
62 #include <vector>
63 
64 using namespace llvm;
65 
66 static codegen::RegisterCodeGenFlags CGF;
67 
68 static cl::OptionCategory LTOCategory("LTO Options");
69 
70 static cl::opt<char>
71     OptLevel("O",
72              cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
73                       "(default = '-O2')"),
74              cl::Prefix, cl::ZeroOrMore, cl::init('2'), cl::cat(LTOCategory));
75 
76 static cl::opt<bool>
77     IndexStats("thinlto-index-stats",
78                cl::desc("Print statistic for the index in every input files"),
79                cl::init(false), cl::cat(LTOCategory));
80 
81 static cl::opt<bool> DisableVerify(
82     "disable-verify", cl::init(false),
83     cl::desc("Do not run the verifier during the optimization pipeline"),
84     cl::cat(LTOCategory));
85 
86 static cl::opt<bool> EnableFreestanding(
87     "lto-freestanding", cl::init(false),
88     cl::desc("Enable Freestanding (disable builtins / TLI) during LTO"),
89     cl::cat(LTOCategory));
90 
91 static cl::opt<bool> UseDiagnosticHandler(
92     "use-diagnostic-handler", cl::init(false),
93     cl::desc("Use a diagnostic handler to test the handler interface"),
94     cl::cat(LTOCategory));
95 
96 static cl::opt<bool>
97     ThinLTO("thinlto", cl::init(false),
98             cl::desc("Only write combined global index for ThinLTO backends"),
99             cl::cat(LTOCategory));
100 
101 enum ThinLTOModes {
102   THINLINK,
103   THINDISTRIBUTE,
104   THINEMITIMPORTS,
105   THINPROMOTE,
106   THINIMPORT,
107   THININTERNALIZE,
108   THINOPT,
109   THINCODEGEN,
110   THINALL
111 };
112 
113 cl::opt<ThinLTOModes> ThinLTOMode(
114     "thinlto-action", cl::desc("Perform a single ThinLTO stage:"),
115     cl::values(
116         clEnumValN(
117             THINLINK, "thinlink",
118             "ThinLink: produces the index by linking only the summaries."),
119         clEnumValN(THINDISTRIBUTE, "distributedindexes",
120                    "Produces individual indexes for distributed backends."),
121         clEnumValN(THINEMITIMPORTS, "emitimports",
122                    "Emit imports files for distributed backends."),
123         clEnumValN(THINPROMOTE, "promote",
124                    "Perform pre-import promotion (requires -thinlto-index)."),
125         clEnumValN(THINIMPORT, "import",
126                    "Perform both promotion and "
127                    "cross-module importing (requires "
128                    "-thinlto-index)."),
129         clEnumValN(THININTERNALIZE, "internalize",
130                    "Perform internalization driven by -exported-symbol "
131                    "(requires -thinlto-index)."),
132         clEnumValN(THINOPT, "optimize", "Perform ThinLTO optimizations."),
133         clEnumValN(THINCODEGEN, "codegen", "CodeGen (expected to match llc)"),
134         clEnumValN(THINALL, "run", "Perform ThinLTO end-to-end")),
135     cl::cat(LTOCategory));
136 
137 static cl::opt<std::string>
138     ThinLTOIndex("thinlto-index",
139                  cl::desc("Provide the index produced by a ThinLink, required "
140                           "to perform the promotion and/or importing."),
141                  cl::cat(LTOCategory));
142 
143 static cl::opt<std::string> ThinLTOPrefixReplace(
144     "thinlto-prefix-replace",
145     cl::desc("Control where files for distributed backends are "
146              "created. Expects 'oldprefix;newprefix' and if path "
147              "prefix of output file is oldprefix it will be "
148              "replaced with newprefix."),
149     cl::cat(LTOCategory));
150 
151 static cl::opt<std::string> ThinLTOModuleId(
152     "thinlto-module-id",
153     cl::desc("For the module ID for the file to process, useful to "
154              "match what is in the index."),
155     cl::cat(LTOCategory));
156 
157 static cl::opt<std::string> ThinLTOCacheDir("thinlto-cache-dir",
158                                             cl::desc("Enable ThinLTO caching."),
159                                             cl::cat(LTOCategory));
160 
161 static cl::opt<int> ThinLTOCachePruningInterval(
162     "thinlto-cache-pruning-interval", cl::init(1200),
163     cl::desc("Set ThinLTO cache pruning interval."), cl::cat(LTOCategory));
164 
165 static cl::opt<uint64_t> ThinLTOCacheMaxSizeBytes(
166     "thinlto-cache-max-size-bytes",
167     cl::desc("Set ThinLTO cache pruning directory maximum size in bytes."),
168     cl::cat(LTOCategory));
169 
170 static cl::opt<int> ThinLTOCacheMaxSizeFiles(
171     "thinlto-cache-max-size-files", cl::init(1000000),
172     cl::desc("Set ThinLTO cache pruning directory maximum number of files."),
173     cl::cat(LTOCategory));
174 
175 static cl::opt<unsigned> ThinLTOCacheEntryExpiration(
176     "thinlto-cache-entry-expiration", cl::init(604800) /* 1w */,
177     cl::desc("Set ThinLTO cache entry expiration time."), cl::cat(LTOCategory));
178 
179 static cl::opt<std::string> ThinLTOSaveTempsPrefix(
180     "thinlto-save-temps",
181     cl::desc("Save ThinLTO temp files using filenames created by adding "
182              "suffixes to the given file path prefix."),
183     cl::cat(LTOCategory));
184 
185 static cl::opt<std::string> ThinLTOGeneratedObjectsDir(
186     "thinlto-save-objects",
187     cl::desc("Save ThinLTO generated object files using filenames created in "
188              "the given directory."),
189     cl::cat(LTOCategory));
190 
191 static cl::opt<bool> SaveLinkedModuleFile(
192     "save-linked-module", cl::init(false),
193     cl::desc("Write linked LTO module to file before optimize"),
194     cl::cat(LTOCategory));
195 
196 static cl::opt<bool>
197     SaveModuleFile("save-merged-module", cl::init(false),
198                    cl::desc("Write merged LTO module to file before CodeGen"),
199                    cl::cat(LTOCategory));
200 
201 static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore,
202                                             cl::desc("<input bitcode files>"),
203                                             cl::cat(LTOCategory));
204 
205 static cl::opt<std::string> OutputFilename("o", cl::init(""),
206                                            cl::desc("Override output filename"),
207                                            cl::value_desc("filename"),
208                                            cl::cat(LTOCategory));
209 
210 static cl::list<std::string> ExportedSymbols(
211     "exported-symbol",
212     cl::desc("List of symbols to export from the resulting object file"),
213     cl::ZeroOrMore, cl::cat(LTOCategory));
214 
215 static cl::list<std::string>
216     DSOSymbols("dso-symbol",
217                cl::desc("Symbol to put in the symtab in the resulting dso"),
218                cl::ZeroOrMore, cl::cat(LTOCategory));
219 
220 static cl::opt<bool> ListSymbolsOnly(
221     "list-symbols-only", cl::init(false),
222     cl::desc("Instead of running LTO, list the symbols in each IR file"),
223     cl::cat(LTOCategory));
224 
225 static cl::opt<bool> ListDependentLibrariesOnly(
226     "list-dependent-libraries-only", cl::init(false),
227     cl::desc(
228         "Instead of running LTO, list the dependent libraries in each IR file"),
229     cl::cat(LTOCategory));
230 
231 static cl::opt<bool> QueryHasCtorDtor(
232     "query-hasCtorDtor", cl::init(false),
233     cl::desc("Queries LTOModule::hasCtorDtor() on each IR file"));
234 
235 static cl::opt<bool>
236     SetMergedModule("set-merged-module", cl::init(false),
237                     cl::desc("Use the first input module as the merged module"),
238                     cl::cat(LTOCategory));
239 
240 static cl::opt<unsigned> Parallelism("j", cl::Prefix, cl::init(1),
241                                      cl::desc("Number of backend threads"),
242                                      cl::cat(LTOCategory));
243 
244 static cl::opt<bool> RestoreGlobalsLinkage(
245     "restore-linkage", cl::init(false),
246     cl::desc("Restore original linkage of globals prior to CodeGen"),
247     cl::cat(LTOCategory));
248 
249 static cl::opt<bool> CheckHasObjC(
250     "check-for-objc", cl::init(false),
251     cl::desc("Only check if the module has objective-C defined in it"),
252     cl::cat(LTOCategory));
253 
254 static cl::opt<bool> PrintMachOCPUOnly(
255     "print-macho-cpu-only", cl::init(false),
256     cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"),
257     cl::cat(LTOCategory));
258 
259 static cl::opt<bool> UseNewPM(
260     "use-new-pm", cl::desc("Run LTO passes using the new pass manager"),
261     cl::init(LLVM_ENABLE_NEW_PASS_MANAGER), cl::Hidden, cl::cat(LTOCategory));
262 
263 static cl::opt<bool>
264     DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden,
265                      cl::desc("Print pass management debugging information"),
266                      cl::cat(LTOCategory));
267 
268 namespace {
269 
270 struct ModuleInfo {
271   BitVector CanBeHidden;
272 };
273 
274 } // end anonymous namespace
275 
276 static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity,
277                               const char *Msg, void *) {
278   errs() << "llvm-lto: ";
279   switch (Severity) {
280   case LTO_DS_NOTE:
281     errs() << "note: ";
282     break;
283   case LTO_DS_REMARK:
284     errs() << "remark: ";
285     break;
286   case LTO_DS_ERROR:
287     errs() << "error: ";
288     break;
289   case LTO_DS_WARNING:
290     errs() << "warning: ";
291     break;
292   }
293   errs() << Msg << "\n";
294 }
295 
296 static std::string CurrentActivity;
297 
298 namespace {
299   struct LLVMLTODiagnosticHandler : public DiagnosticHandler {
300     bool handleDiagnostics(const DiagnosticInfo &DI) override {
301       raw_ostream &OS = errs();
302       OS << "llvm-lto: ";
303       switch (DI.getSeverity()) {
304       case DS_Error:
305         OS << "error";
306         break;
307       case DS_Warning:
308         OS << "warning";
309         break;
310       case DS_Remark:
311         OS << "remark";
312         break;
313       case DS_Note:
314         OS << "note";
315         break;
316       }
317       if (!CurrentActivity.empty())
318         OS << ' ' << CurrentActivity;
319       OS << ": ";
320 
321       DiagnosticPrinterRawOStream DP(OS);
322       DI.print(DP);
323       OS << '\n';
324 
325       if (DI.getSeverity() == DS_Error)
326         exit(1);
327       return true;
328     }
329   };
330   }
331 
332 static void error(const Twine &Msg) {
333   errs() << "llvm-lto: " << Msg << '\n';
334   exit(1);
335 }
336 
337 static void error(std::error_code EC, const Twine &Prefix) {
338   if (EC)
339     error(Prefix + ": " + EC.message());
340 }
341 
342 template <typename T>
343 static void error(const ErrorOr<T> &V, const Twine &Prefix) {
344   error(V.getError(), Prefix);
345 }
346 
347 static void maybeVerifyModule(const Module &Mod) {
348   if (!DisableVerify && verifyModule(Mod, &errs()))
349     error("Broken Module");
350 }
351 
352 static std::unique_ptr<LTOModule>
353 getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer,
354                   const TargetOptions &Options) {
355   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
356       MemoryBuffer::getFile(Path);
357   error(BufferOrErr, "error loading file '" + Path + "'");
358   Buffer = std::move(BufferOrErr.get());
359   CurrentActivity = ("loading file '" + Path + "'").str();
360   std::unique_ptr<LLVMContext> Context = std::make_unique<LLVMContext>();
361   Context->setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
362                                 true);
363   ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext(
364       std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(),
365       Options, Path);
366   CurrentActivity = "";
367   maybeVerifyModule((*Ret)->getModule());
368   return std::move(*Ret);
369 }
370 
371 /// Print some statistics on the index for each input files.
372 static void printIndexStats() {
373   for (auto &Filename : InputFilenames) {
374     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
375     std::unique_ptr<ModuleSummaryIndex> Index =
376         ExitOnErr(getModuleSummaryIndexForFile(Filename));
377     // Skip files without a module summary.
378     if (!Index)
379       report_fatal_error(Twine(Filename) + " does not contain an index");
380 
381     unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0;
382     for (auto &Summaries : *Index) {
383       for (auto &Summary : Summaries.second.SummaryList) {
384         Refs += Summary->refs().size();
385         if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
386           Functions++;
387           Calls += FuncSummary->calls().size();
388         } else if (isa<AliasSummary>(Summary.get()))
389           Alias++;
390         else
391           Globals++;
392       }
393     }
394     outs() << "Index " << Filename << " contains "
395            << (Alias + Globals + Functions) << " nodes (" << Functions
396            << " functions, " << Alias << " alias, " << Globals
397            << " globals) and " << (Calls + Refs) << " edges (" << Refs
398            << " refs and " << Calls << " calls)\n";
399   }
400 }
401 
402 /// Load each IR file and dump certain information based on active flags.
403 ///
404 /// The main point here is to provide lit-testable coverage for the LTOModule
405 /// functionality that's exposed by the C API. Moreover, this provides testing
406 /// coverage for modules that have been created in their own contexts.
407 static void testLTOModule(const TargetOptions &Options) {
408   for (auto &Filename : InputFilenames) {
409     std::unique_ptr<MemoryBuffer> Buffer;
410     std::unique_ptr<LTOModule> Module =
411         getLocalLTOModule(Filename, Buffer, Options);
412 
413     if (ListSymbolsOnly) {
414       // List the symbols.
415       outs() << Filename << ":\n";
416       for (int I = 0, E = Module->getSymbolCount(); I != E; ++I)
417         outs() << Module->getSymbolName(I) << "\n";
418     }
419     if (QueryHasCtorDtor)
420       outs() << Filename
421              << ": hasCtorDtor = " << (Module->hasCtorDtor() ? "true" : "false")
422              << "\n";
423   }
424 }
425 
426 static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
427     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
428         "': ");
429     return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
430 }
431 
432 static void listDependentLibraries() {
433   for (auto &Filename : InputFilenames) {
434     auto Buffer = loadFile(Filename);
435     std::string E;
436     std::unique_ptr<lto::InputFile> Input(LTOModule::createInputFile(
437         Buffer->getBufferStart(), Buffer->getBufferSize(), Filename.c_str(),
438         E));
439     if (!Input)
440       error(E);
441 
442     // List the dependent libraries.
443     outs() << Filename << ":\n";
444     for (size_t I = 0, C = LTOModule::getDependentLibraryCount(Input.get());
445          I != C; ++I) {
446       size_t L = 0;
447       const char *S = LTOModule::getDependentLibrary(Input.get(), I, &L);
448       assert(S);
449       outs() << StringRef(S, L) << "\n";
450     }
451   }
452 }
453 
454 static void printMachOCPUOnly() {
455   LLVMContext Context;
456   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
457                                true);
458   TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
459   for (auto &Filename : InputFilenames) {
460     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
461         LTOModule::createFromFile(Context, Filename, Options);
462     if (!ModuleOrErr)
463       error(ModuleOrErr, "llvm-lto: ");
464 
465     Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
466     Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
467     if (!CPUType)
468       error("Error while printing mach-o cputype: " +
469             toString(CPUType.takeError()));
470     if (!CPUSubType)
471       error("Error while printing mach-o cpusubtype: " +
472             toString(CPUSubType.takeError()));
473     outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
474                            Filename.c_str(), *CPUType, *CPUSubType);
475   }
476 }
477 
478 /// Create a combined index file from the input IR files and write it.
479 ///
480 /// This is meant to enable testing of ThinLTO combined index generation,
481 /// currently available via the gold plugin via -thinlto.
482 static void createCombinedModuleSummaryIndex() {
483   ModuleSummaryIndex CombinedIndex(/*HaveGVs=*/false);
484   uint64_t NextModuleId = 0;
485   for (auto &Filename : InputFilenames) {
486     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
487     std::unique_ptr<MemoryBuffer> MB =
488         ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
489     ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex, NextModuleId++));
490   }
491   // In order to use this index for testing, specifically import testing, we
492   // need to update any indirect call edges created from SamplePGO, so that they
493   // point to the correct GUIDs.
494   updateIndirectCalls(CombinedIndex);
495   std::error_code EC;
496   assert(!OutputFilename.empty());
497   raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
498                     sys::fs::OpenFlags::OF_None);
499   error(EC, "error opening the file '" + OutputFilename + ".thinlto.bc'");
500   writeIndexToFile(CombinedIndex, OS);
501   OS.close();
502 }
503 
504 /// Parse the thinlto_prefix_replace option into the \p OldPrefix and
505 /// \p NewPrefix strings, if it was specified.
506 static void getThinLTOOldAndNewPrefix(std::string &OldPrefix,
507                                       std::string &NewPrefix) {
508   assert(ThinLTOPrefixReplace.empty() ||
509          ThinLTOPrefixReplace.find(';') != StringRef::npos);
510   StringRef PrefixReplace = ThinLTOPrefixReplace;
511   std::pair<StringRef, StringRef> Split = PrefixReplace.split(";");
512   OldPrefix = Split.first.str();
513   NewPrefix = Split.second.str();
514 }
515 
516 /// Given the original \p Path to an output file, replace any path
517 /// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
518 /// resulting directory if it does not yet exist.
519 static std::string getThinLTOOutputFile(const std::string &Path,
520                                         const std::string &OldPrefix,
521                                         const std::string &NewPrefix) {
522   if (OldPrefix.empty() && NewPrefix.empty())
523     return Path;
524   SmallString<128> NewPath(Path);
525   llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
526   StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
527   if (!ParentPath.empty()) {
528     // Make sure the new directory exists, creating it if necessary.
529     if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
530       error(EC, "error creating the directory '" + ParentPath + "'");
531   }
532   return std::string(NewPath.str());
533 }
534 
535 namespace thinlto {
536 
537 std::vector<std::unique_ptr<MemoryBuffer>>
538 loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
539   std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
540 
541   for (auto &ModPath : Index.modulePaths()) {
542     const auto &Filename = ModPath.first();
543     std::string CurrentActivity = ("loading file '" + Filename + "'").str();
544     auto InputOrErr = MemoryBuffer::getFile(Filename);
545     error(InputOrErr, "error " + CurrentActivity);
546     InputBuffers.push_back(std::move(*InputOrErr));
547   }
548   return InputBuffers;
549 }
550 
551 std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
552   if (ThinLTOIndex.empty())
553     report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
554   ExitOnError ExitOnErr("llvm-lto: error loading file '" + ThinLTOIndex +
555                         "': ");
556   return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
557 }
558 
559 static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
560   ExitOnError ExitOnErr("llvm-lto: error loading input '" +
561                         Buffer.getBufferIdentifier().str() + "': ");
562   return ExitOnErr(lto::InputFile::create(Buffer));
563 }
564 
565 static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File,
566                                                    LLVMContext &CTX) {
567   auto &Mod = File.getSingleBitcodeModule();
568   auto ModuleOrErr = Mod.parseModule(CTX);
569   if (!ModuleOrErr) {
570     handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
571       SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
572                                       SourceMgr::DK_Error, EIB.message());
573       Err.print("llvm-lto", errs());
574     });
575     report_fatal_error("Can't load module, abort.");
576   }
577   maybeVerifyModule(**ModuleOrErr);
578   if (ThinLTOModuleId.getNumOccurrences()) {
579     if (InputFilenames.size() != 1)
580       report_fatal_error("Can't override the module id for multiple files");
581     (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
582   }
583   return std::move(*ModuleOrErr);
584 }
585 
586 static void writeModuleToFile(Module &TheModule, StringRef Filename) {
587   std::error_code EC;
588   raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::OF_None);
589   error(EC, "error opening the file '" + Filename + "'");
590   maybeVerifyModule(TheModule);
591   WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
592 }
593 
594 class ThinLTOProcessing {
595 public:
596   ThinLTOCodeGenerator ThinGenerator;
597 
598   ThinLTOProcessing(const TargetOptions &Options) {
599     ThinGenerator.setCodePICModel(codegen::getExplicitRelocModel());
600     ThinGenerator.setTargetOptions(Options);
601     ThinGenerator.setCacheDir(ThinLTOCacheDir);
602     ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval);
603     ThinGenerator.setCacheEntryExpiration(ThinLTOCacheEntryExpiration);
604     ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles);
605     ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes);
606     ThinGenerator.setFreestanding(EnableFreestanding);
607     ThinGenerator.setUseNewPM(UseNewPM);
608     ThinGenerator.setDebugPassManager(DebugPassManager);
609 
610     // Add all the exported symbols to the table of symbols to preserve.
611     for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
612       ThinGenerator.preserveSymbol(ExportedSymbols[i]);
613   }
614 
615   void run() {
616     switch (ThinLTOMode) {
617     case THINLINK:
618       return thinLink();
619     case THINDISTRIBUTE:
620       return distributedIndexes();
621     case THINEMITIMPORTS:
622       return emitImports();
623     case THINPROMOTE:
624       return promote();
625     case THINIMPORT:
626       return import();
627     case THININTERNALIZE:
628       return internalize();
629     case THINOPT:
630       return optimize();
631     case THINCODEGEN:
632       return codegen();
633     case THINALL:
634       return runAll();
635     }
636   }
637 
638 private:
639   /// Load the input files, create the combined index, and write it out.
640   void thinLink() {
641     // Perform "ThinLink": just produce the index
642     if (OutputFilename.empty())
643       report_fatal_error(
644           "OutputFilename is necessary to store the combined index.\n");
645 
646     LLVMContext Ctx;
647     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
648     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
649       auto &Filename = InputFilenames[i];
650       std::string CurrentActivity = "loading file '" + Filename + "'";
651       auto InputOrErr = MemoryBuffer::getFile(Filename);
652       error(InputOrErr, "error " + CurrentActivity);
653       InputBuffers.push_back(std::move(*InputOrErr));
654       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
655     }
656 
657     auto CombinedIndex = ThinGenerator.linkCombinedIndex();
658     if (!CombinedIndex)
659       report_fatal_error("ThinLink didn't create an index");
660     std::error_code EC;
661     raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
662     error(EC, "error opening the file '" + OutputFilename + "'");
663     writeIndexToFile(*CombinedIndex, OS);
664   }
665 
666   /// Load the combined index from disk, then compute and generate
667   /// individual index files suitable for ThinLTO distributed backend builds
668   /// on the files mentioned on the command line (these must match the index
669   /// content).
670   void distributedIndexes() {
671     if (InputFilenames.size() != 1 && !OutputFilename.empty())
672       report_fatal_error("Can't handle a single output filename and multiple "
673                          "input files, do not provide an output filename and "
674                          "the output files will be suffixed from the input "
675                          "ones.");
676 
677     std::string OldPrefix, NewPrefix;
678     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
679 
680     auto Index = loadCombinedIndex();
681     for (auto &Filename : InputFilenames) {
682       LLVMContext Ctx;
683       auto Buffer = loadFile(Filename);
684       auto Input = loadInputFile(Buffer->getMemBufferRef());
685       auto TheModule = loadModuleFromInput(*Input, Ctx);
686 
687       // Build a map of module to the GUIDs and summary objects that should
688       // be written to its index.
689       std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
690       ThinGenerator.gatherImportedSummariesForModule(
691           *TheModule, *Index, ModuleToSummariesForIndex, *Input);
692 
693       std::string OutputName = OutputFilename;
694       if (OutputName.empty()) {
695         OutputName = Filename + ".thinlto.bc";
696       }
697       OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
698       std::error_code EC;
699       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
700       error(EC, "error opening the file '" + OutputName + "'");
701       writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
702     }
703   }
704 
705   /// Load the combined index from disk, compute the imports, and emit
706   /// the import file lists for each module to disk.
707   void emitImports() {
708     if (InputFilenames.size() != 1 && !OutputFilename.empty())
709       report_fatal_error("Can't handle a single output filename and multiple "
710                          "input files, do not provide an output filename and "
711                          "the output files will be suffixed from the input "
712                          "ones.");
713 
714     std::string OldPrefix, NewPrefix;
715     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
716 
717     auto Index = loadCombinedIndex();
718     for (auto &Filename : InputFilenames) {
719       LLVMContext Ctx;
720       auto Buffer = loadFile(Filename);
721       auto Input = loadInputFile(Buffer->getMemBufferRef());
722       auto TheModule = loadModuleFromInput(*Input, Ctx);
723       std::string OutputName = OutputFilename;
724       if (OutputName.empty()) {
725         OutputName = Filename + ".imports";
726       }
727       OutputName =
728           getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
729       ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
730     }
731   }
732 
733   /// Load the combined index from disk, then load every file referenced by
734   /// the index and add them to the generator, finally perform the promotion
735   /// on the files mentioned on the command line (these must match the index
736   /// content).
737   void promote() {
738     if (InputFilenames.size() != 1 && !OutputFilename.empty())
739       report_fatal_error("Can't handle a single output filename and multiple "
740                          "input files, do not provide an output filename and "
741                          "the output files will be suffixed from the input "
742                          "ones.");
743 
744     auto Index = loadCombinedIndex();
745     for (auto &Filename : InputFilenames) {
746       LLVMContext Ctx;
747       auto Buffer = loadFile(Filename);
748       auto Input = loadInputFile(Buffer->getMemBufferRef());
749       auto TheModule = loadModuleFromInput(*Input, Ctx);
750 
751       ThinGenerator.promote(*TheModule, *Index, *Input);
752 
753       std::string OutputName = OutputFilename;
754       if (OutputName.empty()) {
755         OutputName = Filename + ".thinlto.promoted.bc";
756       }
757       writeModuleToFile(*TheModule, OutputName);
758     }
759   }
760 
761   /// Load the combined index from disk, then load every file referenced by
762   /// the index and add them to the generator, then performs the promotion and
763   /// cross module importing on the files mentioned on the command line
764   /// (these must match the index content).
765   void import() {
766     if (InputFilenames.size() != 1 && !OutputFilename.empty())
767       report_fatal_error("Can't handle a single output filename and multiple "
768                          "input files, do not provide an output filename and "
769                          "the output files will be suffixed from the input "
770                          "ones.");
771 
772     auto Index = loadCombinedIndex();
773     auto InputBuffers = loadAllFilesForIndex(*Index);
774     for (auto &MemBuffer : InputBuffers)
775       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
776                               MemBuffer->getBuffer());
777 
778     for (auto &Filename : InputFilenames) {
779       LLVMContext Ctx;
780       auto Buffer = loadFile(Filename);
781       auto Input = loadInputFile(Buffer->getMemBufferRef());
782       auto TheModule = loadModuleFromInput(*Input, Ctx);
783 
784       ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);
785 
786       std::string OutputName = OutputFilename;
787       if (OutputName.empty()) {
788         OutputName = Filename + ".thinlto.imported.bc";
789       }
790       writeModuleToFile(*TheModule, OutputName);
791     }
792   }
793 
794   void internalize() {
795     if (InputFilenames.size() != 1 && !OutputFilename.empty())
796       report_fatal_error("Can't handle a single output filename and multiple "
797                          "input files, do not provide an output filename and "
798                          "the output files will be suffixed from the input "
799                          "ones.");
800 
801     if (ExportedSymbols.empty())
802       errs() << "Warning: -internalize will not perform without "
803                 "-exported-symbol\n";
804 
805     auto Index = loadCombinedIndex();
806     auto InputBuffers = loadAllFilesForIndex(*Index);
807     for (auto &MemBuffer : InputBuffers)
808       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
809                               MemBuffer->getBuffer());
810 
811     for (auto &Filename : InputFilenames) {
812       LLVMContext Ctx;
813       auto Buffer = loadFile(Filename);
814       auto Input = loadInputFile(Buffer->getMemBufferRef());
815       auto TheModule = loadModuleFromInput(*Input, Ctx);
816 
817       ThinGenerator.internalize(*TheModule, *Index, *Input);
818 
819       std::string OutputName = OutputFilename;
820       if (OutputName.empty()) {
821         OutputName = Filename + ".thinlto.internalized.bc";
822       }
823       writeModuleToFile(*TheModule, OutputName);
824     }
825   }
826 
827   void optimize() {
828     if (InputFilenames.size() != 1 && !OutputFilename.empty())
829       report_fatal_error("Can't handle a single output filename and multiple "
830                          "input files, do not provide an output filename and "
831                          "the output files will be suffixed from the input "
832                          "ones.");
833     if (!ThinLTOIndex.empty())
834       errs() << "Warning: -thinlto-index ignored for optimize stage";
835 
836     for (auto &Filename : InputFilenames) {
837       LLVMContext Ctx;
838       auto Buffer = loadFile(Filename);
839       auto Input = loadInputFile(Buffer->getMemBufferRef());
840       auto TheModule = loadModuleFromInput(*Input, Ctx);
841 
842       ThinGenerator.optimize(*TheModule);
843 
844       std::string OutputName = OutputFilename;
845       if (OutputName.empty()) {
846         OutputName = Filename + ".thinlto.imported.bc";
847       }
848       writeModuleToFile(*TheModule, OutputName);
849     }
850   }
851 
852   void codegen() {
853     if (InputFilenames.size() != 1 && !OutputFilename.empty())
854       report_fatal_error("Can't handle a single output filename and multiple "
855                          "input files, do not provide an output filename and "
856                          "the output files will be suffixed from the input "
857                          "ones.");
858     if (!ThinLTOIndex.empty())
859       errs() << "Warning: -thinlto-index ignored for codegen stage";
860 
861     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
862     for (auto &Filename : InputFilenames) {
863       LLVMContext Ctx;
864       auto InputOrErr = MemoryBuffer::getFile(Filename);
865       error(InputOrErr, "error " + CurrentActivity);
866       InputBuffers.push_back(std::move(*InputOrErr));
867       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
868     }
869     ThinGenerator.setCodeGenOnly(true);
870     ThinGenerator.run();
871     for (auto BinName :
872          zip(ThinGenerator.getProducedBinaries(), InputFilenames)) {
873       std::string OutputName = OutputFilename;
874       if (OutputName.empty())
875         OutputName = std::get<1>(BinName) + ".thinlto.o";
876       else if (OutputName == "-") {
877         outs() << std::get<0>(BinName)->getBuffer();
878         return;
879       }
880 
881       std::error_code EC;
882       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
883       error(EC, "error opening the file '" + OutputName + "'");
884       OS << std::get<0>(BinName)->getBuffer();
885     }
886   }
887 
888   /// Full ThinLTO process
889   void runAll() {
890     if (!OutputFilename.empty())
891       report_fatal_error("Do not provide an output filename for ThinLTO "
892                          " processing, the output files will be suffixed from "
893                          "the input ones.");
894 
895     if (!ThinLTOIndex.empty())
896       errs() << "Warning: -thinlto-index ignored for full ThinLTO process";
897 
898     LLVMContext Ctx;
899     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
900     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
901       auto &Filename = InputFilenames[i];
902       std::string CurrentActivity = "loading file '" + Filename + "'";
903       auto InputOrErr = MemoryBuffer::getFile(Filename);
904       error(InputOrErr, "error " + CurrentActivity);
905       InputBuffers.push_back(std::move(*InputOrErr));
906       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
907     }
908 
909     if (!ThinLTOSaveTempsPrefix.empty())
910       ThinGenerator.setSaveTempsDir(ThinLTOSaveTempsPrefix);
911 
912     if (!ThinLTOGeneratedObjectsDir.empty()) {
913       ThinGenerator.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir);
914       ThinGenerator.run();
915       return;
916     }
917 
918     ThinGenerator.run();
919 
920     auto &Binaries = ThinGenerator.getProducedBinaries();
921     if (Binaries.size() != InputFilenames.size())
922       report_fatal_error("Number of output objects does not match the number "
923                          "of inputs");
924 
925     for (unsigned BufID = 0; BufID < Binaries.size(); ++BufID) {
926       auto OutputName = InputFilenames[BufID] + ".thinlto.o";
927       std::error_code EC;
928       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
929       error(EC, "error opening the file '" + OutputName + "'");
930       OS << Binaries[BufID]->getBuffer();
931     }
932   }
933 
934   /// Load the combined index from disk, then load every file referenced by
935 };
936 
937 } // end namespace thinlto
938 
939 int main(int argc, char **argv) {
940   InitLLVM X(argc, argv);
941   cl::HideUnrelatedOptions({&LTOCategory, &getColorCategory()});
942   cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");
943 
944   if (OptLevel < '0' || OptLevel > '3')
945     error("optimization level must be between 0 and 3");
946 
947   // Initialize the configured targets.
948   InitializeAllTargets();
949   InitializeAllTargetMCs();
950   InitializeAllAsmPrinters();
951   InitializeAllAsmParsers();
952 
953   // set up the TargetOptions for the machine
954   TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
955 
956   if (ListSymbolsOnly || QueryHasCtorDtor) {
957     testLTOModule(Options);
958     return 0;
959   }
960 
961   if (ListDependentLibrariesOnly) {
962     listDependentLibraries();
963     return 0;
964   }
965 
966   if (IndexStats) {
967     printIndexStats();
968     return 0;
969   }
970 
971   if (CheckHasObjC) {
972     for (auto &Filename : InputFilenames) {
973       ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" +
974                             Filename + "': ");
975       std::unique_ptr<MemoryBuffer> BufferOrErr =
976           ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename)));
977       auto Buffer = std::move(BufferOrErr.get());
978       if (ExitOnErr(isBitcodeContainingObjCCategory(*Buffer)))
979         outs() << "Bitcode " << Filename << " contains ObjC\n";
980       else
981         outs() << "Bitcode " << Filename << " does not contain ObjC\n";
982     }
983     return 0;
984   }
985 
986   if (PrintMachOCPUOnly) {
987     printMachOCPUOnly();
988     return 0;
989   }
990 
991   if (ThinLTOMode.getNumOccurrences()) {
992     if (ThinLTOMode.getNumOccurrences() > 1)
993       report_fatal_error("You can't specify more than one -thinlto-action");
994     thinlto::ThinLTOProcessing ThinLTOProcessor(Options);
995     ThinLTOProcessor.run();
996     return 0;
997   }
998 
999   if (ThinLTO) {
1000     createCombinedModuleSummaryIndex();
1001     return 0;
1002   }
1003 
1004   unsigned BaseArg = 0;
1005 
1006   LLVMContext Context;
1007   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
1008                                true);
1009 
1010   LTOCodeGenerator CodeGen(Context);
1011   CodeGen.setDisableVerify(DisableVerify);
1012 
1013   if (UseDiagnosticHandler)
1014     CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr);
1015 
1016   CodeGen.setCodePICModel(codegen::getExplicitRelocModel());
1017   CodeGen.setFreestanding(EnableFreestanding);
1018 
1019   CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
1020   CodeGen.setTargetOptions(Options);
1021   CodeGen.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage);
1022 
1023   StringSet<MallocAllocator> DSOSymbolsSet;
1024   for (unsigned i = 0; i < DSOSymbols.size(); ++i)
1025     DSOSymbolsSet.insert(DSOSymbols[i]);
1026 
1027   std::vector<std::string> KeptDSOSyms;
1028 
1029   for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) {
1030     CurrentActivity = "loading file '" + InputFilenames[i] + "'";
1031     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
1032         LTOModule::createFromFile(Context, InputFilenames[i], Options);
1033     std::unique_ptr<LTOModule> &Module = *ModuleOrErr;
1034     CurrentActivity = "";
1035 
1036     unsigned NumSyms = Module->getSymbolCount();
1037     for (unsigned I = 0; I < NumSyms; ++I) {
1038       StringRef Name = Module->getSymbolName(I);
1039       if (!DSOSymbolsSet.count(Name))
1040         continue;
1041       lto_symbol_attributes Attrs = Module->getSymbolAttributes(I);
1042       unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
1043       if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN)
1044         KeptDSOSyms.push_back(std::string(Name));
1045     }
1046 
1047     // We use the first input module as the destination module when
1048     // SetMergedModule is true.
1049     if (SetMergedModule && i == BaseArg) {
1050       // Transfer ownership to the code generator.
1051       CodeGen.setModule(std::move(Module));
1052     } else if (!CodeGen.addModule(Module.get())) {
1053       // Print a message here so that we know addModule() did not abort.
1054       error("error adding file '" + InputFilenames[i] + "'");
1055     }
1056   }
1057 
1058   // Add all the exported symbols to the table of symbols to preserve.
1059   for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
1060     CodeGen.addMustPreserveSymbol(ExportedSymbols[i]);
1061 
1062   // Add all the dso symbols to the table of symbols to expose.
1063   for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
1064     CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]);
1065 
1066   // Set cpu and attrs strings for the default target/subtarget.
1067   CodeGen.setCpu(codegen::getMCPU());
1068 
1069   CodeGen.setOptLevel(OptLevel - '0');
1070   CodeGen.setAttrs(codegen::getMAttrs());
1071 
1072   CodeGen.setUseNewPM(UseNewPM);
1073 
1074   if (auto FT = codegen::getExplicitFileType())
1075     CodeGen.setFileType(FT.getValue());
1076 
1077   if (!OutputFilename.empty()) {
1078     if (SaveLinkedModuleFile) {
1079       std::string ModuleFilename = OutputFilename;
1080       ModuleFilename += ".linked.bc";
1081       std::string ErrMsg;
1082 
1083       if (!CodeGen.writeMergedModules(ModuleFilename))
1084         error("writing linked module failed.");
1085     }
1086 
1087     if (!CodeGen.optimize()) {
1088       // Diagnostic messages should have been printed by the handler.
1089       error("error optimizing the code");
1090     }
1091 
1092     if (SaveModuleFile) {
1093       std::string ModuleFilename = OutputFilename;
1094       ModuleFilename += ".merged.bc";
1095       std::string ErrMsg;
1096 
1097       if (!CodeGen.writeMergedModules(ModuleFilename))
1098         error("writing merged module failed.");
1099     }
1100 
1101     auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
1102       std::string PartFilename = OutputFilename;
1103       if (Parallelism != 1)
1104         PartFilename += "." + utostr(Task);
1105 
1106       std::error_code EC;
1107       auto S =
1108           std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
1109       if (EC)
1110         error("error opening the file '" + PartFilename + "': " + EC.message());
1111       return std::make_unique<CachedFileStream>(std::move(S));
1112     };
1113 
1114     if (!CodeGen.compileOptimized(AddStream, Parallelism))
1115       // Diagnostic messages should have been printed by the handler.
1116       error("error compiling the code");
1117 
1118   } else {
1119     if (Parallelism != 1)
1120       error("-j must be specified together with -o");
1121 
1122     if (SaveModuleFile)
1123       error(": -save-merged-module must be specified with -o");
1124 
1125     const char *OutputName = nullptr;
1126     if (!CodeGen.compile_to_file(&OutputName))
1127       error("error compiling the code");
1128       // Diagnostic messages should have been printed by the handler.
1129 
1130     outs() << "Wrote native object file '" << OutputName << "'\n";
1131   }
1132 
1133   return 0;
1134 }
1135