10b57cec5SDimitry Andric //===- LTO.cpp ------------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "LTO.h"
100b57cec5SDimitry Andric #include "Config.h"
110b57cec5SDimitry Andric #include "InputFiles.h"
120b57cec5SDimitry Andric #include "SymbolTable.h"
130b57cec5SDimitry Andric #include "Symbols.h"
140b57cec5SDimitry Andric #include "lld/Common/Args.h"
157a6dacacSDimitry Andric #include "lld/Common/CommonLinkerContext.h"
160b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h"
175f757f3fSDimitry Andric #include "lld/Common/Filesystem.h"
1881ad6265SDimitry Andric #include "lld/Common/Strings.h"
190b57cec5SDimitry Andric #include "lld/Common/TargetOptionsCommandFlags.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
220b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
230b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
240b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h"
250b57cec5SDimitry Andric #include "llvm/LTO/Config.h"
260b57cec5SDimitry Andric #include "llvm/LTO/LTO.h"
27349cc55cSDimitry Andric #include "llvm/Support/Caching.h"
280b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
290b57cec5SDimitry Andric #include "llvm/Support/Error.h"
300b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
310b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
327a6dacacSDimitry Andric #include "llvm/Support/Path.h"
330b57cec5SDimitry Andric #include <algorithm>
340b57cec5SDimitry Andric #include <cstddef>
350b57cec5SDimitry Andric #include <memory>
360b57cec5SDimitry Andric #include <string>
370b57cec5SDimitry Andric #include <system_error>
380b57cec5SDimitry Andric #include <vector>
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric using namespace llvm;
410b57cec5SDimitry Andric using namespace llvm::object;
420b57cec5SDimitry Andric using namespace llvm::ELF;
435ffd83dbSDimitry Andric using namespace lld;
445ffd83dbSDimitry Andric using namespace lld::elf;
450b57cec5SDimitry Andric
getThinLTOOutputFile(StringRef modulePath)460b57cec5SDimitry Andric static std::string getThinLTOOutputFile(StringRef modulePath) {
4706c3fb27SDimitry Andric return lto::getThinLTOOutputFile(modulePath, config->thinLTOPrefixReplaceOld,
4806c3fb27SDimitry Andric config->thinLTOPrefixReplaceNew);
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric
createConfig()510b57cec5SDimitry Andric static lto::Config createConfig() {
520b57cec5SDimitry Andric lto::Config c;
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric // LLD supports the new relocations and address-significance tables.
550b57cec5SDimitry Andric c.Options = initTargetOptionsFromCodeGenFlags();
560b57cec5SDimitry Andric c.Options.EmitAddrsig = true;
57bdd1243dSDimitry Andric for (StringRef C : config->mllvmOpts)
58bdd1243dSDimitry Andric c.MllvmArgs.emplace_back(C.str());
590b57cec5SDimitry Andric
600b57cec5SDimitry Andric // Always emit a section per function/datum with LTO.
610b57cec5SDimitry Andric c.Options.FunctionSections = true;
620b57cec5SDimitry Andric c.Options.DataSections = true;
630b57cec5SDimitry Andric
64*0fca6ea1SDimitry Andric c.Options.BBAddrMap = config->ltoBBAddrMap;
65*0fca6ea1SDimitry Andric
665ffd83dbSDimitry Andric // Check if basic block sections must be used.
67e8d8bef9SDimitry Andric // Allowed values for --lto-basic-block-sections are "all", "labels",
685ffd83dbSDimitry Andric // "<file name specifying basic block ids>", or none. This is the equivalent
695ffd83dbSDimitry Andric // of -fbasic-block-sections= flag in clang.
705ffd83dbSDimitry Andric if (!config->ltoBasicBlockSections.empty()) {
715ffd83dbSDimitry Andric if (config->ltoBasicBlockSections == "all") {
725ffd83dbSDimitry Andric c.Options.BBSections = BasicBlockSection::All;
735ffd83dbSDimitry Andric } else if (config->ltoBasicBlockSections == "labels") {
745ffd83dbSDimitry Andric c.Options.BBSections = BasicBlockSection::Labels;
755ffd83dbSDimitry Andric } else if (config->ltoBasicBlockSections == "none") {
765ffd83dbSDimitry Andric c.Options.BBSections = BasicBlockSection::None;
775ffd83dbSDimitry Andric } else {
785ffd83dbSDimitry Andric ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
795ffd83dbSDimitry Andric MemoryBuffer::getFile(config->ltoBasicBlockSections.str());
805ffd83dbSDimitry Andric if (!MBOrErr) {
815ffd83dbSDimitry Andric error("cannot open " + config->ltoBasicBlockSections + ":" +
825ffd83dbSDimitry Andric MBOrErr.getError().message());
835ffd83dbSDimitry Andric } else {
845ffd83dbSDimitry Andric c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
855ffd83dbSDimitry Andric }
865ffd83dbSDimitry Andric c.Options.BBSections = BasicBlockSection::List;
875ffd83dbSDimitry Andric }
885ffd83dbSDimitry Andric }
895ffd83dbSDimitry Andric
905ffd83dbSDimitry Andric c.Options.UniqueBasicBlockSectionNames =
915ffd83dbSDimitry Andric config->ltoUniqueBasicBlockSectionNames;
925ffd83dbSDimitry Andric
9385868e8aSDimitry Andric if (auto relocModel = getRelocModelFromCMModel())
9485868e8aSDimitry Andric c.RelocModel = *relocModel;
9585868e8aSDimitry Andric else if (config->relocatable)
96bdd1243dSDimitry Andric c.RelocModel = std::nullopt;
970b57cec5SDimitry Andric else if (config->isPic)
980b57cec5SDimitry Andric c.RelocModel = Reloc::PIC_;
990b57cec5SDimitry Andric else
1000b57cec5SDimitry Andric c.RelocModel = Reloc::Static;
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric c.CodeModel = getCodeModelFromCMModel();
1030b57cec5SDimitry Andric c.DisableVerify = config->disableVerify;
1040b57cec5SDimitry Andric c.DiagHandler = diagnosticHandler;
1050b57cec5SDimitry Andric c.OptLevel = config->ltoo;
1060b57cec5SDimitry Andric c.CPU = getCPUStr();
1070b57cec5SDimitry Andric c.MAttrs = getMAttrs();
10806c3fb27SDimitry Andric c.CGOptLevel = config->ltoCgo;
1090b57cec5SDimitry Andric
110480093f4SDimitry Andric c.PTO.LoopVectorization = c.OptLevel > 1;
111480093f4SDimitry Andric c.PTO.SLPVectorization = c.OptLevel > 1;
112480093f4SDimitry Andric
1130b57cec5SDimitry Andric // Set up a custom pipeline if we've been asked to.
1145ffd83dbSDimitry Andric c.OptPipeline = std::string(config->ltoNewPmPasses);
1155ffd83dbSDimitry Andric c.AAPipeline = std::string(config->ltoAAPipeline);
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric // Set up optimization remarks if we've been asked to.
1185ffd83dbSDimitry Andric c.RemarksFilename = std::string(config->optRemarksFilename);
1195ffd83dbSDimitry Andric c.RemarksPasses = std::string(config->optRemarksPasses);
1200b57cec5SDimitry Andric c.RemarksWithHotness = config->optRemarksWithHotness;
121e8d8bef9SDimitry Andric c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
1225ffd83dbSDimitry Andric c.RemarksFormat = std::string(config->optRemarksFormat);
1230b57cec5SDimitry Andric
12481ad6265SDimitry Andric // Set up output file to emit statistics.
12581ad6265SDimitry Andric c.StatsFile = std::string(config->optStatsFilename);
12681ad6265SDimitry Andric
1275ffd83dbSDimitry Andric c.SampleProfile = std::string(config->ltoSampleProfile);
12881ad6265SDimitry Andric for (StringRef pluginFn : config->passPlugins)
12981ad6265SDimitry Andric c.PassPlugins.push_back(std::string(pluginFn));
1300b57cec5SDimitry Andric c.DebugPassManager = config->ltoDebugPassManager;
1315ffd83dbSDimitry Andric c.DwoDir = std::string(config->dwoDir);
1320b57cec5SDimitry Andric
1335ffd83dbSDimitry Andric c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility;
1345f757f3fSDimitry Andric c.ValidateAllVtablesHaveTypeInfos =
1355f757f3fSDimitry Andric config->ltoValidateAllVtablesHaveTypeInfos;
1365f757f3fSDimitry Andric c.AllVtablesHaveTypeInfos = ctx.ltoAllVtablesHaveTypeInfos;
1375ffd83dbSDimitry Andric c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
1385ffd83dbSDimitry Andric
1395ffd83dbSDimitry Andric for (const llvm::StringRef &name : config->thinLTOModulesToCompile)
1405ffd83dbSDimitry Andric c.ThinLTOModulesToCompile.emplace_back(name);
1415ffd83dbSDimitry Andric
1425ffd83dbSDimitry Andric c.TimeTraceEnabled = config->timeTraceEnabled;
1435ffd83dbSDimitry Andric c.TimeTraceGranularity = config->timeTraceGranularity;
1445ffd83dbSDimitry Andric
1455ffd83dbSDimitry Andric c.CSIRProfile = std::string(config->ltoCSProfileFile);
1460b57cec5SDimitry Andric c.RunCSIRInstr = config->ltoCSProfileGenerate;
147349cc55cSDimitry Andric c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric if (config->emitLLVM) {
150*0fca6ea1SDimitry Andric c.PreCodeGenModuleHook = [](size_t task, const Module &m) {
151e8d8bef9SDimitry Andric if (std::unique_ptr<raw_fd_ostream> os =
152e8d8bef9SDimitry Andric openLTOOutputFile(config->outputFile))
1530b57cec5SDimitry Andric WriteBitcodeToFile(m, *os, false);
1540b57cec5SDimitry Andric return false;
1550b57cec5SDimitry Andric };
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric
158bdd1243dSDimitry Andric if (config->ltoEmitAsm) {
1595f757f3fSDimitry Andric c.CGFileType = CodeGenFileType::AssemblyFile;
160bdd1243dSDimitry Andric c.Options.MCOptions.AsmVerbose = true;
161bdd1243dSDimitry Andric }
1625ffd83dbSDimitry Andric
163753f127fSDimitry Andric if (!config->saveTempsArgs.empty())
1640b57cec5SDimitry Andric checkError(c.addSaveTemps(config->outputFile.str() + ".",
165753f127fSDimitry Andric /*UseInputModulePath*/ true,
166753f127fSDimitry Andric config->saveTempsArgs));
1670b57cec5SDimitry Andric return c;
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric
BitcodeCompiler()1700b57cec5SDimitry Andric BitcodeCompiler::BitcodeCompiler() {
1710b57cec5SDimitry Andric // Initialize indexFile.
1720b57cec5SDimitry Andric if (!config->thinLTOIndexOnlyArg.empty())
1730b57cec5SDimitry Andric indexFile = openFile(config->thinLTOIndexOnlyArg);
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric // Initialize ltoObj.
1760b57cec5SDimitry Andric lto::ThinBackend backend;
1770b57cec5SDimitry Andric auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
17881ad6265SDimitry Andric if (config->thinLTOIndexOnly) {
1790b57cec5SDimitry Andric backend = lto::createWriteIndexesThinBackend(
18006c3fb27SDimitry Andric std::string(config->thinLTOPrefixReplaceOld),
18106c3fb27SDimitry Andric std::string(config->thinLTOPrefixReplaceNew),
18206c3fb27SDimitry Andric std::string(config->thinLTOPrefixReplaceNativeObject),
1830b57cec5SDimitry Andric config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
1845ffd83dbSDimitry Andric } else {
1855ffd83dbSDimitry Andric backend = lto::createInProcessThinBackend(
18681ad6265SDimitry Andric llvm::heavyweight_hardware_concurrency(config->thinLTOJobs),
18781ad6265SDimitry Andric onIndexWrite, config->thinLTOEmitIndexFiles,
18881ad6265SDimitry Andric config->thinLTOEmitImportsFiles);
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric
19106c3fb27SDimitry Andric constexpr llvm::lto::LTO::LTOKind ltoModes[3] =
19206c3fb27SDimitry Andric {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
19306c3fb27SDimitry Andric llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
19406c3fb27SDimitry Andric llvm::lto::LTO::LTOKind::LTOK_Default};
19506c3fb27SDimitry Andric ltoObj = std::make_unique<lto::LTO>(
19606c3fb27SDimitry Andric createConfig(), backend, config->ltoPartitions,
19706c3fb27SDimitry Andric ltoModes[config->ltoKind]);
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andric // Initialize usedStartStop.
200bdd1243dSDimitry Andric if (ctx.bitcodeFiles.empty())
2010eae32dcSDimitry Andric return;
202bdd1243dSDimitry Andric for (Symbol *sym : symtab.getSymbols()) {
20304eeddc0SDimitry Andric if (sym->isPlaceholder())
20404eeddc0SDimitry Andric continue;
2050b57cec5SDimitry Andric StringRef s = sym->getName();
2060b57cec5SDimitry Andric for (StringRef prefix : {"__start_", "__stop_"})
20706c3fb27SDimitry Andric if (s.starts_with(prefix))
2080b57cec5SDimitry Andric usedStartStop.insert(s.substr(prefix.size()));
209480093f4SDimitry Andric }
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric BitcodeCompiler::~BitcodeCompiler() = default;
2130b57cec5SDimitry Andric
add(BitcodeFile & f)2140b57cec5SDimitry Andric void BitcodeCompiler::add(BitcodeFile &f) {
2150b57cec5SDimitry Andric lto::InputFile &obj = *f.obj;
2160b57cec5SDimitry Andric bool isExec = !config->shared && !config->relocatable;
2170b57cec5SDimitry Andric
21881ad6265SDimitry Andric if (config->thinLTOEmitIndexFiles)
2190b57cec5SDimitry Andric thinIndices.insert(obj.getName());
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric ArrayRef<Symbol *> syms = f.getSymbols();
2220b57cec5SDimitry Andric ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
2230b57cec5SDimitry Andric std::vector<lto::SymbolResolution> resols(syms.size());
2240b57cec5SDimitry Andric
2250b57cec5SDimitry Andric // Provide a resolution to the LTO API for each symbol.
2260b57cec5SDimitry Andric for (size_t i = 0, e = syms.size(); i != e; ++i) {
2270b57cec5SDimitry Andric Symbol *sym = syms[i];
2280b57cec5SDimitry Andric const lto::InputFile::Symbol &objSym = objSyms[i];
2290b57cec5SDimitry Andric lto::SymbolResolution &r = resols[i];
2300b57cec5SDimitry Andric
2310b57cec5SDimitry Andric // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
2320b57cec5SDimitry Andric // reports two symbols for module ASM defined. Without this check, lld
2330b57cec5SDimitry Andric // flags an undefined in IR with a definition in ASM as prevailing.
2340b57cec5SDimitry Andric // Once IRObjectFile is fixed to report only one symbol this hack can
2350b57cec5SDimitry Andric // be removed.
2360b57cec5SDimitry Andric r.Prevailing = !objSym.isUndefined() && sym->file == &f;
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric // We ask LTO to preserve following global symbols:
2390b57cec5SDimitry Andric // 1) All symbols when doing relocatable link, so that them can be used
2400b57cec5SDimitry Andric // for doing final link.
2410b57cec5SDimitry Andric // 2) Symbols that are used in regular objects.
2420b57cec5SDimitry Andric // 3) C named sections if we have corresponding __start_/__stop_ symbol.
24381ad6265SDimitry Andric // 4) Symbols that are defined in bitcode files and used for dynamic
24481ad6265SDimitry Andric // linking.
24581ad6265SDimitry Andric // 5) Symbols that will be referenced after linker wrapping is performed.
2460b57cec5SDimitry Andric r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
24781ad6265SDimitry Andric sym->referencedAfterWrap ||
2480b57cec5SDimitry Andric (r.Prevailing && sym->includeInDynsym()) ||
2490b57cec5SDimitry Andric usedStartStop.count(objSym.getSectionName());
250fe6060f1SDimitry Andric // Identify symbols exported dynamically, and that therefore could be
251fe6060f1SDimitry Andric // referenced by a shared library not visible to the linker.
25281ad6265SDimitry Andric r.ExportDynamic =
25381ad6265SDimitry Andric sym->computeBinding() != STB_LOCAL &&
25481ad6265SDimitry Andric (config->exportDynamic || sym->exportDynamic || sym->inDynamicList);
2550b57cec5SDimitry Andric const auto *dr = dyn_cast<Defined>(sym);
2560b57cec5SDimitry Andric r.FinalDefinitionInLinkageUnit =
257bdd1243dSDimitry Andric (isExec || sym->visibility() != STV_DEFAULT) && dr &&
2580b57cec5SDimitry Andric // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
2590b57cec5SDimitry Andric // will be generated by for them, triggering linker errors.
2600b57cec5SDimitry Andric // Symbol section is always null for bitcode symbols, hence the check
2610b57cec5SDimitry Andric // for isElf(). Skip linker script defined symbols as well: they have
2620b57cec5SDimitry Andric // no File defined.
2637a6dacacSDimitry Andric !(dr->section == nullptr &&
2647a6dacacSDimitry Andric (sym->file->isInternal() || sym->file->isElf()));
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric if (r.Prevailing)
2677a6dacacSDimitry Andric Undefined(ctx.internalFile, StringRef(), STB_GLOBAL, STV_DEFAULT,
2687a6dacacSDimitry Andric sym->type)
269bdd1243dSDimitry Andric .overwrite(*sym);
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric // We tell LTO to not apply interprocedural optimization for wrapped
2720b57cec5SDimitry Andric // (with --wrap) symbols because otherwise LTO would inline them while
2730b57cec5SDimitry Andric // their values are still not final.
27481ad6265SDimitry Andric r.LinkerRedefined = sym->scriptDefined;
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric checkError(ltoObj->add(std::move(f.obj), resols));
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric // If LazyObjFile has not been added to link, emit empty index files.
2800b57cec5SDimitry Andric // This is needed because this is what GNU gold plugin does and we have a
2810b57cec5SDimitry Andric // distributed build system that depends on that behavior.
thinLTOCreateEmptyIndexFiles()2820b57cec5SDimitry Andric static void thinLTOCreateEmptyIndexFiles() {
283bdd1243dSDimitry Andric DenseSet<StringRef> linkedBitCodeFiles;
284bdd1243dSDimitry Andric for (BitcodeFile *f : ctx.bitcodeFiles)
285bdd1243dSDimitry Andric linkedBitCodeFiles.insert(f->getName());
286bdd1243dSDimitry Andric
287bdd1243dSDimitry Andric for (BitcodeFile *f : ctx.lazyBitcodeFiles) {
2880eae32dcSDimitry Andric if (!f->lazy)
2890b57cec5SDimitry Andric continue;
290bdd1243dSDimitry Andric if (linkedBitCodeFiles.contains(f->getName()))
291bdd1243dSDimitry Andric continue;
292bdd1243dSDimitry Andric std::string path =
293bdd1243dSDimitry Andric replaceThinLTOSuffix(getThinLTOOutputFile(f->obj->getName()));
2940b57cec5SDimitry Andric std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");
2950b57cec5SDimitry Andric if (!os)
2960b57cec5SDimitry Andric continue;
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric ModuleSummaryIndex m(/*HaveGVs*/ false);
2990b57cec5SDimitry Andric m.setSkipModuleByDistributedBackend();
3001fd87a68SDimitry Andric writeIndexToFile(m, *os);
3010b57cec5SDimitry Andric if (config->thinLTOEmitImportsFiles)
3020b57cec5SDimitry Andric openFile(path + ".imports");
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric
3060b57cec5SDimitry Andric // Merge all the bitcode files we have seen, codegen the result
3070b57cec5SDimitry Andric // and return the resulting ObjectFile(s).
compile()3080b57cec5SDimitry Andric std::vector<InputFile *> BitcodeCompiler::compile() {
3090b57cec5SDimitry Andric unsigned maxTasks = ltoObj->getMaxTasks();
3100b57cec5SDimitry Andric buf.resize(maxTasks);
3110b57cec5SDimitry Andric files.resize(maxTasks);
3127a6dacacSDimitry Andric filenames.resize(maxTasks);
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andric // The --thinlto-cache-dir option specifies the path to a directory in which
3150b57cec5SDimitry Andric // to cache native object files for ThinLTO incremental builds. If a path was
3160b57cec5SDimitry Andric // specified, configure LTO to use it as the cache directory.
317349cc55cSDimitry Andric FileCache cache;
3180b57cec5SDimitry Andric if (!config->thinLTOCacheDir.empty())
319bdd1243dSDimitry Andric cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
320bdd1243dSDimitry Andric [&](size_t task, const Twine &moduleName,
321bdd1243dSDimitry Andric std::unique_ptr<MemoryBuffer> mb) {
3220b57cec5SDimitry Andric files[task] = std::move(mb);
3237a6dacacSDimitry Andric filenames[task] = moduleName.str();
3240b57cec5SDimitry Andric }));
3250b57cec5SDimitry Andric
326bdd1243dSDimitry Andric if (!ctx.bitcodeFiles.empty())
3270b57cec5SDimitry Andric checkError(ltoObj->run(
328bdd1243dSDimitry Andric [&](size_t task, const Twine &moduleName) {
3297a6dacacSDimitry Andric buf[task].first = moduleName.str();
330349cc55cSDimitry Andric return std::make_unique<CachedFileStream>(
3317a6dacacSDimitry Andric std::make_unique<raw_svector_ostream>(buf[task].second));
3320b57cec5SDimitry Andric },
3330b57cec5SDimitry Andric cache));
3340b57cec5SDimitry Andric
3355ffd83dbSDimitry Andric // Emit empty index files for non-indexed files but not in single-module mode.
3365ffd83dbSDimitry Andric if (config->thinLTOModulesToCompile.empty()) {
3370b57cec5SDimitry Andric for (StringRef s : thinIndices) {
3380b57cec5SDimitry Andric std::string path = getThinLTOOutputFile(s);
3390b57cec5SDimitry Andric openFile(path + ".thinlto.bc");
3400b57cec5SDimitry Andric if (config->thinLTOEmitImportsFiles)
3410b57cec5SDimitry Andric openFile(path + ".imports");
3420b57cec5SDimitry Andric }
3435ffd83dbSDimitry Andric }
3440b57cec5SDimitry Andric
34581ad6265SDimitry Andric if (config->thinLTOEmitIndexFiles)
3460b57cec5SDimitry Andric thinLTOCreateEmptyIndexFiles();
3470b57cec5SDimitry Andric
34881ad6265SDimitry Andric if (config->thinLTOIndexOnly) {
3490b57cec5SDimitry Andric if (!config->ltoObjPath.empty())
3507a6dacacSDimitry Andric saveBuffer(buf[0].second, config->ltoObjPath);
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric // ThinLTO with index only option is required to generate only the index
3530b57cec5SDimitry Andric // files. After that, we exit from linker and ThinLTO backend runs in a
3540b57cec5SDimitry Andric // distributed environment.
3550b57cec5SDimitry Andric if (indexFile)
3560b57cec5SDimitry Andric indexFile->close();
3570b57cec5SDimitry Andric return {};
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric if (!config->thinLTOCacheDir.empty())
361bdd1243dSDimitry Andric pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy, files);
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andric if (!config->ltoObjPath.empty()) {
3647a6dacacSDimitry Andric saveBuffer(buf[0].second, config->ltoObjPath);
3650b57cec5SDimitry Andric for (unsigned i = 1; i != maxTasks; ++i)
3667a6dacacSDimitry Andric saveBuffer(buf[i].second, config->ltoObjPath + Twine(i));
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3697a6dacacSDimitry Andric bool savePrelink = config->saveTempsArgs.contains("prelink");
3700b57cec5SDimitry Andric std::vector<InputFile *> ret;
3717a6dacacSDimitry Andric const char *ext = config->ltoEmitAsm ? ".s" : ".o";
3727a6dacacSDimitry Andric for (unsigned i = 0; i != maxTasks; ++i) {
3737a6dacacSDimitry Andric StringRef bitcodeFilePath;
3747a6dacacSDimitry Andric StringRef objBuf;
3757a6dacacSDimitry Andric if (files[i]) {
3767a6dacacSDimitry Andric // When files[i] is not null, we get the native relocatable file from the
3777a6dacacSDimitry Andric // cache. filenames[i] contains the original BitcodeFile's identifier.
3787a6dacacSDimitry Andric objBuf = files[i]->getBuffer();
3797a6dacacSDimitry Andric bitcodeFilePath = filenames[i];
3807a6dacacSDimitry Andric } else {
3817a6dacacSDimitry Andric // Get the native relocatable file after in-process LTO compilation.
3827a6dacacSDimitry Andric objBuf = buf[i].second;
3837a6dacacSDimitry Andric bitcodeFilePath = buf[i].first;
3847a6dacacSDimitry Andric }
3857a6dacacSDimitry Andric if (objBuf.empty())
3867a6dacacSDimitry Andric continue;
3870b57cec5SDimitry Andric
3887a6dacacSDimitry Andric // If the input bitcode file is path/to/x.o and -o specifies a.out, the
3897a6dacacSDimitry Andric // corresponding native relocatable file path will look like:
3907a6dacacSDimitry Andric // path/to/a.out.lto.x.o.
3917a6dacacSDimitry Andric StringRef ltoObjName;
3927a6dacacSDimitry Andric if (bitcodeFilePath == "ld-temp.o") {
3937a6dacacSDimitry Andric ltoObjName =
3947a6dacacSDimitry Andric saver().save(Twine(config->outputFile) + ".lto" +
3957a6dacacSDimitry Andric (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ext);
3967a6dacacSDimitry Andric } else {
3977a6dacacSDimitry Andric StringRef directory = sys::path::parent_path(bitcodeFilePath);
3987a6dacacSDimitry Andric // For an archive member, which has an identifier like "d/a.a(coll.o at
3997a6dacacSDimitry Andric // 8)" (see BitcodeFile::BitcodeFile), use the filename; otherwise, use
4007a6dacacSDimitry Andric // the stem (d/a.o => a).
4017a6dacacSDimitry Andric StringRef baseName = bitcodeFilePath.ends_with(")")
4027a6dacacSDimitry Andric ? sys::path::filename(bitcodeFilePath)
4037a6dacacSDimitry Andric : sys::path::stem(bitcodeFilePath);
4047a6dacacSDimitry Andric StringRef outputFileBaseName = sys::path::filename(config->outputFile);
4057a6dacacSDimitry Andric SmallString<256> path;
4067a6dacacSDimitry Andric sys::path::append(path, directory,
4077a6dacacSDimitry Andric outputFileBaseName + ".lto." + baseName + ext);
4087a6dacacSDimitry Andric sys::path::remove_dots(path, true);
4097a6dacacSDimitry Andric ltoObjName = saver().save(path.str());
4107a6dacacSDimitry Andric }
4117a6dacacSDimitry Andric if (savePrelink || config->ltoEmitAsm)
4127a6dacacSDimitry Andric saveBuffer(buf[i].second, ltoObjName);
4137a6dacacSDimitry Andric if (!config->ltoEmitAsm)
4147a6dacacSDimitry Andric ret.push_back(createObjFile(MemoryBufferRef(objBuf, ltoObjName)));
4157a6dacacSDimitry Andric }
4160b57cec5SDimitry Andric return ret;
4170b57cec5SDimitry Andric }
418