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