1 //===- llvm-lto: a simple command-line program to link modules with LTO ---===//
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
7 //===----------------------------------------------------------------------===//
9 // This program takes in a list of bitcode files, links them, performs link-time
10 // optimization, and outputs an object file.
12 //===----------------------------------------------------------------------===//
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"
58 #include <system_error>
65 static codegen::RegisterCodeGenFlags CGF
;
67 static cl::OptionCategory
LTOCategory("LTO Options");
71 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
73 cl::Prefix
, cl::init('2'), cl::cat(LTOCategory
));
76 IndexStats("thinlto-index-stats",
77 cl::desc("Print statistic for the index in every input files"),
78 cl::init(false), cl::cat(LTOCategory
));
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
));
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
));
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
));
96 ThinLTO("thinlto", cl::init(false),
97 cl::desc("Only write combined global index for ThinLTO backends"),
98 cl::cat(LTOCategory
));
112 cl::opt
<ThinLTOModes
> ThinLTOMode(
113 "thinlto-action", cl::desc("Perform a single ThinLTO stage:"),
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 "
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
));
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
));
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
));
150 static cl::opt
<std::string
> ThinLTOModuleId(
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
));
156 static cl::opt
<std::string
> ThinLTOCacheDir("thinlto-cache-dir",
157 cl::desc("Enable ThinLTO caching."),
158 cl::cat(LTOCategory
));
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
));
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
));
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
));
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
));
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
));
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
));
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
));
196 SaveModuleFile("save-merged-module", cl::init(false),
197 cl::desc("Write merged LTO module to file before CodeGen"),
198 cl::cat(LTOCategory
));
200 static cl::list
<std::string
> InputFilenames(cl::Positional
, cl::OneOrMore
,
201 cl::desc("<input bitcode files>"),
202 cl::cat(LTOCategory
));
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
));
209 static cl::list
<std::string
> ExportedSymbols(
211 cl::desc("List of symbols to export from the resulting object file"),
212 cl::cat(LTOCategory
));
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
));
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
));
224 static cl::opt
<bool> ListDependentLibrariesOnly(
225 "list-dependent-libraries-only", cl::init(false),
227 "Instead of running LTO, list the dependent libraries in each IR file"),
228 cl::cat(LTOCategory
));
230 static cl::opt
<bool> QueryHasCtorDtor(
231 "query-hasCtorDtor", cl::init(false),
232 cl::desc("Queries LTOModule::hasCtorDtor() on each IR file"));
235 SetMergedModule("set-merged-module", cl::init(false),
236 cl::desc("Use the first input module as the merged module"),
237 cl::cat(LTOCategory
));
239 static cl::opt
<unsigned> Parallelism("j", cl::Prefix
, cl::init(1),
240 cl::desc("Number of backend threads"),
241 cl::cat(LTOCategory
));
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
));
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
));
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
));
259 DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden
,
260 cl::desc("Print pass management debugging information"),
261 cl::cat(LTOCategory
));
264 LTOSaveBeforeOpt("lto-save-before-opt", cl::init(false),
265 cl::desc("Save the IR before running optimizations"));
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
);
272 extern cl::opt
<bool> UseNewDbgInfoFormat
;
273 extern cl::opt
<cl::boolOrDefault
> LoadBitcodeIntoNewDbgInfoFormat
;
274 extern cl::opt
<cl::boolOrDefault
> PreserveInputDbgFormat
;
279 BitVector CanBeHidden
;
282 } // end anonymous namespace
284 static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity
,
285 const char *Msg
, void *) {
286 errs() << "llvm-lto: ";
292 errs() << "remark: ";
298 errs() << "warning: ";
301 errs() << Msg
<< "\n";
304 static std::string CurrentActivity
;
307 struct LLVMLTODiagnosticHandler
: public DiagnosticHandler
{
308 bool handleDiagnostics(const DiagnosticInfo
&DI
) override
{
309 raw_ostream
&OS
= errs();
311 switch (DI
.getSeverity()) {
325 if (!CurrentActivity
.empty())
326 OS
<< ' ' << CurrentActivity
;
329 DiagnosticPrinterRawOStream
DP(OS
);
333 if (DI
.getSeverity() == DS_Error
)
340 static void error(const Twine
&Msg
) {
341 errs() << "llvm-lto: " << Msg
<< '\n';
345 static void error(std::error_code EC
, const Twine
&Prefix
) {
347 error(Prefix
+ ": " + EC
.message());
350 template <typename T
>
351 static void error(const ErrorOr
<T
> &V
, const Twine
&Prefix
) {
352 error(V
.getError(), Prefix
);
355 static void maybeVerifyModule(const Module
&Mod
) {
356 if (!DisableVerify
&& verifyModule(Mod
, &errs()))
357 error("Broken Module");
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
>(),
371 ErrorOr
<std::unique_ptr
<LTOModule
>> Ret
= LTOModule::createInLocalContext(
372 std::move(Context
), Buffer
->getBufferStart(), Buffer
->getBufferSize(),
374 CurrentActivity
= "";
375 maybeVerifyModule((*Ret
)->getModule());
376 return std::move(*Ret
);
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.
387 report_fatal_error(Twine(Filename
) + " does not contain an index");
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())) {
395 Calls
+= FuncSummary
->calls().size();
396 } else if (isa
<AliasSummary
>(Summary
.get()))
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";
410 /// Print the lto symbol attributes.
411 static void printLTOSymbolAttributes(lto_symbol_attributes Attrs
) {
413 unsigned Permission
= Attrs
& LTO_SYMBOL_PERMISSIONS_MASK
;
414 switch (Permission
) {
415 case LTO_SYMBOL_PERMISSIONS_CODE
:
416 outs() << "function ";
418 case LTO_SYMBOL_PERMISSIONS_DATA
:
421 case LTO_SYMBOL_PERMISSIONS_RODATA
:
422 outs() << "constant ";
425 unsigned Definition
= Attrs
& LTO_SYMBOL_DEFINITION_MASK
;
426 switch (Definition
) {
427 case LTO_SYMBOL_DEFINITION_REGULAR
:
428 outs() << "defined ";
430 case LTO_SYMBOL_DEFINITION_TENTATIVE
:
433 case LTO_SYMBOL_DEFINITION_WEAK
:
436 case LTO_SYMBOL_DEFINITION_UNDEFINED
:
439 case LTO_SYMBOL_DEFINITION_WEAKUNDEF
:
440 outs() << "extern-weak ";
443 unsigned Scope
= Attrs
& LTO_SYMBOL_SCOPE_MASK
;
445 case LTO_SYMBOL_SCOPE_INTERNAL
:
446 outs() << "internal ";
448 case LTO_SYMBOL_SCOPE_HIDDEN
:
451 case LTO_SYMBOL_SCOPE_PROTECTED
:
452 outs() << "protected ";
454 case LTO_SYMBOL_SCOPE_DEFAULT
:
455 outs() << "default ";
457 case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN
:
458 outs() << "omitted ";
461 if (Attrs
& LTO_SYMBOL_COMDAT
)
463 if (Attrs
& LTO_SYMBOL_ALIAS
)
468 /// Load each IR file and dump certain information based on active flags.
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
);
479 if (ListSymbolsOnly
) {
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
));
488 if (QueryHasCtorDtor
)
490 << ": hasCtorDtor = " << (Module
->hasCtorDtor() ? "true" : "false")
495 static std::unique_ptr
<MemoryBuffer
> loadFile(StringRef Filename
) {
496 ExitOnError
ExitOnErr("llvm-lto: error loading file '" + Filename
.str() +
498 return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename
)));
501 static void listDependentLibraries() {
502 for (auto &Filename
: InputFilenames
) {
503 auto Buffer
= loadFile(Filename
);
505 std::unique_ptr
<lto::InputFile
> Input(LTOModule::createInputFile(
506 Buffer
->getBufferStart(), Buffer
->getBufferSize(), Filename
.c_str(),
511 // List the dependent libraries.
512 outs() << Filename
<< ":\n";
513 for (size_t I
= 0, C
= LTOModule::getDependentLibraryCount(Input
.get());
516 const char *S
= LTOModule::getDependentLibrary(Input
.get(), I
, &L
);
518 outs() << StringRef(S
, L
) << "\n";
523 static void printMachOCPUOnly() {
525 Context
.setDiagnosticHandler(std::make_unique
<LLVMLTODiagnosticHandler
>(),
527 TargetOptions Options
= codegen::InitTargetOptionsFromCodeGenFlags(Triple());
528 for (auto &Filename
: InputFilenames
) {
529 ErrorOr
<std::unique_ptr
<LTOModule
>> ModuleOrErr
=
530 LTOModule::createFromFile(Context
, Filename
, Options
);
532 error(ModuleOrErr
, "llvm-lto: ");
534 Expected
<uint32_t> CPUType
= (*ModuleOrErr
)->getMachOCPUType();
535 Expected
<uint32_t> CPUSubType
= (*ModuleOrErr
)->getMachOCPUSubType();
537 error("Error while printing mach-o cputype: " +
538 toString(CPUType
.takeError()));
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
);
547 /// Create a combined index file from the input IR files and write it.
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
));
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
);
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
);
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();
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
+ "'");
599 return std::string(NewPath
);
604 std::vector
<std::unique_ptr
<MemoryBuffer
>>
605 loadAllFilesForIndex(const ModuleSummaryIndex
&Index
) {
606 std::vector
<std::unique_ptr
<MemoryBuffer
>> InputBuffers
;
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
));
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
+
623 return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex
));
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
));
632 static std::unique_ptr
<Module
> loadModuleFromInput(lto::InputFile
&File
,
634 auto &Mod
= File
.getSingleBitcodeModule();
635 auto ModuleOrErr
= Mod
.parseModule(CTX
);
637 handleAllErrors(ModuleOrErr
.takeError(), [&](ErrorInfoBase
&EIB
) {
638 SMDiagnostic Err
= SMDiagnostic(Mod
.getModuleIdentifier(),
639 SourceMgr::DK_Error
, EIB
.message());
640 Err
.print("llvm-lto", errs());
642 report_fatal_error("Can't load module, abort.");
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
);
650 return std::move(*ModuleOrErr
);
653 static void writeModuleToFile(Module
&TheModule
, StringRef Filename
) {
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);
661 class ThinLTOProcessing
{
663 ThinLTOCodeGenerator ThinGenerator
;
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
);
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
]);
682 switch (ThinLTOMode
) {
686 return distributedIndexes();
687 case THINEMITIMPORTS
:
688 return emitImports();
693 case THININTERNALIZE
:
694 return internalize();
705 /// Load the input files, create the combined index, and write it out.
707 // Perform "ThinLink": just produce the index
708 if (OutputFilename
.empty())
710 "OutputFilename is necessary to store the combined index.\n");
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());
723 auto CombinedIndex
= ThinGenerator
.linkCombinedIndex();
725 report_fatal_error("ThinLink didn't create an index");
727 raw_fd_ostream
OS(OutputFilename
, EC
, sys::fs::OpenFlags::OF_None
);
728 error(EC
, "error opening the file '" + OutputFilename
+ "'");
729 writeIndexToFile(*CombinedIndex
, OS
);
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
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 "
743 std::string OldPrefix
, NewPrefix
;
744 getThinLTOOldAndNewPrefix(OldPrefix
, NewPrefix
);
746 auto Index
= loadCombinedIndex();
747 for (auto &Filename
: InputFilenames
) {
749 auto Buffer
= loadFile(Filename
);
750 auto Input
= loadInputFile(Buffer
->getMemBufferRef());
751 auto TheModule
= loadModuleFromInput(*Input
, Ctx
);
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
);
760 std::string OutputName
= OutputFilename
;
761 if (OutputName
.empty()) {
762 OutputName
= Filename
+ ".thinlto.bc";
764 OutputName
= getThinLTOOutputFile(OutputName
, OldPrefix
, NewPrefix
);
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
);
772 /// Load the combined index from disk, compute the imports, and emit
773 /// the import file lists for each module to disk.
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 "
781 std::string OldPrefix
, NewPrefix
;
782 getThinLTOOldAndNewPrefix(OldPrefix
, NewPrefix
);
784 auto Index
= loadCombinedIndex();
785 for (auto &Filename
: InputFilenames
) {
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";
795 getThinLTOOutputFile(OutputName
, OldPrefix
, NewPrefix
);
796 ThinGenerator
.emitImports(*TheModule
, OutputName
, *Index
, *Input
);
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
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 "
811 auto Index
= loadCombinedIndex();
812 for (auto &Filename
: InputFilenames
) {
814 auto Buffer
= loadFile(Filename
);
815 auto Input
= loadInputFile(Buffer
->getMemBufferRef());
816 auto TheModule
= loadModuleFromInput(*Input
, Ctx
);
818 ThinGenerator
.promote(*TheModule
, *Index
, *Input
);
820 std::string OutputName
= OutputFilename
;
821 if (OutputName
.empty()) {
822 OutputName
= Filename
+ ".thinlto.promoted.bc";
824 writeModuleToFile(*TheModule
, OutputName
);
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).
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 "
839 auto Index
= loadCombinedIndex();
840 auto InputBuffers
= loadAllFilesForIndex(*Index
);
841 for (auto &MemBuffer
: InputBuffers
)
842 ThinGenerator
.addModule(MemBuffer
->getBufferIdentifier(),
843 MemBuffer
->getBuffer());
845 for (auto &Filename
: InputFilenames
) {
847 auto Buffer
= loadFile(Filename
);
848 auto Input
= loadInputFile(Buffer
->getMemBufferRef());
849 auto TheModule
= loadModuleFromInput(*Input
, Ctx
);
851 ThinGenerator
.crossModuleImport(*TheModule
, *Index
, *Input
);
853 std::string OutputName
= OutputFilename
;
854 if (OutputName
.empty()) {
855 OutputName
= Filename
+ ".thinlto.imported.bc";
857 writeModuleToFile(*TheModule
, OutputName
);
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 "
868 if (ExportedSymbols
.empty())
869 errs() << "Warning: -internalize will not perform without "
870 "-exported-symbol\n";
872 auto Index
= loadCombinedIndex();
873 auto InputBuffers
= loadAllFilesForIndex(*Index
);
874 for (auto &MemBuffer
: InputBuffers
)
875 ThinGenerator
.addModule(MemBuffer
->getBufferIdentifier(),
876 MemBuffer
->getBuffer());
878 for (auto &Filename
: InputFilenames
) {
880 auto Buffer
= loadFile(Filename
);
881 auto Input
= loadInputFile(Buffer
->getMemBufferRef());
882 auto TheModule
= loadModuleFromInput(*Input
, Ctx
);
884 ThinGenerator
.internalize(*TheModule
, *Index
, *Input
);
886 std::string OutputName
= OutputFilename
;
887 if (OutputName
.empty()) {
888 OutputName
= Filename
+ ".thinlto.internalized.bc";
890 writeModuleToFile(*TheModule
, OutputName
);
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 "
900 if (!ThinLTOIndex
.empty())
901 errs() << "Warning: -thinlto-index ignored for optimize stage";
903 for (auto &Filename
: InputFilenames
) {
905 auto Buffer
= loadFile(Filename
);
906 auto Input
= loadInputFile(Buffer
->getMemBufferRef());
907 auto TheModule
= loadModuleFromInput(*Input
, Ctx
);
909 ThinGenerator
.optimize(*TheModule
);
911 std::string OutputName
= OutputFilename
;
912 if (OutputName
.empty()) {
913 OutputName
= Filename
+ ".thinlto.imported.bc";
915 writeModuleToFile(*TheModule
, OutputName
);
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 "
925 if (!ThinLTOIndex
.empty())
926 errs() << "Warning: -thinlto-index ignored for codegen stage";
928 std::vector
<std::unique_ptr
<MemoryBuffer
>> InputBuffers
;
929 for (auto &Filename
: InputFilenames
) {
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());
936 ThinGenerator
.setCodeGenOnly(true);
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();
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();
955 /// Full ThinLTO process
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 "
962 if (!ThinLTOIndex
.empty())
963 errs() << "Warning: -thinlto-index ignored for full ThinLTO process";
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());
976 if (!ThinLTOSaveTempsPrefix
.empty())
977 ThinGenerator
.setSaveTempsDir(ThinLTOSaveTempsPrefix
);
979 if (!ThinLTOGeneratedObjectsDir
.empty()) {
980 ThinGenerator
.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir
);
987 auto &Binaries
= ThinGenerator
.getProducedBinaries();
988 if (Binaries
.size() != InputFilenames
.size())
989 report_fatal_error("Number of output objects does not match the number "
992 for (unsigned BufID
= 0; BufID
< Binaries
.size(); ++BufID
) {
993 auto OutputName
= InputFilenames
[BufID
] + ".thinlto.o";
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();
1001 /// Load the combined index from disk, then load every file referenced by
1004 } // end namespace thinlto
1006 int main(int argc
, char **argv
) {
1007 InitLLVM
X(argc
, argv
);
1008 cl::HideUnrelatedOptions({<OCategory
, &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
;
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;
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
1023 PreserveInputDbgFormat
= cl::boolOrDefault::BOU_FALSE
;
1025 if (OptLevel
< '0' || OptLevel
> '3')
1026 error("optimization level must be between 0 and 3");
1028 // Initialize the configured targets.
1029 InitializeAllTargets();
1030 InitializeAllTargetMCs();
1031 InitializeAllAsmPrinters();
1032 InitializeAllAsmParsers();
1034 // set up the TargetOptions for the machine
1035 TargetOptions Options
= codegen::InitTargetOptionsFromCodeGenFlags(Triple());
1037 if (ListSymbolsOnly
|| QueryHasCtorDtor
) {
1038 testLTOModule(Options
);
1042 if (ListDependentLibrariesOnly
) {
1043 listDependentLibraries();
1053 for (auto &Filename
: InputFilenames
) {
1054 ExitOnError
ExitOnErr(std::string(*argv
) + ": error loading file '" +
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";
1062 outs() << "Bitcode " << Filename
<< " does not contain ObjC\n";
1067 if (PrintMachOCPUOnly
) {
1068 printMachOCPUOnly();
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();
1081 createCombinedModuleSummaryIndex();
1085 unsigned BaseArg
= 0;
1087 LLVMContext Context
;
1088 Context
.setDiagnosticHandler(std::make_unique
<LLVMLTODiagnosticHandler
>(),
1091 LTOCodeGenerator
CodeGen(Context
);
1092 CodeGen
.setDisableVerify(DisableVerify
);
1094 if (UseDiagnosticHandler
)
1095 CodeGen
.setDiagnosticHandler(handleDiagnostics
, nullptr);
1097 CodeGen
.setCodePICModel(codegen::getExplicitRelocModel());
1098 CodeGen
.setFreestanding(EnableFreestanding
);
1099 CodeGen
.setDebugPassManager(DebugPassManager
);
1101 CodeGen
.setDebugInfo(LTO_DEBUG_MODEL_DWARF
);
1102 CodeGen
.setTargetOptions(Options
);
1103 CodeGen
.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage
);
1105 StringSet
<MallocAllocator
> DSOSymbolsSet
;
1106 for (unsigned i
= 0; i
< DSOSymbols
.size(); ++i
)
1107 DSOSymbolsSet
.insert(DSOSymbols
[i
]);
1109 std::vector
<std::string
> KeptDSOSyms
;
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
= "";
1118 unsigned NumSyms
= Module
->getSymbolCount();
1119 for (unsigned I
= 0; I
< NumSyms
; ++I
) {
1120 StringRef Name
= Module
->getSymbolName(I
);
1121 if (!DSOSymbolsSet
.count(Name
))
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
));
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
] + "'");
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
]);
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
]);
1148 // Set cpu and attrs strings for the default target/subtarget.
1149 CodeGen
.setCpu(codegen::getMCPU());
1151 CodeGen
.setOptLevel(OptLevel
- '0');
1152 CodeGen
.setAttrs(codegen::getMAttrs());
1154 if (auto FT
= codegen::getExplicitFileType())
1155 CodeGen
.setFileType(*FT
);
1157 if (!OutputFilename
.empty()) {
1158 if (LTOSaveBeforeOpt
)
1159 CodeGen
.setSaveIRBeforeOptPath(OutputFilename
+ ".0.preopt.bc");
1161 if (SaveLinkedModuleFile
) {
1162 std::string ModuleFilename
= OutputFilename
;
1163 ModuleFilename
+= ".linked.bc";
1166 if (!CodeGen
.writeMergedModules(ModuleFilename
))
1167 error("writing linked module failed.");
1170 if (!CodeGen
.optimize()) {
1171 // Diagnostic messages should have been printed by the handler.
1172 error("error optimizing the code");
1175 if (SaveModuleFile
) {
1176 std::string ModuleFilename
= OutputFilename
;
1177 ModuleFilename
+= ".merged.bc";
1180 if (!CodeGen
.writeMergedModules(ModuleFilename
))
1181 error("writing merged module failed.");
1186 const Twine
&ModuleName
) -> std::unique_ptr
<CachedFileStream
> {
1187 std::string PartFilename
= OutputFilename
;
1188 if (Parallelism
!= 1)
1189 PartFilename
+= "." + utostr(Task
);
1193 std::make_unique
<raw_fd_ostream
>(PartFilename
, EC
, sys::fs::OF_None
);
1195 error("error opening the file '" + PartFilename
+ "': " + EC
.message());
1196 return std::make_unique
<CachedFileStream
>(std::move(S
));
1199 if (!CodeGen
.compileOptimized(AddStream
, Parallelism
))
1200 // Diagnostic messages should have been printed by the handler.
1201 error("error compiling the code");
1204 if (Parallelism
!= 1)
1205 error("-j must be specified together with -o");
1208 error(": -save-merged-module must be specified with -o");
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.
1215 outs() << "Wrote native object file '" << OutputName
<< "'\n";