xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-lto/llvm-lto.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
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 namespace {
265 
266 struct ModuleInfo {
267   BitVector CanBeHidden;
268 };
269 
270 } // end anonymous namespace
271 
272 static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity,
273                               const char *Msg, void *) {
274   errs() << "llvm-lto: ";
275   switch (Severity) {
276   case LTO_DS_NOTE:
277     errs() << "note: ";
278     break;
279   case LTO_DS_REMARK:
280     errs() << "remark: ";
281     break;
282   case LTO_DS_ERROR:
283     errs() << "error: ";
284     break;
285   case LTO_DS_WARNING:
286     errs() << "warning: ";
287     break;
288   }
289   errs() << Msg << "\n";
290 }
291 
292 static std::string CurrentActivity;
293 
294 namespace {
295   struct LLVMLTODiagnosticHandler : public DiagnosticHandler {
296     bool handleDiagnostics(const DiagnosticInfo &DI) override {
297       raw_ostream &OS = errs();
298       OS << "llvm-lto: ";
299       switch (DI.getSeverity()) {
300       case DS_Error:
301         OS << "error";
302         break;
303       case DS_Warning:
304         OS << "warning";
305         break;
306       case DS_Remark:
307         OS << "remark";
308         break;
309       case DS_Note:
310         OS << "note";
311         break;
312       }
313       if (!CurrentActivity.empty())
314         OS << ' ' << CurrentActivity;
315       OS << ": ";
316 
317       DiagnosticPrinterRawOStream DP(OS);
318       DI.print(DP);
319       OS << '\n';
320 
321       if (DI.getSeverity() == DS_Error)
322         exit(1);
323       return true;
324     }
325   };
326   }
327 
328 static void error(const Twine &Msg) {
329   errs() << "llvm-lto: " << Msg << '\n';
330   exit(1);
331 }
332 
333 static void error(std::error_code EC, const Twine &Prefix) {
334   if (EC)
335     error(Prefix + ": " + EC.message());
336 }
337 
338 template <typename T>
339 static void error(const ErrorOr<T> &V, const Twine &Prefix) {
340   error(V.getError(), Prefix);
341 }
342 
343 static void maybeVerifyModule(const Module &Mod) {
344   if (!DisableVerify && verifyModule(Mod, &errs()))
345     error("Broken Module");
346 }
347 
348 static std::unique_ptr<LTOModule>
349 getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer,
350                   const TargetOptions &Options) {
351   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
352       MemoryBuffer::getFile(Path);
353   error(BufferOrErr, "error loading file '" + Path + "'");
354   Buffer = std::move(BufferOrErr.get());
355   CurrentActivity = ("loading file '" + Path + "'").str();
356   std::unique_ptr<LLVMContext> Context = std::make_unique<LLVMContext>();
357   Context->setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
358                                 true);
359   ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext(
360       std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(),
361       Options, Path);
362   CurrentActivity = "";
363   maybeVerifyModule((*Ret)->getModule());
364   return std::move(*Ret);
365 }
366 
367 /// Print some statistics on the index for each input files.
368 static void printIndexStats() {
369   for (auto &Filename : InputFilenames) {
370     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
371     std::unique_ptr<ModuleSummaryIndex> Index =
372         ExitOnErr(getModuleSummaryIndexForFile(Filename));
373     // Skip files without a module summary.
374     if (!Index)
375       report_fatal_error(Twine(Filename) + " does not contain an index");
376 
377     unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0;
378     for (auto &Summaries : *Index) {
379       for (auto &Summary : Summaries.second.SummaryList) {
380         Refs += Summary->refs().size();
381         if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
382           Functions++;
383           Calls += FuncSummary->calls().size();
384         } else if (isa<AliasSummary>(Summary.get()))
385           Alias++;
386         else
387           Globals++;
388       }
389     }
390     outs() << "Index " << Filename << " contains "
391            << (Alias + Globals + Functions) << " nodes (" << Functions
392            << " functions, " << Alias << " alias, " << Globals
393            << " globals) and " << (Calls + Refs) << " edges (" << Refs
394            << " refs and " << Calls << " calls)\n";
395   }
396 }
397 
398 /// Load each IR file and dump certain information based on active flags.
399 ///
400 /// The main point here is to provide lit-testable coverage for the LTOModule
401 /// functionality that's exposed by the C API. Moreover, this provides testing
402 /// coverage for modules that have been created in their own contexts.
403 static void testLTOModule(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     if (ListSymbolsOnly) {
410       // List the symbols.
411       outs() << Filename << ":\n";
412       for (int I = 0, E = Module->getSymbolCount(); I != E; ++I)
413         outs() << Module->getSymbolName(I) << "\n";
414     }
415     if (QueryHasCtorDtor)
416       outs() << Filename
417              << ": hasCtorDtor = " << (Module->hasCtorDtor() ? "true" : "false")
418              << "\n";
419   }
420 }
421 
422 static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) {
423     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
424         "': ");
425     return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
426 }
427 
428 static void listDependentLibraries() {
429   for (auto &Filename : InputFilenames) {
430     auto Buffer = loadFile(Filename);
431     std::string E;
432     std::unique_ptr<lto::InputFile> Input(LTOModule::createInputFile(
433         Buffer->getBufferStart(), Buffer->getBufferSize(), Filename.c_str(),
434         E));
435     if (!Input)
436       error(E);
437 
438     // List the dependent libraries.
439     outs() << Filename << ":\n";
440     for (size_t I = 0, C = LTOModule::getDependentLibraryCount(Input.get());
441          I != C; ++I) {
442       size_t L = 0;
443       const char *S = LTOModule::getDependentLibrary(Input.get(), I, &L);
444       assert(S);
445       outs() << StringRef(S, L) << "\n";
446     }
447   }
448 }
449 
450 static void printMachOCPUOnly() {
451   LLVMContext Context;
452   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
453                                true);
454   TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
455   for (auto &Filename : InputFilenames) {
456     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
457         LTOModule::createFromFile(Context, Filename, Options);
458     if (!ModuleOrErr)
459       error(ModuleOrErr, "llvm-lto: ");
460 
461     Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType();
462     Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType();
463     if (!CPUType)
464       error("Error while printing mach-o cputype: " +
465             toString(CPUType.takeError()));
466     if (!CPUSubType)
467       error("Error while printing mach-o cpusubtype: " +
468             toString(CPUSubType.takeError()));
469     outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n",
470                            Filename.c_str(), *CPUType, *CPUSubType);
471   }
472 }
473 
474 /// Create a combined index file from the input IR files and write it.
475 ///
476 /// This is meant to enable testing of ThinLTO combined index generation,
477 /// currently available via the gold plugin via -thinlto.
478 static void createCombinedModuleSummaryIndex() {
479   ModuleSummaryIndex CombinedIndex(/*HaveGVs=*/false);
480   uint64_t NextModuleId = 0;
481   for (auto &Filename : InputFilenames) {
482     ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': ");
483     std::unique_ptr<MemoryBuffer> MB =
484         ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
485     ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex, NextModuleId++));
486   }
487   // In order to use this index for testing, specifically import testing, we
488   // need to update any indirect call edges created from SamplePGO, so that they
489   // point to the correct GUIDs.
490   updateIndirectCalls(CombinedIndex);
491   std::error_code EC;
492   assert(!OutputFilename.empty());
493   raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC,
494                     sys::fs::OpenFlags::OF_None);
495   error(EC, "error opening the file '" + OutputFilename + ".thinlto.bc'");
496   writeIndexToFile(CombinedIndex, OS);
497   OS.close();
498 }
499 
500 /// Parse the thinlto_prefix_replace option into the \p OldPrefix and
501 /// \p NewPrefix strings, if it was specified.
502 static void getThinLTOOldAndNewPrefix(std::string &OldPrefix,
503                                       std::string &NewPrefix) {
504   assert(ThinLTOPrefixReplace.empty() ||
505          ThinLTOPrefixReplace.find(';') != StringRef::npos);
506   StringRef PrefixReplace = ThinLTOPrefixReplace;
507   std::pair<StringRef, StringRef> Split = PrefixReplace.split(";");
508   OldPrefix = Split.first.str();
509   NewPrefix = Split.second.str();
510 }
511 
512 /// Given the original \p Path to an output file, replace any path
513 /// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
514 /// resulting directory if it does not yet exist.
515 static std::string getThinLTOOutputFile(const std::string &Path,
516                                         const std::string &OldPrefix,
517                                         const std::string &NewPrefix) {
518   if (OldPrefix.empty() && NewPrefix.empty())
519     return Path;
520   SmallString<128> NewPath(Path);
521   llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
522   StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
523   if (!ParentPath.empty()) {
524     // Make sure the new directory exists, creating it if necessary.
525     if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
526       error(EC, "error creating the directory '" + ParentPath + "'");
527   }
528   return std::string(NewPath.str());
529 }
530 
531 namespace thinlto {
532 
533 std::vector<std::unique_ptr<MemoryBuffer>>
534 loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
535   std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
536 
537   for (auto &ModPath : Index.modulePaths()) {
538     const auto &Filename = ModPath.first();
539     std::string CurrentActivity = ("loading file '" + Filename + "'").str();
540     auto InputOrErr = MemoryBuffer::getFile(Filename);
541     error(InputOrErr, "error " + CurrentActivity);
542     InputBuffers.push_back(std::move(*InputOrErr));
543   }
544   return InputBuffers;
545 }
546 
547 std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
548   if (ThinLTOIndex.empty())
549     report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
550   ExitOnError ExitOnErr("llvm-lto: error loading file '" + ThinLTOIndex +
551                         "': ");
552   return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
553 }
554 
555 static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) {
556   ExitOnError ExitOnErr("llvm-lto: error loading input '" +
557                         Buffer.getBufferIdentifier().str() + "': ");
558   return ExitOnErr(lto::InputFile::create(Buffer));
559 }
560 
561 static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File,
562                                                    LLVMContext &CTX) {
563   auto &Mod = File.getSingleBitcodeModule();
564   auto ModuleOrErr = Mod.parseModule(CTX);
565   if (!ModuleOrErr) {
566     handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
567       SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
568                                       SourceMgr::DK_Error, EIB.message());
569       Err.print("llvm-lto", errs());
570     });
571     report_fatal_error("Can't load module, abort.");
572   }
573   maybeVerifyModule(**ModuleOrErr);
574   if (ThinLTOModuleId.getNumOccurrences()) {
575     if (InputFilenames.size() != 1)
576       report_fatal_error("Can't override the module id for multiple files");
577     (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
578   }
579   return std::move(*ModuleOrErr);
580 }
581 
582 static void writeModuleToFile(Module &TheModule, StringRef Filename) {
583   std::error_code EC;
584   raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::OF_None);
585   error(EC, "error opening the file '" + Filename + "'");
586   maybeVerifyModule(TheModule);
587   WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
588 }
589 
590 class ThinLTOProcessing {
591 public:
592   ThinLTOCodeGenerator ThinGenerator;
593 
594   ThinLTOProcessing(const TargetOptions &Options) {
595     ThinGenerator.setCodePICModel(codegen::getExplicitRelocModel());
596     ThinGenerator.setTargetOptions(Options);
597     ThinGenerator.setCacheDir(ThinLTOCacheDir);
598     ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval);
599     ThinGenerator.setCacheEntryExpiration(ThinLTOCacheEntryExpiration);
600     ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles);
601     ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes);
602     ThinGenerator.setFreestanding(EnableFreestanding);
603     ThinGenerator.setDebugPassManager(DebugPassManager);
604 
605     // Add all the exported symbols to the table of symbols to preserve.
606     for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
607       ThinGenerator.preserveSymbol(ExportedSymbols[i]);
608   }
609 
610   void run() {
611     switch (ThinLTOMode) {
612     case THINLINK:
613       return thinLink();
614     case THINDISTRIBUTE:
615       return distributedIndexes();
616     case THINEMITIMPORTS:
617       return emitImports();
618     case THINPROMOTE:
619       return promote();
620     case THINIMPORT:
621       return import();
622     case THININTERNALIZE:
623       return internalize();
624     case THINOPT:
625       return optimize();
626     case THINCODEGEN:
627       return codegen();
628     case THINALL:
629       return runAll();
630     }
631   }
632 
633 private:
634   /// Load the input files, create the combined index, and write it out.
635   void thinLink() {
636     // Perform "ThinLink": just produce the index
637     if (OutputFilename.empty())
638       report_fatal_error(
639           "OutputFilename is necessary to store the combined index.\n");
640 
641     LLVMContext Ctx;
642     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
643     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
644       auto &Filename = InputFilenames[i];
645       std::string CurrentActivity = "loading file '" + Filename + "'";
646       auto InputOrErr = MemoryBuffer::getFile(Filename);
647       error(InputOrErr, "error " + CurrentActivity);
648       InputBuffers.push_back(std::move(*InputOrErr));
649       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
650     }
651 
652     auto CombinedIndex = ThinGenerator.linkCombinedIndex();
653     if (!CombinedIndex)
654       report_fatal_error("ThinLink didn't create an index");
655     std::error_code EC;
656     raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None);
657     error(EC, "error opening the file '" + OutputFilename + "'");
658     writeIndexToFile(*CombinedIndex, OS);
659   }
660 
661   /// Load the combined index from disk, then compute and generate
662   /// individual index files suitable for ThinLTO distributed backend builds
663   /// on the files mentioned on the command line (these must match the index
664   /// content).
665   void distributedIndexes() {
666     if (InputFilenames.size() != 1 && !OutputFilename.empty())
667       report_fatal_error("Can't handle a single output filename and multiple "
668                          "input files, do not provide an output filename and "
669                          "the output files will be suffixed from the input "
670                          "ones.");
671 
672     std::string OldPrefix, NewPrefix;
673     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
674 
675     auto Index = loadCombinedIndex();
676     for (auto &Filename : InputFilenames) {
677       LLVMContext Ctx;
678       auto Buffer = loadFile(Filename);
679       auto Input = loadInputFile(Buffer->getMemBufferRef());
680       auto TheModule = loadModuleFromInput(*Input, Ctx);
681 
682       // Build a map of module to the GUIDs and summary objects that should
683       // be written to its index.
684       std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex;
685       ThinGenerator.gatherImportedSummariesForModule(
686           *TheModule, *Index, ModuleToSummariesForIndex, *Input);
687 
688       std::string OutputName = OutputFilename;
689       if (OutputName.empty()) {
690         OutputName = Filename + ".thinlto.bc";
691       }
692       OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
693       std::error_code EC;
694       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
695       error(EC, "error opening the file '" + OutputName + "'");
696       writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex);
697     }
698   }
699 
700   /// Load the combined index from disk, compute the imports, and emit
701   /// the import file lists for each module to disk.
702   void emitImports() {
703     if (InputFilenames.size() != 1 && !OutputFilename.empty())
704       report_fatal_error("Can't handle a single output filename and multiple "
705                          "input files, do not provide an output filename and "
706                          "the output files will be suffixed from the input "
707                          "ones.");
708 
709     std::string OldPrefix, NewPrefix;
710     getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
711 
712     auto Index = loadCombinedIndex();
713     for (auto &Filename : InputFilenames) {
714       LLVMContext Ctx;
715       auto Buffer = loadFile(Filename);
716       auto Input = loadInputFile(Buffer->getMemBufferRef());
717       auto TheModule = loadModuleFromInput(*Input, Ctx);
718       std::string OutputName = OutputFilename;
719       if (OutputName.empty()) {
720         OutputName = Filename + ".imports";
721       }
722       OutputName =
723           getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
724       ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
725     }
726   }
727 
728   /// Load the combined index from disk, then load every file referenced by
729   /// the index and add them to the generator, finally perform the promotion
730   /// on the files mentioned on the command line (these must match the index
731   /// content).
732   void promote() {
733     if (InputFilenames.size() != 1 && !OutputFilename.empty())
734       report_fatal_error("Can't handle a single output filename and multiple "
735                          "input files, do not provide an output filename and "
736                          "the output files will be suffixed from the input "
737                          "ones.");
738 
739     auto Index = loadCombinedIndex();
740     for (auto &Filename : InputFilenames) {
741       LLVMContext Ctx;
742       auto Buffer = loadFile(Filename);
743       auto Input = loadInputFile(Buffer->getMemBufferRef());
744       auto TheModule = loadModuleFromInput(*Input, Ctx);
745 
746       ThinGenerator.promote(*TheModule, *Index, *Input);
747 
748       std::string OutputName = OutputFilename;
749       if (OutputName.empty()) {
750         OutputName = Filename + ".thinlto.promoted.bc";
751       }
752       writeModuleToFile(*TheModule, OutputName);
753     }
754   }
755 
756   /// Load the combined index from disk, then load every file referenced by
757   /// the index and add them to the generator, then performs the promotion and
758   /// cross module importing on the files mentioned on the command line
759   /// (these must match the index content).
760   void import() {
761     if (InputFilenames.size() != 1 && !OutputFilename.empty())
762       report_fatal_error("Can't handle a single output filename and multiple "
763                          "input files, do not provide an output filename and "
764                          "the output files will be suffixed from the input "
765                          "ones.");
766 
767     auto Index = loadCombinedIndex();
768     auto InputBuffers = loadAllFilesForIndex(*Index);
769     for (auto &MemBuffer : InputBuffers)
770       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
771                               MemBuffer->getBuffer());
772 
773     for (auto &Filename : InputFilenames) {
774       LLVMContext Ctx;
775       auto Buffer = loadFile(Filename);
776       auto Input = loadInputFile(Buffer->getMemBufferRef());
777       auto TheModule = loadModuleFromInput(*Input, Ctx);
778 
779       ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);
780 
781       std::string OutputName = OutputFilename;
782       if (OutputName.empty()) {
783         OutputName = Filename + ".thinlto.imported.bc";
784       }
785       writeModuleToFile(*TheModule, OutputName);
786     }
787   }
788 
789   void internalize() {
790     if (InputFilenames.size() != 1 && !OutputFilename.empty())
791       report_fatal_error("Can't handle a single output filename and multiple "
792                          "input files, do not provide an output filename and "
793                          "the output files will be suffixed from the input "
794                          "ones.");
795 
796     if (ExportedSymbols.empty())
797       errs() << "Warning: -internalize will not perform without "
798                 "-exported-symbol\n";
799 
800     auto Index = loadCombinedIndex();
801     auto InputBuffers = loadAllFilesForIndex(*Index);
802     for (auto &MemBuffer : InputBuffers)
803       ThinGenerator.addModule(MemBuffer->getBufferIdentifier(),
804                               MemBuffer->getBuffer());
805 
806     for (auto &Filename : InputFilenames) {
807       LLVMContext Ctx;
808       auto Buffer = loadFile(Filename);
809       auto Input = loadInputFile(Buffer->getMemBufferRef());
810       auto TheModule = loadModuleFromInput(*Input, Ctx);
811 
812       ThinGenerator.internalize(*TheModule, *Index, *Input);
813 
814       std::string OutputName = OutputFilename;
815       if (OutputName.empty()) {
816         OutputName = Filename + ".thinlto.internalized.bc";
817       }
818       writeModuleToFile(*TheModule, OutputName);
819     }
820   }
821 
822   void optimize() {
823     if (InputFilenames.size() != 1 && !OutputFilename.empty())
824       report_fatal_error("Can't handle a single output filename and multiple "
825                          "input files, do not provide an output filename and "
826                          "the output files will be suffixed from the input "
827                          "ones.");
828     if (!ThinLTOIndex.empty())
829       errs() << "Warning: -thinlto-index ignored for optimize stage";
830 
831     for (auto &Filename : InputFilenames) {
832       LLVMContext Ctx;
833       auto Buffer = loadFile(Filename);
834       auto Input = loadInputFile(Buffer->getMemBufferRef());
835       auto TheModule = loadModuleFromInput(*Input, Ctx);
836 
837       ThinGenerator.optimize(*TheModule);
838 
839       std::string OutputName = OutputFilename;
840       if (OutputName.empty()) {
841         OutputName = Filename + ".thinlto.imported.bc";
842       }
843       writeModuleToFile(*TheModule, OutputName);
844     }
845   }
846 
847   void codegen() {
848     if (InputFilenames.size() != 1 && !OutputFilename.empty())
849       report_fatal_error("Can't handle a single output filename and multiple "
850                          "input files, do not provide an output filename and "
851                          "the output files will be suffixed from the input "
852                          "ones.");
853     if (!ThinLTOIndex.empty())
854       errs() << "Warning: -thinlto-index ignored for codegen stage";
855 
856     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
857     for (auto &Filename : InputFilenames) {
858       LLVMContext Ctx;
859       auto InputOrErr = MemoryBuffer::getFile(Filename);
860       error(InputOrErr, "error " + CurrentActivity);
861       InputBuffers.push_back(std::move(*InputOrErr));
862       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
863     }
864     ThinGenerator.setCodeGenOnly(true);
865     ThinGenerator.run();
866     for (auto BinName :
867          zip(ThinGenerator.getProducedBinaries(), InputFilenames)) {
868       std::string OutputName = OutputFilename;
869       if (OutputName.empty())
870         OutputName = std::get<1>(BinName) + ".thinlto.o";
871       else if (OutputName == "-") {
872         outs() << std::get<0>(BinName)->getBuffer();
873         return;
874       }
875 
876       std::error_code EC;
877       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
878       error(EC, "error opening the file '" + OutputName + "'");
879       OS << std::get<0>(BinName)->getBuffer();
880     }
881   }
882 
883   /// Full ThinLTO process
884   void runAll() {
885     if (!OutputFilename.empty())
886       report_fatal_error("Do not provide an output filename for ThinLTO "
887                          " processing, the output files will be suffixed from "
888                          "the input ones.");
889 
890     if (!ThinLTOIndex.empty())
891       errs() << "Warning: -thinlto-index ignored for full ThinLTO process";
892 
893     LLVMContext Ctx;
894     std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
895     for (unsigned i = 0; i < InputFilenames.size(); ++i) {
896       auto &Filename = InputFilenames[i];
897       std::string CurrentActivity = "loading file '" + Filename + "'";
898       auto InputOrErr = MemoryBuffer::getFile(Filename);
899       error(InputOrErr, "error " + CurrentActivity);
900       InputBuffers.push_back(std::move(*InputOrErr));
901       ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer());
902     }
903 
904     if (!ThinLTOSaveTempsPrefix.empty())
905       ThinGenerator.setSaveTempsDir(ThinLTOSaveTempsPrefix);
906 
907     if (!ThinLTOGeneratedObjectsDir.empty()) {
908       ThinGenerator.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir);
909       ThinGenerator.run();
910       return;
911     }
912 
913     ThinGenerator.run();
914 
915     auto &Binaries = ThinGenerator.getProducedBinaries();
916     if (Binaries.size() != InputFilenames.size())
917       report_fatal_error("Number of output objects does not match the number "
918                          "of inputs");
919 
920     for (unsigned BufID = 0; BufID < Binaries.size(); ++BufID) {
921       auto OutputName = InputFilenames[BufID] + ".thinlto.o";
922       std::error_code EC;
923       raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None);
924       error(EC, "error opening the file '" + OutputName + "'");
925       OS << Binaries[BufID]->getBuffer();
926     }
927   }
928 
929   /// Load the combined index from disk, then load every file referenced by
930 };
931 
932 } // end namespace thinlto
933 
934 int main(int argc, char **argv) {
935   InitLLVM X(argc, argv);
936   cl::HideUnrelatedOptions({&LTOCategory, &getColorCategory()});
937   cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n");
938 
939   if (OptLevel < '0' || OptLevel > '3')
940     error("optimization level must be between 0 and 3");
941 
942   // Initialize the configured targets.
943   InitializeAllTargets();
944   InitializeAllTargetMCs();
945   InitializeAllAsmPrinters();
946   InitializeAllAsmParsers();
947 
948   // set up the TargetOptions for the machine
949   TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
950 
951   if (ListSymbolsOnly || QueryHasCtorDtor) {
952     testLTOModule(Options);
953     return 0;
954   }
955 
956   if (ListDependentLibrariesOnly) {
957     listDependentLibraries();
958     return 0;
959   }
960 
961   if (IndexStats) {
962     printIndexStats();
963     return 0;
964   }
965 
966   if (CheckHasObjC) {
967     for (auto &Filename : InputFilenames) {
968       ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" +
969                             Filename + "': ");
970       std::unique_ptr<MemoryBuffer> BufferOrErr =
971           ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename)));
972       auto Buffer = std::move(BufferOrErr.get());
973       if (ExitOnErr(isBitcodeContainingObjCCategory(*Buffer)))
974         outs() << "Bitcode " << Filename << " contains ObjC\n";
975       else
976         outs() << "Bitcode " << Filename << " does not contain ObjC\n";
977     }
978     return 0;
979   }
980 
981   if (PrintMachOCPUOnly) {
982     printMachOCPUOnly();
983     return 0;
984   }
985 
986   if (ThinLTOMode.getNumOccurrences()) {
987     if (ThinLTOMode.getNumOccurrences() > 1)
988       report_fatal_error("You can't specify more than one -thinlto-action");
989     thinlto::ThinLTOProcessing ThinLTOProcessor(Options);
990     ThinLTOProcessor.run();
991     return 0;
992   }
993 
994   if (ThinLTO) {
995     createCombinedModuleSummaryIndex();
996     return 0;
997   }
998 
999   unsigned BaseArg = 0;
1000 
1001   LLVMContext Context;
1002   Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(),
1003                                true);
1004 
1005   LTOCodeGenerator CodeGen(Context);
1006   CodeGen.setDisableVerify(DisableVerify);
1007 
1008   if (UseDiagnosticHandler)
1009     CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr);
1010 
1011   CodeGen.setCodePICModel(codegen::getExplicitRelocModel());
1012   CodeGen.setFreestanding(EnableFreestanding);
1013   CodeGen.setDebugPassManager(DebugPassManager);
1014 
1015   CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
1016   CodeGen.setTargetOptions(Options);
1017   CodeGen.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage);
1018 
1019   StringSet<MallocAllocator> DSOSymbolsSet;
1020   for (unsigned i = 0; i < DSOSymbols.size(); ++i)
1021     DSOSymbolsSet.insert(DSOSymbols[i]);
1022 
1023   std::vector<std::string> KeptDSOSyms;
1024 
1025   for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) {
1026     CurrentActivity = "loading file '" + InputFilenames[i] + "'";
1027     ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr =
1028         LTOModule::createFromFile(Context, InputFilenames[i], Options);
1029     std::unique_ptr<LTOModule> &Module = *ModuleOrErr;
1030     CurrentActivity = "";
1031 
1032     unsigned NumSyms = Module->getSymbolCount();
1033     for (unsigned I = 0; I < NumSyms; ++I) {
1034       StringRef Name = Module->getSymbolName(I);
1035       if (!DSOSymbolsSet.count(Name))
1036         continue;
1037       lto_symbol_attributes Attrs = Module->getSymbolAttributes(I);
1038       unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK;
1039       if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN)
1040         KeptDSOSyms.push_back(std::string(Name));
1041     }
1042 
1043     // We use the first input module as the destination module when
1044     // SetMergedModule is true.
1045     if (SetMergedModule && i == BaseArg) {
1046       // Transfer ownership to the code generator.
1047       CodeGen.setModule(std::move(Module));
1048     } else if (!CodeGen.addModule(Module.get())) {
1049       // Print a message here so that we know addModule() did not abort.
1050       error("error adding file '" + InputFilenames[i] + "'");
1051     }
1052   }
1053 
1054   // Add all the exported symbols to the table of symbols to preserve.
1055   for (unsigned i = 0; i < ExportedSymbols.size(); ++i)
1056     CodeGen.addMustPreserveSymbol(ExportedSymbols[i]);
1057 
1058   // Add all the dso symbols to the table of symbols to expose.
1059   for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
1060     CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]);
1061 
1062   // Set cpu and attrs strings for the default target/subtarget.
1063   CodeGen.setCpu(codegen::getMCPU());
1064 
1065   CodeGen.setOptLevel(OptLevel - '0');
1066   CodeGen.setAttrs(codegen::getMAttrs());
1067 
1068   if (auto FT = codegen::getExplicitFileType())
1069     CodeGen.setFileType(*FT);
1070 
1071   if (!OutputFilename.empty()) {
1072     if (SaveLinkedModuleFile) {
1073       std::string ModuleFilename = OutputFilename;
1074       ModuleFilename += ".linked.bc";
1075       std::string ErrMsg;
1076 
1077       if (!CodeGen.writeMergedModules(ModuleFilename))
1078         error("writing linked module failed.");
1079     }
1080 
1081     if (!CodeGen.optimize()) {
1082       // Diagnostic messages should have been printed by the handler.
1083       error("error optimizing the code");
1084     }
1085 
1086     if (SaveModuleFile) {
1087       std::string ModuleFilename = OutputFilename;
1088       ModuleFilename += ".merged.bc";
1089       std::string ErrMsg;
1090 
1091       if (!CodeGen.writeMergedModules(ModuleFilename))
1092         error("writing merged module failed.");
1093     }
1094 
1095     auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
1096       std::string PartFilename = OutputFilename;
1097       if (Parallelism != 1)
1098         PartFilename += "." + utostr(Task);
1099 
1100       std::error_code EC;
1101       auto S =
1102           std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None);
1103       if (EC)
1104         error("error opening the file '" + PartFilename + "': " + EC.message());
1105       return std::make_unique<CachedFileStream>(std::move(S));
1106     };
1107 
1108     if (!CodeGen.compileOptimized(AddStream, Parallelism))
1109       // Diagnostic messages should have been printed by the handler.
1110       error("error compiling the code");
1111 
1112   } else {
1113     if (Parallelism != 1)
1114       error("-j must be specified together with -o");
1115 
1116     if (SaveModuleFile)
1117       error(": -save-merged-module must be specified with -o");
1118 
1119     const char *OutputName = nullptr;
1120     if (!CodeGen.compile_to_file(&OutputName))
1121       error("error compiling the code");
1122       // Diagnostic messages should have been printed by the handler.
1123 
1124     outs() << "Wrote native object file '" << OutputName << "'\n";
1125   }
1126 
1127   return 0;
1128 }
1129