diff options
Diffstat (limited to 'lld/ELF/LTO.cpp')
-rw-r--r-- | lld/ELF/LTO.cpp | 103 |
1 files changed, 75 insertions, 28 deletions
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index 2148ac500291..b8041afed6c9 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -41,9 +41,8 @@ using namespace llvm; using namespace llvm::object; using namespace llvm::ELF; - -namespace lld { -namespace elf { +using namespace lld; +using namespace lld::elf; // Creates an empty file to store a list of object files for final // linking of distributed ThinLTO. @@ -59,9 +58,9 @@ static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) { } static std::string getThinLTOOutputFile(StringRef modulePath) { - return lto::getThinLTOOutputFile(modulePath, - config->thinLTOPrefixReplace.first, - config->thinLTOPrefixReplace.second); + return lto::getThinLTOOutputFile( + std::string(modulePath), std::string(config->thinLTOPrefixReplace.first), + std::string(config->thinLTOPrefixReplace.second)); } static lto::Config createConfig() { @@ -76,6 +75,33 @@ static lto::Config createConfig() { c.Options.FunctionSections = true; c.Options.DataSections = true; + // Check if basic block sections must be used. + // Allowed values for --lto-basicblock-sections are "all", "labels", + // "<file name specifying basic block ids>", or none. This is the equivalent + // of -fbasic-block-sections= flag in clang. + if (!config->ltoBasicBlockSections.empty()) { + if (config->ltoBasicBlockSections == "all") { + c.Options.BBSections = BasicBlockSection::All; + } else if (config->ltoBasicBlockSections == "labels") { + c.Options.BBSections = BasicBlockSection::Labels; + } else if (config->ltoBasicBlockSections == "none") { + c.Options.BBSections = BasicBlockSection::None; + } else { + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = + MemoryBuffer::getFile(config->ltoBasicBlockSections.str()); + if (!MBOrErr) { + error("cannot open " + config->ltoBasicBlockSections + ":" + + MBOrErr.getError().message()); + } else { + c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr); + } + c.Options.BBSections = BasicBlockSection::List; + } + } + + c.Options.UniqueBasicBlockSectionNames = + config->ltoUniqueBasicBlockSectionNames; + if (auto relocModel = getRelocModelFromCMModel()) c.RelocModel = *relocModel; else if (config->relocatable) @@ -97,21 +123,30 @@ static lto::Config createConfig() { c.PTO.SLPVectorization = c.OptLevel > 1; // Set up a custom pipeline if we've been asked to. - c.OptPipeline = config->ltoNewPmPasses; - c.AAPipeline = config->ltoAAPipeline; + c.OptPipeline = std::string(config->ltoNewPmPasses); + c.AAPipeline = std::string(config->ltoAAPipeline); // Set up optimization remarks if we've been asked to. - c.RemarksFilename = config->optRemarksFilename; - c.RemarksPasses = config->optRemarksPasses; + c.RemarksFilename = std::string(config->optRemarksFilename); + c.RemarksPasses = std::string(config->optRemarksPasses); c.RemarksWithHotness = config->optRemarksWithHotness; - c.RemarksFormat = config->optRemarksFormat; + c.RemarksFormat = std::string(config->optRemarksFormat); - c.SampleProfile = config->ltoSampleProfile; + c.SampleProfile = std::string(config->ltoSampleProfile); c.UseNewPM = config->ltoNewPassManager; c.DebugPassManager = config->ltoDebugPassManager; - c.DwoDir = config->dwoDir; + c.DwoDir = std::string(config->dwoDir); - c.CSIRProfile = config->ltoCSProfileFile; + c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility; + c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty(); + + for (const llvm::StringRef &name : config->thinLTOModulesToCompile) + c.ThinLTOModulesToCompile.emplace_back(name); + + c.TimeTraceEnabled = config->timeTraceEnabled; + c.TimeTraceGranularity = config->timeTraceGranularity; + + c.CSIRProfile = std::string(config->ltoCSProfileFile); c.RunCSIRInstr = config->ltoCSProfileGenerate; if (config->emitLLVM) { @@ -122,6 +157,9 @@ static lto::Config createConfig() { }; } + if (config->ltoEmitAsm) + c.CGFileType = CGFT_AssemblyFile; + if (config->saveTemps) checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath*/ true)); @@ -138,10 +176,12 @@ BitcodeCompiler::BitcodeCompiler() { if (config->thinLTOIndexOnly) { auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); }; backend = lto::createWriteIndexesThinBackend( - config->thinLTOPrefixReplace.first, config->thinLTOPrefixReplace.second, + std::string(config->thinLTOPrefixReplace.first), + std::string(config->thinLTOPrefixReplace.second), config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite); - } else if (config->thinLTOJobs != -1U) { - backend = lto::createInProcessThinBackend(config->thinLTOJobs); + } else { + backend = lto::createInProcessThinBackend( + llvm::heavyweight_hardware_concurrency(config->thinLTOJobs)); } ltoObj = std::make_unique<lto::LTO>(createConfig(), backend, @@ -218,7 +258,7 @@ void BitcodeCompiler::add(BitcodeFile &f) { // distributed build system that depends on that behavior. static void thinLTOCreateEmptyIndexFiles() { for (LazyObjFile *f : lazyObjFiles) { - if (!isBitcode(f->mb)) + if (f->fetched || !isBitcode(f->mb)) continue; std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName())); std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc"); @@ -259,12 +299,14 @@ std::vector<InputFile *> BitcodeCompiler::compile() { }, cache)); - // Emit empty index files for non-indexed files - for (StringRef s : thinIndices) { - std::string path = getThinLTOOutputFile(s); - openFile(path + ".thinlto.bc"); - if (config->thinLTOEmitImportsFiles) - openFile(path + ".imports"); + // Emit empty index files for non-indexed files but not in single-module mode. + if (config->thinLTOModulesToCompile.empty()) { + for (StringRef s : thinIndices) { + std::string path = getThinLTOOutputFile(s); + openFile(path + ".thinlto.bc"); + if (config->thinLTOEmitImportsFiles) + openFile(path + ".imports"); + } } if (config->thinLTOIndexOnly) { @@ -291,11 +333,19 @@ std::vector<InputFile *> BitcodeCompiler::compile() { } if (config->saveTemps) { - saveBuffer(buf[0], config->outputFile + ".lto.o"); + if (!buf[0].empty()) + saveBuffer(buf[0], config->outputFile + ".lto.o"); for (unsigned i = 1; i != maxTasks; ++i) saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o"); } + if (config->ltoEmitAsm) { + saveBuffer(buf[0], config->outputFile); + for (unsigned i = 1; i != maxTasks; ++i) + saveBuffer(buf[i], config->outputFile + Twine(i)); + return {}; + } + std::vector<InputFile *> ret; for (unsigned i = 0; i != maxTasks; ++i) if (!buf[i].empty()) @@ -306,6 +356,3 @@ std::vector<InputFile *> BitcodeCompiler::compile() { ret.push_back(createObjectFile(*file)); return ret; } - -} // namespace elf -} // namespace lld |