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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of lld/ELF/LTO.cpp