1 //===- LTO.cpp ------------------------------------------------------------===//
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 //===----------------------------------------------------------------------===//
11 #include "InputFiles.h"
13 #include "lld/Common/Args.h"
14 #include "lld/Common/ErrorHandler.h"
15 #include "lld/Common/Strings.h"
16 #include "lld/Common/TargetOptionsCommandFlags.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/IR/DiagnosticPrinter.h"
22 #include "llvm/LTO/Config.h"
23 #include "llvm/LTO/LTO.h"
24 #include "llvm/Object/SymbolicFile.h"
25 #include "llvm/Support/Caching.h"
26 #include "llvm/Support/CodeGen.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/raw_ostream.h"
35 #include <system_error>
41 static std::unique_ptr
<lto::LTO
> createLTO() {
43 c
.Options
= initTargetOptionsFromCodeGenFlags();
45 // Always emit a section per function/data with LTO.
46 c
.Options
.FunctionSections
= true;
47 c
.Options
.DataSections
= true;
49 c
.DisableVerify
= config
->disableVerify
;
50 c
.DiagHandler
= diagnosticHandler
;
51 c
.OptLevel
= config
->ltoo
;
52 c
.MAttrs
= getMAttrs();
53 c
.CGOptLevel
= config
->ltoCgo
;
54 c
.DebugPassManager
= config
->ltoDebugPassManager
;
56 if (config
->relocatable
)
57 c
.RelocModel
= std::nullopt
;
58 else if (config
->isPic
)
59 c
.RelocModel
= Reloc::PIC_
;
61 c
.RelocModel
= Reloc::Static
;
63 if (config
->saveTemps
)
64 checkError(c
.addSaveTemps(config
->outputFile
.str() + ".",
65 /*UseInputModulePath*/ true));
66 lto::ThinBackend backend
= lto::createInProcessThinBackend(
67 llvm::heavyweight_hardware_concurrency(config
->thinLTOJobs
));
68 return std::make_unique
<lto::LTO
>(std::move(c
), backend
,
69 config
->ltoPartitions
);
72 BitcodeCompiler::BitcodeCompiler() : ltoObj(createLTO()) {}
74 BitcodeCompiler::~BitcodeCompiler() = default;
76 static void undefine(Symbol
*s
) {
77 if (auto f
= dyn_cast
<DefinedFunction
>(s
))
78 replaceSymbol
<UndefinedFunction
>(f
, f
->getName(), std::nullopt
,
79 std::nullopt
, 0, f
->getFile(),
81 else if (isa
<DefinedData
>(s
))
82 replaceSymbol
<UndefinedData
>(s
, s
->getName(), 0, s
->getFile());
84 llvm_unreachable("unexpected symbol kind");
87 void BitcodeCompiler::add(BitcodeFile
&f
) {
88 lto::InputFile
&obj
= *f
.obj
;
90 ArrayRef
<Symbol
*> syms
= f
.getSymbols();
91 std::vector
<lto::SymbolResolution
> resols(syms
.size());
93 // Provide a resolution to the LTO API for each symbol.
94 for (const lto::InputFile::Symbol
&objSym
: obj
.symbols()) {
95 Symbol
*sym
= syms
[symNum
];
96 lto::SymbolResolution
&r
= resols
[symNum
];
99 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
100 // reports two symbols for module ASM defined. Without this check, lld
101 // flags an undefined in IR with a definition in ASM as prevailing.
102 // Once IRObjectFile is fixed to report only one symbol this hack can
104 r
.Prevailing
= !objSym
.isUndefined() && sym
->getFile() == &f
;
105 r
.VisibleToRegularObj
= config
->relocatable
|| sym
->isUsedInRegularObj
||
107 (r
.Prevailing
&& sym
->isExported());
111 // We tell LTO to not apply interprocedural optimization for wrapped
112 // (with --wrap) symbols because otherwise LTO would inline them while
113 // their values are still not final.
114 r
.LinkerRedefined
= !sym
->canInline
;
116 checkError(ltoObj
->add(std::move(f
.obj
), resols
));
119 // Merge all the bitcode files we have seen, codegen the result
120 // and return the resulting objects.
121 std::vector
<StringRef
> BitcodeCompiler::compile() {
122 unsigned maxTasks
= ltoObj
->getMaxTasks();
123 buf
.resize(maxTasks
);
124 files
.resize(maxTasks
);
126 // The --thinlto-cache-dir option specifies the path to a directory in which
127 // to cache native object files for ThinLTO incremental builds. If a path was
128 // specified, configure LTO to use it as the cache directory.
130 if (!config
->thinLTOCacheDir
.empty())
131 cache
= check(localCache("ThinLTO", "Thin", config
->thinLTOCacheDir
,
132 [&](size_t task
, const Twine
&moduleName
,
133 std::unique_ptr
<MemoryBuffer
> mb
) {
134 files
[task
] = std::move(mb
);
137 checkError(ltoObj
->run(
138 [&](size_t task
, const Twine
&moduleName
) {
139 return std::make_unique
<CachedFileStream
>(
140 std::make_unique
<raw_svector_ostream
>(buf
[task
]));
144 if (!config
->thinLTOCacheDir
.empty())
145 pruneCache(config
->thinLTOCacheDir
, config
->thinLTOCachePolicy
, files
);
147 std::vector
<StringRef
> ret
;
148 for (unsigned i
= 0; i
!= maxTasks
; ++i
) {
151 if (config
->saveTemps
) {
153 saveBuffer(buf
[i
], config
->outputFile
+ ".lto.o");
155 saveBuffer(buf
[i
], config
->outputFile
+ Twine(i
) + ".lto.o");
157 ret
.emplace_back(buf
[i
].data(), buf
[i
].size());
160 for (std::unique_ptr
<MemoryBuffer
> &file
: files
)
162 ret
.push_back(file
->getBuffer());
167 } // namespace lld::wasm