425 lines · cpp
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-exception6//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(modulePath, ctx.arg.thinLTOPrefixReplaceOld,42 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(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 equivalent61 // 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(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 else97 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(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(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(ctx.arg.outputFile))151 WriteBitcodeToFile(m, *os, 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(ctx.e, c.addSaveTemps(ctx.arg.outputFile.str() + ".",163 /*UseInputModulePath*/ true,164 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(ctx.arg.thinLTOIndexOnlyArg);172 173 // Initialize ltoObj.174 lto::ThinBackend backend;175 auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };176 if (ctx.arg.thinLTOIndexOnly) {177 backend = lto::createWriteIndexesThinBackend(178 llvm::hardware_concurrency(ctx.arg.thinLTOJobs),179 std::string(ctx.arg.thinLTOPrefixReplaceOld),180 std::string(ctx.arg.thinLTOPrefixReplaceNew),181 std::string(ctx.arg.thinLTOPrefixReplaceNativeObject),182 ctx.arg.thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);183 } else if (!ctx.arg.dtltoDistributor.empty()) {184 backend = lto::createOutOfProcessThinBackend(185 llvm::hardware_concurrency(ctx.arg.thinLTOJobs), onIndexWrite,186 ctx.arg.thinLTOEmitIndexFiles, ctx.arg.thinLTOEmitImportsFiles,187 ctx.arg.outputFile, ctx.arg.dtltoDistributor,188 ctx.arg.dtltoDistributorArgs, ctx.arg.dtltoCompiler,189 ctx.arg.dtltoCompilerPrependArgs, ctx.arg.dtltoCompilerArgs,190 !ctx.arg.saveTempsArgs.empty());191 } else {192 backend = lto::createInProcessThinBackend(193 llvm::heavyweight_hardware_concurrency(ctx.arg.thinLTOJobs),194 onIndexWrite, ctx.arg.thinLTOEmitIndexFiles,195 ctx.arg.thinLTOEmitImportsFiles);196 }197 198 constexpr llvm::lto::LTO::LTOKind ltoModes[3] =199 {llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,200 llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,201 llvm::lto::LTO::LTOKind::LTOK_Default};202 ltoObj = std::make_unique<lto::LTO>(createConfig(ctx), backend,203 ctx.arg.ltoPartitions,204 ltoModes[ctx.arg.ltoKind]);205 206 // Initialize usedStartStop.207 if (ctx.bitcodeFiles.empty())208 return;209 for (Symbol *sym : ctx.symtab->getSymbols()) {210 if (sym->isPlaceholder())211 continue;212 StringRef s = sym->getName();213 for (StringRef prefix : {"__start_", "__stop_"})214 if (s.starts_with(prefix))215 usedStartStop.insert(s.substr(prefix.size()));216 }217}218 219BitcodeCompiler::~BitcodeCompiler() = default;220 221void BitcodeCompiler::add(BitcodeFile &f) {222 lto::InputFile &obj = *f.obj;223 bool isExec = !ctx.arg.shared && !ctx.arg.relocatable;224 225 if (ctx.arg.thinLTOEmitIndexFiles)226 thinIndices.insert(obj.getName());227 228 ArrayRef<Symbol *> syms = f.getSymbols();229 ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();230 std::vector<lto::SymbolResolution> resols(syms.size());231 232 // Provide a resolution to the LTO API for each symbol.233 for (size_t i = 0, e = syms.size(); i != e; ++i) {234 Symbol *sym = syms[i];235 const lto::InputFile::Symbol &objSym = objSyms[i];236 lto::SymbolResolution &r = resols[i];237 238 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile239 // reports two symbols for module ASM defined. Without this check, lld240 // flags an undefined in IR with a definition in ASM as prevailing.241 // Once IRObjectFile is fixed to report only one symbol this hack can242 // be removed.243 r.Prevailing = !objSym.isUndefined() && sym->file == &f;244 245 // We ask LTO to preserve following global symbols:246 // 1) All symbols when doing relocatable link, so that them can be used247 // for doing final link.248 // 2) Symbols that are used in regular objects.249 // 3) C named sections if we have corresponding __start_/__stop_ symbol.250 // 4) Symbols that are defined in bitcode files and used for dynamic251 // linking.252 // 5) Symbols that will be referenced after linker wrapping is performed.253 r.VisibleToRegularObj = ctx.arg.relocatable || sym->isUsedInRegularObj ||254 sym->referencedAfterWrap ||255 (r.Prevailing && sym->isExported) ||256 usedStartStop.count(objSym.getSectionName());257 // Identify symbols exported dynamically, and that therefore could be258 // referenced by a shared library not visible to the linker.259 r.ExportDynamic = sym->computeBinding(ctx) != STB_LOCAL &&260 (ctx.arg.exportDynamic || sym->isExported);261 const auto *dr = dyn_cast<Defined>(sym);262 r.FinalDefinitionInLinkageUnit =263 (isExec || sym->visibility() != STV_DEFAULT) && dr &&264 // Skip absolute symbols from ELF objects, otherwise PC-rel relocations265 // will be generated by for them, triggering linker errors.266 // Symbol section is always null for bitcode symbols, hence the check267 // for isElf(). Skip linker script defined symbols as well: they have268 // no File defined.269 !(dr->section == nullptr &&270 (sym->file->isInternal() || sym->file->isElf()));271 272 if (r.Prevailing)273 Undefined(ctx.internalFile, StringRef(), STB_GLOBAL, STV_DEFAULT,274 sym->type)275 .overwrite(*sym);276 277 // We tell LTO to not apply interprocedural optimization for wrapped278 // (with --wrap) symbols because otherwise LTO would inline them while279 // their values are still not final.280 r.LinkerRedefined = sym->scriptDefined;281 }282 checkError(ctx.e, ltoObj->add(std::move(f.obj), resols));283}284 285// If LazyObjFile has not been added to link, emit empty index files.286// This is needed because this is what GNU gold plugin does and we have a287// distributed build system that depends on that behavior.288static void thinLTOCreateEmptyIndexFiles(Ctx &ctx) {289 DenseSet<StringRef> linkedBitCodeFiles;290 for (BitcodeFile *f : ctx.bitcodeFiles)291 linkedBitCodeFiles.insert(f->getName());292 293 for (BitcodeFile *f : ctx.lazyBitcodeFiles) {294 if (!f->lazy)295 continue;296 if (linkedBitCodeFiles.contains(f->getName()))297 continue;298 std::string path =299 replaceThinLTOSuffix(ctx, getThinLTOOutputFile(ctx, f->obj->getName()));300 std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");301 if (!os)302 continue;303 304 ModuleSummaryIndex m(/*HaveGVs*/ false);305 m.setSkipModuleByDistributedBackend();306 writeIndexToFile(m, *os);307 if (ctx.arg.thinLTOEmitImportsFiles)308 openFile(path + ".imports");309 }310}311 312// Merge all the bitcode files we have seen, codegen the result313// and return the resulting ObjectFile(s).314SmallVector<std::unique_ptr<InputFile>, 0> BitcodeCompiler::compile() {315 unsigned maxTasks = ltoObj->getMaxTasks();316 buf.resize(maxTasks);317 files.resize(maxTasks);318 filenames.resize(maxTasks);319 320 // The --thinlto-cache-dir option specifies the path to a directory in which321 // to cache native object files for ThinLTO incremental builds. If a path was322 // specified, configure LTO to use it as the cache directory.323 FileCache cache;324 if (!ctx.arg.thinLTOCacheDir.empty())325 cache = check(localCache("ThinLTO", "Thin", ctx.arg.thinLTOCacheDir,326 [&](size_t task, const Twine &moduleName,327 std::unique_ptr<MemoryBuffer> mb) {328 files[task] = std::move(mb);329 filenames[task] = moduleName.str();330 }));331 332 if (!ctx.bitcodeFiles.empty())333 checkError(ctx.e, ltoObj->run(334 [&](size_t task, const Twine &moduleName) {335 buf[task].first = moduleName.str();336 return std::make_unique<CachedFileStream>(337 std::make_unique<raw_svector_ostream>(338 buf[task].second));339 },340 cache));341 342 // Emit empty index files for non-indexed files but not in single-module mode.343 if (ctx.arg.thinLTOModulesToCompile.empty()) {344 for (StringRef s : thinIndices) {345 std::string path = getThinLTOOutputFile(ctx, s);346 openFile(path + ".thinlto.bc");347 if (ctx.arg.thinLTOEmitImportsFiles)348 openFile(path + ".imports");349 }350 }351 352 if (ctx.arg.thinLTOEmitIndexFiles)353 thinLTOCreateEmptyIndexFiles(ctx);354 355 if (ctx.arg.thinLTOIndexOnly) {356 if (!ctx.arg.ltoObjPath.empty())357 saveBuffer(buf[0].second, ctx.arg.ltoObjPath);358 359 // ThinLTO with index only option is required to generate only the index360 // files. After that, we exit from linker and ThinLTO backend runs in a361 // distributed environment.362 if (indexFile)363 indexFile->close();364 return {};365 }366 367 if (!ctx.arg.thinLTOCacheDir.empty())368 pruneCache(ctx.arg.thinLTOCacheDir, ctx.arg.thinLTOCachePolicy, files);369 370 if (!ctx.arg.ltoObjPath.empty()) {371 saveBuffer(buf[0].second, ctx.arg.ltoObjPath);372 for (unsigned i = 1; i != maxTasks; ++i)373 saveBuffer(buf[i].second, ctx.arg.ltoObjPath + Twine(i));374 }375 376 bool savePrelink = ctx.arg.saveTempsArgs.contains("prelink");377 SmallVector<std::unique_ptr<InputFile>, 0> ret;378 const char *ext = ctx.arg.ltoEmitAsm ? ".s" : ".o";379 for (unsigned i = 0; i != maxTasks; ++i) {380 StringRef bitcodeFilePath;381 StringRef objBuf;382 if (files[i]) {383 // When files[i] is not null, we get the native relocatable file from the384 // cache. filenames[i] contains the original BitcodeFile's identifier.385 objBuf = files[i]->getBuffer();386 bitcodeFilePath = filenames[i];387 } else {388 // Get the native relocatable file after in-process LTO compilation.389 objBuf = buf[i].second;390 bitcodeFilePath = buf[i].first;391 }392 if (objBuf.empty())393 continue;394 395 // If the input bitcode file is path/to/x.o and -o specifies a.out, the396 // corresponding native relocatable file path will look like:397 // path/to/a.out.lto.x.o.398 StringRef ltoObjName;399 if (bitcodeFilePath == "ld-temp.o") {400 ltoObjName =401 ctx.saver.save(Twine(ctx.arg.outputFile) + ".lto" +402 (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ext);403 } else {404 StringRef directory = sys::path::parent_path(bitcodeFilePath);405 // For an archive member, which has an identifier like "d/a.a(coll.o at406 // 8)" (see BitcodeFile::BitcodeFile), use the filename; otherwise, use407 // the stem (d/a.o => a).408 StringRef baseName = bitcodeFilePath.ends_with(")")409 ? sys::path::filename(bitcodeFilePath)410 : sys::path::stem(bitcodeFilePath);411 StringRef outputFileBaseName = sys::path::filename(ctx.arg.outputFile);412 SmallString<256> path;413 sys::path::append(path, directory,414 outputFileBaseName + ".lto." + baseName + ext);415 sys::path::remove_dots(path, true);416 ltoObjName = ctx.saver.save(path.str());417 }418 if (savePrelink || ctx.arg.ltoEmitAsm)419 saveBuffer(buf[i].second, ltoObjName);420 if (!ctx.arg.ltoEmitAsm)421 ret.push_back(createObjFile(ctx, MemoryBufferRef(objBuf, ltoObjName)));422 }423 return ret;424}425