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