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::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::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::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>
260     DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden,
261                      cl::desc("Print pass management debugging information"),
262                      cl::cat(LTOCategory));
263 
264 static cl::opt<bool>
265     LTOSaveBeforeOpt("lto-save-before-opt", cl::init(false),
266                      cl::desc("Save the IR before running optimizations"));
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(StringRef Path, StringRef OldPrefix,
520                                         StringRef NewPrefix) {
521   if (OldPrefix.empty() && NewPrefix.empty())
522     return std::string(Path);
523   SmallString<128> NewPath(Path);
524   llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
525   StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
526   if (!ParentPath.empty()) {
527     // Make sure the new directory exists, creating it if necessary.
528     if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
529       error(EC, "error creating the directory '" + ParentPath + "'");
530   }
531   return std::string(NewPath.str());
532 }
533 
534 namespace thinlto {
535 
536 std::vector<std::unique_ptr<MemoryBuffer>>
537 loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
538   std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
539 
540   for (auto &ModPath : Index.modulePaths()) {
541     const auto &Filename = ModPath.first();
542     std::string CurrentActivity = ("loading file '" + Filename + "'").str();
543     auto InputOrErr = MemoryBuffer::getFile(Filename);
544     error(InputOrErr, "error " + CurrentActivity);
545     InputBuffers.push_back(std::move(*InputOrErr));
546   }
547   return InputBuffers;
548 }
549 
550 std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
551   if (ThinLTOIndex.empty())
552     report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
553   ExitOnError ExitOnErr("llvm-lto: error loading file '" + ThinLTOIndex +
554                         "': ");
555   return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
556 }
557 
558 static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
559   ExitOnError ExitOnErr("llvm-lto: error loading input '" +
560                         Buffer.getBufferIdentifier().str() + "': ");
561   return ExitOnErr(lto::InputFile::create(Buffer));
562 }
563 
564 static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File,
565                                                    LLVMContext &CTX) {
566   auto &Mod = File.getSingleBitcodeModule();
567   auto ModuleOrErr = Mod.parseModule(CTX);
568   if (!ModuleOrErr) {
569     handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
570       SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
571                                       SourceMgr::DK_Error, EIB.message());
572       Err.print("llvm-lto", errs());
573     });
574     report_fatal_error("Can't load module, abort.");
575   }
576   maybeVerifyModule(**ModuleOrErr);
577   if (ThinLTOModuleId.getNumOccurrences()) {
578     if (InputFilenames.size() != 1)
579       report_fatal_error("Can't override the module id for multiple files");
580     (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
581   }
582   return std::move(*ModuleOrErr);
583 }
584 
585 static void writeModuleToFile(Module &TheModule, StringRef Filename) {
586   std::error_code EC;
587   raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::OF_None);
588   error(EC, "error opening the file '" + Filename + "'");
589   maybeVerifyModule(TheModule);
590   WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
591 }
592 
593 class ThinLTOProcessing {
594 public:
595   ThinLTOCodeGenerator ThinGenerator;
596 
597   ThinLTOProcessing(const TargetOptions &Options) {
598     ThinGenerator.setCodePICModel(codegen::getExplicitRelocModel());
599     ThinGenerator.setTargetOptions(Options);
600     ThinGenerator.setCacheDir(ThinLTOCacheDir);
601     ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval);
602     ThinGenerator.setCacheEntryExpiration(ThinLTOCacheEntryExpiration);
603     ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles);
604     ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes);
605     ThinGenerator.setFreestanding(EnableFreestanding);
606     ThinGenerator.setDebugPassManager(DebugPassManager);
607 
608     // Add all the exported symbols to the table of symbols to preserve.
609     for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
610       ThinGenerator.preserveSymbol(ExportedSymbols[i]);
611   }
612 
613   void run() {
614     switch (ThinLTOMode) {
615     case THINLINK:
616       return thinLink();
617     case THINDISTRIBUTE:
618       return distributedIndexes();
619     case THINEMITIMPORTS:
620       return emitImports();
621     case THINPROMOTE:
622       return promote();
623     case THINIMPORT:
624       return import();
625     case THININTERNALIZE:
626       return internalize();
627     case THINOPT:
628       return optimize();
629     case THINCODEGEN:
630       return codegen();
631     case THINALL:
632       return runAll();
633     }
634   }
635 
636 private:
637   /// Load the input files, create the combined index, and write it out.
638   void thinLink() {
639     // Perform "ThinLink": just produce the index
640     if (OutputFilename.empty())
641       report_fatal_error(
642           "OutputFilename is necessary to store the combined index.\n");
643 
644     LLVMContext Ctx;
645     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
646     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
647       auto &Filename = InputFilenames[i];
648       std::string CurrentActivity = "loading file '" + Filename + "'";
649       auto InputOrErr = MemoryBuffer::getFile(Filename);
650       error(InputOrErr, "error " + CurrentActivity);
651       InputBuffers.push_back(std::move(*InputOrErr));
652       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
653     }
654 
655     auto CombinedIndex = ThinGenerator.linkCombinedIndex();
656     if (!CombinedIndex)
657       report_fatal_error("ThinLink didn't create an index");
658     std::error_code EC;
659     raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
660     error(EC, "error opening the file '" + OutputFilename + "'");
661     writeIndexToFile(*CombinedIndex, OS);
662   }
663 
664   /// Load the combined index from disk, then compute and generate
665   /// individual index files suitable for ThinLTO distributed backend builds
666   /// on the files mentioned on the command line (these must match the index
667   /// content).
668   void distributedIndexes() {
669     if (InputFilenames.size() != 1 && !OutputFilename.empty())
670       report_fatal_error("Can't handle a single output filename and multiple "
671                          "input files, do not provide an output filename and "
672                          "the output files will be suffixed from the input "
673                          "ones.");
674 
675     std::string OldPrefix, NewPrefix;
676     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
677 
678     auto Index = loadCombinedIndex();
679     for (auto &Filename : InputFilenames) {
680       LLVMContext Ctx;
681       auto Buffer = loadFile(Filename);
682       auto Input = loadInputFile(Buffer->getMemBufferRef());
683       auto TheModule = loadModuleFromInput(*Input, Ctx);
684 
685       // Build a map of module to the GUIDs and summary objects that should
686       // be written to its index.
687       std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
688       ThinGenerator.gatherImportedSummariesForModule(
689           *TheModule, *Index, ModuleToSummariesForIndex, *Input);
690 
691       std::string OutputName = OutputFilename;
692       if (OutputName.empty()) {
693         OutputName = Filename + ".thinlto.bc";
694       }
695       OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
696       std::error_code EC;
697       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
698       error(EC, "error opening the file '" + OutputName + "'");
699       writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
700     }
701   }
702 
703   /// Load the combined index from disk, compute the imports, and emit
704   /// the import file lists for each module to disk.
705   void emitImports() {
706     if (InputFilenames.size() != 1 && !OutputFilename.empty())
707       report_fatal_error("Can't handle a single output filename and multiple "
708                          "input files, do not provide an output filename and "
709                          "the output files will be suffixed from the input "
710                          "ones.");
711 
712     std::string OldPrefix, NewPrefix;
713     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
714 
715     auto Index = loadCombinedIndex();
716     for (auto &Filename : InputFilenames) {
717       LLVMContext Ctx;
718       auto Buffer = loadFile(Filename);
719       auto Input = loadInputFile(Buffer->getMemBufferRef());
720       auto TheModule = loadModuleFromInput(*Input, Ctx);
721       std::string OutputName = OutputFilename;
722       if (OutputName.empty()) {
723         OutputName = Filename + ".imports";
724       }
725       OutputName =
726           getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
727       ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
728     }
729   }
730 
731   /// Load the combined index from disk, then load every file referenced by
732   /// the index and add them to the generator, finally perform the promotion
733   /// on the files mentioned on the command line (these must match the index
734   /// content).
735   void promote() {
736     if (InputFilenames.size() != 1 && !OutputFilename.empty())
737       report_fatal_error("Can't handle a single output filename and multiple "
738                          "input files, do not provide an output filename and "
739                          "the output files will be suffixed from the input "
740                          "ones.");
741 
742     auto Index = loadCombinedIndex();
743     for (auto &Filename : InputFilenames) {
744       LLVMContext Ctx;
745       auto Buffer = loadFile(Filename);
746       auto Input = loadInputFile(Buffer->getMemBufferRef());
747       auto TheModule = loadModuleFromInput(*Input, Ctx);
748 
749       ThinGenerator.promote(*TheModule, *Index, *Input);
750 
751       std::string OutputName = OutputFilename;
752       if (OutputName.empty()) {
753         OutputName = Filename + ".thinlto.promoted.bc";
754       }
755       writeModuleToFile(*TheModule, OutputName);
756     }
757   }
758 
759   /// Load the combined index from disk, then load every file referenced by
760   /// the index and add them to the generator, then performs the promotion and
761   /// cross module importing on the files mentioned on the command line
762   /// (these must match the index content).
763   void import() {
764     if (InputFilenames.size() != 1 && !OutputFilename.empty())
765       report_fatal_error("Can't handle a single output filename and multiple "
766                          "input files, do not provide an output filename and "
767                          "the output files will be suffixed from the input "
768                          "ones.");
769 
770     auto Index = loadCombinedIndex();
771     auto InputBuffers = loadAllFilesForIndex(*Index);
772     for (auto &MemBuffer : InputBuffers)
773       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
774                               MemBuffer->getBuffer());
775 
776     for (auto &Filename : InputFilenames) {
777       LLVMContext Ctx;
778       auto Buffer = loadFile(Filename);
779       auto Input = loadInputFile(Buffer->getMemBufferRef());
780       auto TheModule = loadModuleFromInput(*Input, Ctx);
781 
782       ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);
783 
784       std::string OutputName = OutputFilename;
785       if (OutputName.empty()) {
786         OutputName = Filename + ".thinlto.imported.bc";
787       }
788       writeModuleToFile(*TheModule, OutputName);
789     }
790   }
791 
792   void internalize() {
793     if (InputFilenames.size() != 1 && !OutputFilename.empty())
794       report_fatal_error("Can't handle a single output filename and multiple "
795                          "input files, do not provide an output filename and "
796                          "the output files will be suffixed from the input "
797                          "ones.");
798 
799     if (ExportedSymbols.empty())
800       errs() << "Warning: -internalize will not perform without "
801                 "-exported-symbol\n";
802 
803     auto Index = loadCombinedIndex();
804     auto InputBuffers = loadAllFilesForIndex(*Index);
805     for (auto &MemBuffer : InputBuffers)
806       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
807                               MemBuffer->getBuffer());
808 
809     for (auto &Filename : InputFilenames) {
810       LLVMContext Ctx;
811       auto Buffer = loadFile(Filename);
812       auto Input = loadInputFile(Buffer->getMemBufferRef());
813       auto TheModule = loadModuleFromInput(*Input, Ctx);
814 
815       ThinGenerator.internalize(*TheModule, *Index, *Input);
816 
817       std::string OutputName = OutputFilename;
818       if (OutputName.empty()) {
819         OutputName = Filename + ".thinlto.internalized.bc";
820       }
821       writeModuleToFile(*TheModule, OutputName);
822     }
823   }
824 
825   void optimize() {
826     if (InputFilenames.size() != 1 && !OutputFilename.empty())
827       report_fatal_error("Can't handle a single output filename and multiple "
828                          "input files, do not provide an output filename and "
829                          "the output files will be suffixed from the input "
830                          "ones.");
831     if (!ThinLTOIndex.empty())
832       errs() << "Warning: -thinlto-index ignored for optimize stage";
833 
834     for (auto &Filename : InputFilenames) {
835       LLVMContext Ctx;
836       auto Buffer = loadFile(Filename);
837       auto Input = loadInputFile(Buffer->getMemBufferRef());
838       auto TheModule = loadModuleFromInput(*Input, Ctx);
839 
840       ThinGenerator.optimize(*TheModule);
841 
842       std::string OutputName = OutputFilename;
843       if (OutputName.empty()) {
844         OutputName = Filename + ".thinlto.imported.bc";
845       }
846       writeModuleToFile(*TheModule, OutputName);
847     }
848   }
849 
850   void codegen() {
851     if (InputFilenames.size() != 1 && !OutputFilename.empty())
852       report_fatal_error("Can't handle a single output filename and multiple "
853                          "input files, do not provide an output filename and "
854                          "the output files will be suffixed from the input "
855                          "ones.");
856     if (!ThinLTOIndex.empty())
857       errs() << "Warning: -thinlto-index ignored for codegen stage";
858 
859     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
860     for (auto &Filename : InputFilenames) {
861       LLVMContext Ctx;
862       auto InputOrErr = MemoryBuffer::getFile(Filename);
863       error(InputOrErr, "error " + CurrentActivity);
864       InputBuffers.push_back(std::move(*InputOrErr));
865       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
866     }
867     ThinGenerator.setCodeGenOnly(true);
868     ThinGenerator.run();
869     for (auto BinName :
870          zip(ThinGenerator.getProducedBinaries(), InputFilenames)) {
871       std::string OutputName = OutputFilename;
872       if (OutputName.empty())
873         OutputName = std::get<1>(BinName) + ".thinlto.o";
874       else if (OutputName == "-") {
875         outs() << std::get<0>(BinName)->getBuffer();
876         return;
877       }
878 
879       std::error_code EC;
880       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
881       error(EC, "error opening the file '" + OutputName + "'");
882       OS << std::get<0>(BinName)->getBuffer();
883     }
884   }
885 
886   /// Full ThinLTO process
887   void runAll() {
888     if (!OutputFilename.empty())
889       report_fatal_error("Do not provide an output filename for ThinLTO "
890                          " processing, the output files will be suffixed from "
891                          "the input ones.");
892 
893     if (!ThinLTOIndex.empty())
894       errs() << "Warning: -thinlto-index ignored for full ThinLTO process";
895 
896     LLVMContext Ctx;
897     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
898     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
899       auto &Filename = InputFilenames[i];
900       std::string CurrentActivity = "loading file '" + Filename + "'";
901       auto InputOrErr = MemoryBuffer::getFile(Filename);
902       error(InputOrErr, "error " + CurrentActivity);
903       InputBuffers.push_back(std::move(*InputOrErr));
904       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
905     }
906 
907     if (!ThinLTOSaveTempsPrefix.empty())
908       ThinGenerator.setSaveTempsDir(ThinLTOSaveTempsPrefix);
909 
910     if (!ThinLTOGeneratedObjectsDir.empty()) {
911       ThinGenerator.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir);
912       ThinGenerator.run();
913       return;
914     }
915 
916     ThinGenerator.run();
917 
918     auto &Binaries = ThinGenerator.getProducedBinaries();
919     if (Binaries.size() != InputFilenames.size())
920       report_fatal_error("Number of output objects does not match the number "
921                          "of inputs");
922 
923     for (unsigned BufID = 0; BufID < Binaries.size(); ++BufID) {
924       auto OutputName = InputFilenames[BufID] + ".thinlto.o";
925       std::error_code EC;
926       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
927       error(EC, "error opening the file '" + OutputName + "'");
928       OS << Binaries[BufID]->getBuffer();
929     }
930   }
931 
932   /// Load the combined index from disk, then load every file referenced by
933 };
934 
935 } // end namespace thinlto
936 
937 int main(int argc, char **argv) {
938   InitLLVM X(argc, argv);
939   cl::HideUnrelatedOptions({&LTOCategory, &getColorCategory()});
940   cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");
941 
942   if (OptLevel < '0' || OptLevel > '3')
943     error("optimization level must be between 0 and 3");
944 
945   // Initialize the configured targets.
946   InitializeAllTargets();
947   InitializeAllTargetMCs();
948   InitializeAllAsmPrinters();
949   InitializeAllAsmParsers();
950 
951   // set up the TargetOptions for the machine
952   TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
953 
954   if (ListSymbolsOnly || QueryHasCtorDtor) {
955     testLTOModule(Options);
956     return 0;
957   }
958 
959   if (ListDependentLibrariesOnly) {
960     listDependentLibraries();
961     return 0;
962   }
963 
964   if (IndexStats) {
965     printIndexStats();
966     return 0;
967   }
968 
969   if (CheckHasObjC) {
970     for (auto &Filename : InputFilenames) {
971       ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" +
972                             Filename + "': ");
973       std::unique_ptr<MemoryBuffer> BufferOrErr =
974           ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename)));
975       auto Buffer = std::move(BufferOrErr.get());
976       if (ExitOnErr(isBitcodeContainingObjCCategory(*Buffer)))
977         outs() << "Bitcode " << Filename << " contains ObjC\n";
978       else
979         outs() << "Bitcode " << Filename << " does not contain ObjC\n";
980     }
981     return 0;
982   }
983 
984   if (PrintMachOCPUOnly) {
985     printMachOCPUOnly();
986     return 0;
987   }
988 
989   if (ThinLTOMode.getNumOccurrences()) {
990     if (ThinLTOMode.getNumOccurrences() > 1)
991       report_fatal_error("You can't specify more than one -thinlto-action");
992     thinlto::ThinLTOProcessing ThinLTOProcessor(Options);
993     ThinLTOProcessor.run();
994     return 0;
995   }
996 
997   if (ThinLTO) {
998     createCombinedModuleSummaryIndex();
999     return 0;
1000   }
1001 
1002   unsigned BaseArg = 0;
1003 
1004   LLVMContext Context;
1005   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
1006                                true);
1007 
1008   LTOCodeGenerator CodeGen(Context);
1009   CodeGen.setDisableVerify(DisableVerify);
1010 
1011   if (UseDiagnosticHandler)
1012     CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr);
1013 
1014   CodeGen.setCodePICModel(codegen::getExplicitRelocModel());
1015   CodeGen.setFreestanding(EnableFreestanding);
1016   CodeGen.setDebugPassManager(DebugPassManager);
1017 
1018   CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
1019   CodeGen.setTargetOptions(Options);
1020   CodeGen.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage);
1021 
1022   StringSet<MallocAllocator> DSOSymbolsSet;
1023   for (unsigned i = 0; i < DSOSymbols.size(); ++i)
1024     DSOSymbolsSet.insert(DSOSymbols[i]);
1025 
1026   std::vector<std::string> KeptDSOSyms;
1027 
1028   for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) {
1029     CurrentActivity = "loading file '" + InputFilenames[i] + "'";
1030     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
1031         LTOModule::createFromFile(Context, InputFilenames[i], Options);
1032     std::unique_ptr<LTOModule> &Module = *ModuleOrErr;
1033     CurrentActivity = "";
1034 
1035     unsigned NumSyms = Module->getSymbolCount();
1036     for (unsigned I = 0; I < NumSyms; ++I) {
1037       StringRef Name = Module->getSymbolName(I);
1038       if (!DSOSymbolsSet.count(Name))
1039         continue;
1040       lto_symbol_attributes Attrs = Module->getSymbolAttributes(I);
1041       unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
1042       if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN)
1043         KeptDSOSyms.push_back(std::string(Name));
1044     }
1045 
1046     // We use the first input module as the destination module when
1047     // SetMergedModule is true.
1048     if (SetMergedModule && i == BaseArg) {
1049       // Transfer ownership to the code generator.
1050       CodeGen.setModule(std::move(Module));
1051     } else if (!CodeGen.addModule(Module.get())) {
1052       // Print a message here so that we know addModule() did not abort.
1053       error("error adding file '" + InputFilenames[i] + "'");
1054     }
1055   }
1056 
1057   // Add all the exported symbols to the table of symbols to preserve.
1058   for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
1059     CodeGen.addMustPreserveSymbol(ExportedSymbols[i]);
1060 
1061   // Add all the dso symbols to the table of symbols to expose.
1062   for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
1063     CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]);
1064 
1065   // Set cpu and attrs strings for the default target/subtarget.
1066   CodeGen.setCpu(codegen::getMCPU());
1067 
1068   CodeGen.setOptLevel(OptLevel - '0');
1069   CodeGen.setAttrs(codegen::getMAttrs());
1070 
1071   if (auto FT = codegen::getExplicitFileType())
1072     CodeGen.setFileType(*FT);
1073 
1074   if (!OutputFilename.empty()) {
1075     if (LTOSaveBeforeOpt)
1076       CodeGen.setSaveIRBeforeOptPath(OutputFilename + ".0.preopt.bc");
1077 
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 =
1102         [&](size_t Task,
1103             const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
1104       std::string PartFilename = OutputFilename;
1105       if (Parallelism != 1)
1106         PartFilename += "." + utostr(Task);
1107 
1108       std::error_code EC;
1109       auto S =
1110           std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
1111       if (EC)
1112         error("error opening the file '" + PartFilename + "': " + EC.message());
1113       return std::make_unique<CachedFileStream>(std::move(S));
1114     };
1115 
1116     if (!CodeGen.compileOptimized(AddStream, Parallelism))
1117       // Diagnostic messages should have been printed by the handler.
1118       error("error compiling the code");
1119 
1120   } else {
1121     if (Parallelism != 1)
1122       error("-j must be specified together with -o");
1123 
1124     if (SaveModuleFile)
1125       error(": -save-merged-module must be specified with -o");
1126 
1127     const char *OutputName = nullptr;
1128     if (!CodeGen.compile_to_file(&OutputName))
1129       error("error compiling the code");
1130       // Diagnostic messages should have been printed by the handler.
1131 
1132     outs() << "Wrote native object file '" << OutputName << "'\n";
1133   }
1134 
1135   return 0;
1136 }
1137