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