1//===- LTO.cpp ------------------------------------------------------------===//
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#include "LTO.h"
10#include "Config.h"
11#include "InputFiles.h"
12#include "SymbolTable.h"
13#include "Symbols.h"
14#include "lld/Common/Args.h"
15#include "lld/Common/CommonLinkerContext.h"
16#include "lld/Common/ErrorHandler.h"
17#include "lld/Common/Filesystem.h"
18#include "lld/Common/Strings.h"
19#include "lld/Common/TargetOptionsCommandFlags.h"
20#include "llvm/ADT/SmallString.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/BinaryFormat/ELF.h"
24#include "llvm/Bitcode/BitcodeWriter.h"
25#include "llvm/LTO/Config.h"
26#include "llvm/LTO/LTO.h"
27#include "llvm/Support/Caching.h"
28#include "llvm/Support/CodeGen.h"
29#include "llvm/Support/Error.h"
30#include "llvm/Support/FileSystem.h"
31#include "llvm/Support/MemoryBuffer.h"
32#include "llvm/Support/Path.h"
33#include <algorithm>
34#include <cstddef>
35#include <memory>
36#include <string>
37#include <system_error>
38#include <vector>
39
40using namespace llvm;
41using namespace llvm::object;
42using namespace llvm::ELF;
43using namespace lld;
44using namespace lld::elf;
45
46static std::string getThinLTOOutputFile(StringRef modulePath) {
47 return lto::getThinLTOOutputFile(Path: modulePath, OldPrefix: config->thinLTOPrefixReplaceOld,
48 NewPrefix: config->thinLTOPrefixReplaceNew);
49}
50
51static lto::Config createConfig() {
52 lto::Config c;
53
54 // LLD supports the new relocations and address-significance tables.
55 c.Options = initTargetOptionsFromCodeGenFlags();
56 c.Options.EmitAddrsig = true;
57 for (StringRef C : config->mllvmOpts)
58 c.MllvmArgs.emplace_back(args: C.str());
59
60 // Always emit a section per function/datum with LTO.
61 c.Options.FunctionSections = true;
62 c.Options.DataSections = true;
63
64 c.Options.BBAddrMap = config->ltoBBAddrMap;
65
66 // Check if basic block sections must be used.
67 // Allowed values for --lto-basic-block-sections are "all", "labels",
68 // "<file name specifying basic block ids>", or none. This is the equivalent
69 // of -fbasic-block-sections= flag in clang.
70 if (!config->ltoBasicBlockSections.empty()) {
71 if (config->ltoBasicBlockSections == "all") {
72 c.Options.BBSections = BasicBlockSection::All;
73 } else if (config->ltoBasicBlockSections == "labels") {
74 c.Options.BBSections = BasicBlockSection::Labels;
75 } else if (config->ltoBasicBlockSections == "none") {
76 c.Options.BBSections = BasicBlockSection::None;
77 } else {
78 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
79 MemoryBuffer::getFile(Filename: config->ltoBasicBlockSections.str());
80 if (!MBOrErr) {
81 error(msg: "cannot open " + config->ltoBasicBlockSections + ":" +
82 MBOrErr.getError().message());
83 } else {
84 c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
85 }
86 c.Options.BBSections = BasicBlockSection::List;
87 }
88 }
89
90 c.Options.UniqueBasicBlockSectionNames =
91 config->ltoUniqueBasicBlockSectionNames;
92
93 if (auto relocModel = getRelocModelFromCMModel())
94 c.RelocModel = *relocModel;
95 else if (config->relocatable)
96 c.RelocModel = std::nullopt;
97 else if (config->isPic)
98 c.RelocModel = Reloc::PIC_;
99 else
100 c.RelocModel = Reloc::Static;
101
102 c.CodeModel = getCodeModelFromCMModel();
103 c.DisableVerify = config->disableVerify;
104 c.DiagHandler = diagnosticHandler;
105 c.OptLevel = config->ltoo;
106 c.CPU = getCPUStr();
107 c.MAttrs = getMAttrs();
108 c.CGOptLevel = config->ltoCgo;
109
110 c.PTO.LoopVectorization = c.OptLevel > 1;
111 c.PTO.SLPVectorization = c.OptLevel > 1;
112
113 // Set up a custom pipeline if we've been asked to.
114 c.OptPipeline = std::string(config->ltoNewPmPasses);
115 c.AAPipeline = std::string(config->ltoAAPipeline);
116
117 // Set up optimization remarks if we've been asked to.
118 c.RemarksFilename = std::string(config->optRemarksFilename);
119 c.RemarksPasses = std::string(config->optRemarksPasses);
120 c.RemarksWithHotness = config->optRemarksWithHotness;
121 c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
122 c.RemarksFormat = std::string(config->optRemarksFormat);
123
124 // Set up output file to emit statistics.
125 c.StatsFile = std::string(config->optStatsFilename);
126
127 c.SampleProfile = std::string(config->ltoSampleProfile);
128 for (StringRef pluginFn : config->passPlugins)
129 c.PassPlugins.push_back(x: std::string(pluginFn));
130 c.DebugPassManager = config->ltoDebugPassManager;
131 c.DwoDir = std::string(config->dwoDir);
132
133 c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility;
134 c.ValidateAllVtablesHaveTypeInfos =
135 config->ltoValidateAllVtablesHaveTypeInfos;
136 c.AllVtablesHaveTypeInfos = ctx.ltoAllVtablesHaveTypeInfos;
137 c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
138
139 for (const llvm::StringRef &name : config->thinLTOModulesToCompile)
140 c.ThinLTOModulesToCompile.emplace_back(args: name);
141
142 c.TimeTraceEnabled = config->timeTraceEnabled;
143 c.TimeTraceGranularity = config->timeTraceGranularity;
144
145 c.CSIRProfile = std::string(config->ltoCSProfileFile);
146 c.RunCSIRInstr = config->ltoCSProfileGenerate;
147 c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
148
149 if (config->emitLLVM) {
150 c.PreCodeGenModuleHook = [](size_t task, const Module &m) {
151 if (std::unique_ptr<raw_fd_ostream> os =
152 openLTOOutputFile(file: config->outputFile))
153 WriteBitcodeToFile(M: m, Out&: *os, ShouldPreserveUseListOrder: false);
154 return false;
155 };
156 }
157
158 if (config->ltoEmitAsm) {
159 c.CGFileType = CodeGenFileType::AssemblyFile;
160 c.Options.MCOptions.AsmVerbose = true;
161 }
162
163 if (!config->saveTempsArgs.empty())
164 checkError(e: c.addSaveTemps(OutputFileName: config->outputFile.str() + ".",
165 /*UseInputModulePath*/ true,
166 SaveTempsArgs: config->saveTempsArgs));
167 return c;
168}
169
170BitcodeCompiler::BitcodeCompiler() {
171 // Initialize indexFile.
172 if (!config->thinLTOIndexOnlyArg.empty())
173 indexFile = openFile(file: config->thinLTOIndexOnlyArg);
174
175 // Initialize ltoObj.
176 lto::ThinBackend backend;
177 auto onIndexWrite = [&](StringRef s) { thinIndices.erase(V: s); };
178 if (config->thinLTOIndexOnly) {
179 backend = lto::createWriteIndexesThinBackend(
180 OldPrefix: std::string(config->thinLTOPrefixReplaceOld),
181 NewPrefix: std::string(config->thinLTOPrefixReplaceNew),
182 NativeObjectPrefix: std::string(config->thinLTOPrefixReplaceNativeObject),
183 ShouldEmitImportsFiles: config->thinLTOEmitImportsFiles, LinkedObjectsFile: indexFile.get(), OnWrite: onIndexWrite);
184 } else {
185 backend = lto::createInProcessThinBackend(
186 Parallelism: llvm::heavyweight_hardware_concurrency(Num: config->thinLTOJobs),
187 OnWrite: onIndexWrite, ShouldEmitIndexFiles: config->thinLTOEmitIndexFiles,
188 ShouldEmitImportsFiles: config->thinLTOEmitImportsFiles);
189 }
190
191 constexpr llvm::lto::LTO::LTOKind ltoModes[3] =
192 {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
193 llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
194 llvm::lto::LTO::LTOKind::LTOK_Default};
195 ltoObj = std::make_unique<lto::LTO>(
196 args: createConfig(), args&: backend, args&: config->ltoPartitions,
197 args: ltoModes[config->ltoKind]);
198
199 // Initialize usedStartStop.
200 if (ctx.bitcodeFiles.empty())
201 return;
202 for (Symbol *sym : symtab.getSymbols()) {
203 if (sym->isPlaceholder())
204 continue;
205 StringRef s = sym->getName();
206 for (StringRef prefix : {"__start_", "__stop_"})
207 if (s.starts_with(Prefix: prefix))
208 usedStartStop.insert(V: s.substr(Start: prefix.size()));
209 }
210}
211
212BitcodeCompiler::~BitcodeCompiler() = default;
213
214void BitcodeCompiler::add(BitcodeFile &f) {
215 lto::InputFile &obj = *f.obj;
216 bool isExec = !config->shared && !config->relocatable;
217
218 if (config->thinLTOEmitIndexFiles)
219 thinIndices.insert(V: obj.getName());
220
221 ArrayRef<Symbol *> syms = f.getSymbols();
222 ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
223 std::vector<lto::SymbolResolution> resols(syms.size());
224
225 // Provide a resolution to the LTO API for each symbol.
226 for (size_t i = 0, e = syms.size(); i != e; ++i) {
227 Symbol *sym = syms[i];
228 const lto::InputFile::Symbol &objSym = objSyms[i];
229 lto::SymbolResolution &r = resols[i];
230
231 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
232 // reports two symbols for module ASM defined. Without this check, lld
233 // flags an undefined in IR with a definition in ASM as prevailing.
234 // Once IRObjectFile is fixed to report only one symbol this hack can
235 // be removed.
236 r.Prevailing = !objSym.isUndefined() && sym->file == &f;
237
238 // We ask LTO to preserve following global symbols:
239 // 1) All symbols when doing relocatable link, so that them can be used
240 // for doing final link.
241 // 2) Symbols that are used in regular objects.
242 // 3) C named sections if we have corresponding __start_/__stop_ symbol.
243 // 4) Symbols that are defined in bitcode files and used for dynamic
244 // linking.
245 // 5) Symbols that will be referenced after linker wrapping is performed.
246 r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
247 sym->referencedAfterWrap ||
248 (r.Prevailing && sym->includeInDynsym()) ||
249 usedStartStop.count(V: objSym.getSectionName());
250 // Identify symbols exported dynamically, and that therefore could be
251 // referenced by a shared library not visible to the linker.
252 r.ExportDynamic =
253 sym->computeBinding() != STB_LOCAL &&
254 (config->exportDynamic || sym->exportDynamic || sym->inDynamicList);
255 const auto *dr = dyn_cast<Defined>(Val: sym);
256 r.FinalDefinitionInLinkageUnit =
257 (isExec || sym->visibility() != STV_DEFAULT) && dr &&
258 // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
259 // will be generated by for them, triggering linker errors.
260 // Symbol section is always null for bitcode symbols, hence the check
261 // for isElf(). Skip linker script defined symbols as well: they have
262 // no File defined.
263 !(dr->section == nullptr &&
264 (sym->file->isInternal() || sym->file->isElf()));
265
266 if (r.Prevailing)
267 Undefined(ctx.internalFile, StringRef(), STB_GLOBAL, STV_DEFAULT,
268 sym->type)
269 .overwrite(sym&: *sym);
270
271 // We tell LTO to not apply interprocedural optimization for wrapped
272 // (with --wrap) symbols because otherwise LTO would inline them while
273 // their values are still not final.
274 r.LinkerRedefined = sym->scriptDefined;
275 }
276 checkError(e: ltoObj->add(Obj: std::move(f.obj), Res: resols));
277}
278
279// If LazyObjFile has not been added to link, emit empty index files.
280// This is needed because this is what GNU gold plugin does and we have a
281// distributed build system that depends on that behavior.
282static void thinLTOCreateEmptyIndexFiles() {
283 DenseSet<StringRef> linkedBitCodeFiles;
284 for (BitcodeFile *f : ctx.bitcodeFiles)
285 linkedBitCodeFiles.insert(V: f->getName());
286
287 for (BitcodeFile *f : ctx.lazyBitcodeFiles) {
288 if (!f->lazy)
289 continue;
290 if (linkedBitCodeFiles.contains(V: f->getName()))
291 continue;
292 std::string path =
293 replaceThinLTOSuffix(path: getThinLTOOutputFile(modulePath: f->obj->getName()));
294 std::unique_ptr<raw_fd_ostream> os = openFile(file: path + ".thinlto.bc");
295 if (!os)
296 continue;
297
298 ModuleSummaryIndex m(/*HaveGVs*/ false);
299 m.setSkipModuleByDistributedBackend();
300 writeIndexToFile(Index: m, Out&: *os);
301 if (config->thinLTOEmitImportsFiles)
302 openFile(file: path + ".imports");
303 }
304}
305
306// Merge all the bitcode files we have seen, codegen the result
307// and return the resulting ObjectFile(s).
308std::vector<InputFile *> BitcodeCompiler::compile() {
309 unsigned maxTasks = ltoObj->getMaxTasks();
310 buf.resize(N: maxTasks);
311 files.resize(new_size: maxTasks);
312 filenames.resize(N: maxTasks);
313
314 // The --thinlto-cache-dir option specifies the path to a directory in which
315 // to cache native object files for ThinLTO incremental builds. If a path was
316 // specified, configure LTO to use it as the cache directory.
317 FileCache cache;
318 if (!config->thinLTOCacheDir.empty())
319 cache = check(e: localCache(CacheNameRef: "ThinLTO", TempFilePrefixRef: "Thin", CacheDirectoryPathRef: config->thinLTOCacheDir,
320 AddBuffer: [&](size_t task, const Twine &moduleName,
321 std::unique_ptr<MemoryBuffer> mb) {
322 files[task] = std::move(mb);
323 filenames[task] = moduleName.str();
324 }));
325
326 if (!ctx.bitcodeFiles.empty())
327 checkError(e: ltoObj->run(
328 AddStream: [&](size_t task, const Twine &moduleName) {
329 buf[task].first = moduleName.str();
330 return std::make_unique<CachedFileStream>(
331 args: std::make_unique<raw_svector_ostream>(args&: buf[task].second));
332 },
333 Cache: cache));
334
335 // Emit empty index files for non-indexed files but not in single-module mode.
336 if (config->thinLTOModulesToCompile.empty()) {
337 for (StringRef s : thinIndices) {
338 std::string path = getThinLTOOutputFile(modulePath: s);
339 openFile(file: path + ".thinlto.bc");
340 if (config->thinLTOEmitImportsFiles)
341 openFile(file: path + ".imports");
342 }
343 }
344
345 if (config->thinLTOEmitIndexFiles)
346 thinLTOCreateEmptyIndexFiles();
347
348 if (config->thinLTOIndexOnly) {
349 if (!config->ltoObjPath.empty())
350 saveBuffer(buffer: buf[0].second, path: config->ltoObjPath);
351
352 // ThinLTO with index only option is required to generate only the index
353 // files. After that, we exit from linker and ThinLTO backend runs in a
354 // distributed environment.
355 if (indexFile)
356 indexFile->close();
357 return {};
358 }
359
360 if (!config->thinLTOCacheDir.empty())
361 pruneCache(Path: config->thinLTOCacheDir, Policy: config->thinLTOCachePolicy, Files: files);
362
363 if (!config->ltoObjPath.empty()) {
364 saveBuffer(buffer: buf[0].second, path: config->ltoObjPath);
365 for (unsigned i = 1; i != maxTasks; ++i)
366 saveBuffer(buffer: buf[i].second, path: config->ltoObjPath + Twine(i));
367 }
368
369 bool savePrelink = config->saveTempsArgs.contains(V: "prelink");
370 std::vector<InputFile *> ret;
371 const char *ext = config->ltoEmitAsm ? ".s" : ".o";
372 for (unsigned i = 0; i != maxTasks; ++i) {
373 StringRef bitcodeFilePath;
374 StringRef objBuf;
375 if (files[i]) {
376 // When files[i] is not null, we get the native relocatable file from the
377 // cache. filenames[i] contains the original BitcodeFile's identifier.
378 objBuf = files[i]->getBuffer();
379 bitcodeFilePath = filenames[i];
380 } else {
381 // Get the native relocatable file after in-process LTO compilation.
382 objBuf = buf[i].second;
383 bitcodeFilePath = buf[i].first;
384 }
385 if (objBuf.empty())
386 continue;
387
388 // If the input bitcode file is path/to/x.o and -o specifies a.out, the
389 // corresponding native relocatable file path will look like:
390 // path/to/a.out.lto.x.o.
391 StringRef ltoObjName;
392 if (bitcodeFilePath == "ld-temp.o") {
393 ltoObjName =
394 saver().save(S: Twine(config->outputFile) + ".lto" +
395 (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ext);
396 } else {
397 StringRef directory = sys::path::parent_path(path: bitcodeFilePath);
398 // For an archive member, which has an identifier like "d/a.a(coll.o at
399 // 8)" (see BitcodeFile::BitcodeFile), use the filename; otherwise, use
400 // the stem (d/a.o => a).
401 StringRef baseName = bitcodeFilePath.ends_with(Suffix: ")")
402 ? sys::path::filename(path: bitcodeFilePath)
403 : sys::path::stem(path: bitcodeFilePath);
404 StringRef outputFileBaseName = sys::path::filename(path: config->outputFile);
405 SmallString<256> path;
406 sys::path::append(path, a: directory,
407 b: outputFileBaseName + ".lto." + baseName + ext);
408 sys::path::remove_dots(path, remove_dot_dot: true);
409 ltoObjName = saver().save(S: path.str());
410 }
411 if (savePrelink || config->ltoEmitAsm)
412 saveBuffer(buffer: buf[i].second, path: ltoObjName);
413 if (!config->ltoEmitAsm)
414 ret.push_back(x: createObjFile(mb: MemoryBufferRef(objBuf, ltoObjName)));
415 }
416 return ret;
417}
418