xref: /freebsd/contrib/llvm-project/lld/ELF/LTO.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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 "LinkerScript.h"
130b57cec5SDimitry Andric #include "SymbolTable.h"
140b57cec5SDimitry Andric #include "Symbols.h"
150b57cec5SDimitry Andric #include "lld/Common/Args.h"
160b57cec5SDimitry Andric #include "lld/Common/ErrorHandler.h"
170b57cec5SDimitry Andric #include "lld/Common/TargetOptionsCommandFlags.h"
180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
210b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
220b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
230b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeReader.h"
240b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h"
250b57cec5SDimitry Andric #include "llvm/IR/DiagnosticPrinter.h"
260b57cec5SDimitry Andric #include "llvm/LTO/Caching.h"
270b57cec5SDimitry Andric #include "llvm/LTO/Config.h"
280b57cec5SDimitry Andric #include "llvm/LTO/LTO.h"
290b57cec5SDimitry Andric #include "llvm/Object/SymbolicFile.h"
300b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
310b57cec5SDimitry Andric #include "llvm/Support/Error.h"
320b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
330b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
340b57cec5SDimitry Andric #include <algorithm>
350b57cec5SDimitry Andric #include <cstddef>
360b57cec5SDimitry Andric #include <memory>
370b57cec5SDimitry Andric #include <string>
380b57cec5SDimitry Andric #include <system_error>
390b57cec5SDimitry Andric #include <vector>
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric using namespace llvm;
420b57cec5SDimitry Andric using namespace llvm::object;
430b57cec5SDimitry Andric using namespace llvm::ELF;
445ffd83dbSDimitry Andric using namespace lld;
455ffd83dbSDimitry Andric using namespace lld::elf;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric // Creates an empty file to store a list of object files for final
480b57cec5SDimitry Andric // linking of distributed ThinLTO.
490b57cec5SDimitry Andric static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) {
500b57cec5SDimitry Andric   std::error_code ec;
510b57cec5SDimitry Andric   auto ret =
5285868e8aSDimitry Andric       std::make_unique<raw_fd_ostream>(file, ec, sys::fs::OpenFlags::OF_None);
530b57cec5SDimitry Andric   if (ec) {
540b57cec5SDimitry Andric     error("cannot open " + file + ": " + ec.message());
550b57cec5SDimitry Andric     return nullptr;
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric   return ret;
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
60*e8d8bef9SDimitry Andric // The merged bitcode after LTO is large. Try openning a file stream that
61*e8d8bef9SDimitry Andric // supports reading, seeking and writing. Such a file allows BitcodeWriter to
62*e8d8bef9SDimitry Andric // flush buffered data to reduce memory comsuption. If this fails, open a file
63*e8d8bef9SDimitry Andric // stream that supports only write.
64*e8d8bef9SDimitry Andric static std::unique_ptr<raw_fd_ostream> openLTOOutputFile(StringRef file) {
65*e8d8bef9SDimitry Andric   std::error_code ec;
66*e8d8bef9SDimitry Andric   std::unique_ptr<raw_fd_ostream> fs =
67*e8d8bef9SDimitry Andric       std::make_unique<raw_fd_stream>(file, ec);
68*e8d8bef9SDimitry Andric   if (!ec)
69*e8d8bef9SDimitry Andric     return fs;
70*e8d8bef9SDimitry Andric   return openFile(file);
71*e8d8bef9SDimitry Andric }
72*e8d8bef9SDimitry Andric 
730b57cec5SDimitry Andric static std::string getThinLTOOutputFile(StringRef modulePath) {
745ffd83dbSDimitry Andric   return lto::getThinLTOOutputFile(
755ffd83dbSDimitry Andric       std::string(modulePath), std::string(config->thinLTOPrefixReplace.first),
765ffd83dbSDimitry Andric       std::string(config->thinLTOPrefixReplace.second));
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric static lto::Config createConfig() {
800b57cec5SDimitry Andric   lto::Config c;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   // LLD supports the new relocations and address-significance tables.
830b57cec5SDimitry Andric   c.Options = initTargetOptionsFromCodeGenFlags();
840b57cec5SDimitry Andric   c.Options.RelaxELFRelocations = true;
850b57cec5SDimitry Andric   c.Options.EmitAddrsig = true;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   // Always emit a section per function/datum with LTO.
880b57cec5SDimitry Andric   c.Options.FunctionSections = true;
890b57cec5SDimitry Andric   c.Options.DataSections = true;
900b57cec5SDimitry Andric 
915ffd83dbSDimitry Andric   // Check if basic block sections must be used.
92*e8d8bef9SDimitry Andric   // Allowed values for --lto-basic-block-sections are "all", "labels",
935ffd83dbSDimitry Andric   // "<file name specifying basic block ids>", or none.  This is the equivalent
945ffd83dbSDimitry Andric   // of -fbasic-block-sections= flag in clang.
955ffd83dbSDimitry Andric   if (!config->ltoBasicBlockSections.empty()) {
965ffd83dbSDimitry Andric     if (config->ltoBasicBlockSections == "all") {
975ffd83dbSDimitry Andric       c.Options.BBSections = BasicBlockSection::All;
985ffd83dbSDimitry Andric     } else if (config->ltoBasicBlockSections == "labels") {
995ffd83dbSDimitry Andric       c.Options.BBSections = BasicBlockSection::Labels;
1005ffd83dbSDimitry Andric     } else if (config->ltoBasicBlockSections == "none") {
1015ffd83dbSDimitry Andric       c.Options.BBSections = BasicBlockSection::None;
1025ffd83dbSDimitry Andric     } else {
1035ffd83dbSDimitry Andric       ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
1045ffd83dbSDimitry Andric           MemoryBuffer::getFile(config->ltoBasicBlockSections.str());
1055ffd83dbSDimitry Andric       if (!MBOrErr) {
1065ffd83dbSDimitry Andric         error("cannot open " + config->ltoBasicBlockSections + ":" +
1075ffd83dbSDimitry Andric               MBOrErr.getError().message());
1085ffd83dbSDimitry Andric       } else {
1095ffd83dbSDimitry Andric         c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
1105ffd83dbSDimitry Andric       }
1115ffd83dbSDimitry Andric       c.Options.BBSections = BasicBlockSection::List;
1125ffd83dbSDimitry Andric     }
1135ffd83dbSDimitry Andric   }
1145ffd83dbSDimitry Andric 
115*e8d8bef9SDimitry Andric   c.Options.PseudoProbeForProfiling = config->ltoPseudoProbeForProfiling;
1165ffd83dbSDimitry Andric   c.Options.UniqueBasicBlockSectionNames =
1175ffd83dbSDimitry Andric       config->ltoUniqueBasicBlockSectionNames;
1185ffd83dbSDimitry Andric 
11985868e8aSDimitry Andric   if (auto relocModel = getRelocModelFromCMModel())
12085868e8aSDimitry Andric     c.RelocModel = *relocModel;
12185868e8aSDimitry Andric   else if (config->relocatable)
1220b57cec5SDimitry Andric     c.RelocModel = None;
1230b57cec5SDimitry Andric   else if (config->isPic)
1240b57cec5SDimitry Andric     c.RelocModel = Reloc::PIC_;
1250b57cec5SDimitry Andric   else
1260b57cec5SDimitry Andric     c.RelocModel = Reloc::Static;
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   c.CodeModel = getCodeModelFromCMModel();
1290b57cec5SDimitry Andric   c.DisableVerify = config->disableVerify;
1300b57cec5SDimitry Andric   c.DiagHandler = diagnosticHandler;
1310b57cec5SDimitry Andric   c.OptLevel = config->ltoo;
1320b57cec5SDimitry Andric   c.CPU = getCPUStr();
1330b57cec5SDimitry Andric   c.MAttrs = getMAttrs();
1340b57cec5SDimitry Andric   c.CGOptLevel = args::getCGOptLevel(config->ltoo);
1350b57cec5SDimitry Andric 
136480093f4SDimitry Andric   c.PTO.LoopVectorization = c.OptLevel > 1;
137480093f4SDimitry Andric   c.PTO.SLPVectorization = c.OptLevel > 1;
138480093f4SDimitry Andric 
1390b57cec5SDimitry Andric   // Set up a custom pipeline if we've been asked to.
1405ffd83dbSDimitry Andric   c.OptPipeline = std::string(config->ltoNewPmPasses);
1415ffd83dbSDimitry Andric   c.AAPipeline = std::string(config->ltoAAPipeline);
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   // Set up optimization remarks if we've been asked to.
1445ffd83dbSDimitry Andric   c.RemarksFilename = std::string(config->optRemarksFilename);
1455ffd83dbSDimitry Andric   c.RemarksPasses = std::string(config->optRemarksPasses);
1460b57cec5SDimitry Andric   c.RemarksWithHotness = config->optRemarksWithHotness;
147*e8d8bef9SDimitry Andric   c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
1485ffd83dbSDimitry Andric   c.RemarksFormat = std::string(config->optRemarksFormat);
1490b57cec5SDimitry Andric 
1505ffd83dbSDimitry Andric   c.SampleProfile = std::string(config->ltoSampleProfile);
1510b57cec5SDimitry Andric   c.UseNewPM = config->ltoNewPassManager;
1520b57cec5SDimitry Andric   c.DebugPassManager = config->ltoDebugPassManager;
1535ffd83dbSDimitry Andric   c.DwoDir = std::string(config->dwoDir);
1540b57cec5SDimitry Andric 
1555ffd83dbSDimitry Andric   c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility;
1565ffd83dbSDimitry Andric   c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
1575ffd83dbSDimitry Andric 
1585ffd83dbSDimitry Andric   for (const llvm::StringRef &name : config->thinLTOModulesToCompile)
1595ffd83dbSDimitry Andric     c.ThinLTOModulesToCompile.emplace_back(name);
1605ffd83dbSDimitry Andric 
1615ffd83dbSDimitry Andric   c.TimeTraceEnabled = config->timeTraceEnabled;
1625ffd83dbSDimitry Andric   c.TimeTraceGranularity = config->timeTraceGranularity;
1635ffd83dbSDimitry Andric 
1645ffd83dbSDimitry Andric   c.CSIRProfile = std::string(config->ltoCSProfileFile);
1650b57cec5SDimitry Andric   c.RunCSIRInstr = config->ltoCSProfileGenerate;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   if (config->emitLLVM) {
1680b57cec5SDimitry Andric     c.PostInternalizeModuleHook = [](size_t task, const Module &m) {
169*e8d8bef9SDimitry Andric       if (std::unique_ptr<raw_fd_ostream> os =
170*e8d8bef9SDimitry Andric               openLTOOutputFile(config->outputFile))
1710b57cec5SDimitry Andric         WriteBitcodeToFile(m, *os, false);
1720b57cec5SDimitry Andric       return false;
1730b57cec5SDimitry Andric     };
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
1765ffd83dbSDimitry Andric   if (config->ltoEmitAsm)
1775ffd83dbSDimitry Andric     c.CGFileType = CGFT_AssemblyFile;
1785ffd83dbSDimitry Andric 
1790b57cec5SDimitry Andric   if (config->saveTemps)
1800b57cec5SDimitry Andric     checkError(c.addSaveTemps(config->outputFile.str() + ".",
1810b57cec5SDimitry Andric                               /*UseInputModulePath*/ true));
1820b57cec5SDimitry Andric   return c;
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric BitcodeCompiler::BitcodeCompiler() {
1860b57cec5SDimitry Andric   // Initialize indexFile.
1870b57cec5SDimitry Andric   if (!config->thinLTOIndexOnlyArg.empty())
1880b57cec5SDimitry Andric     indexFile = openFile(config->thinLTOIndexOnlyArg);
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   // Initialize ltoObj.
1910b57cec5SDimitry Andric   lto::ThinBackend backend;
1920b57cec5SDimitry Andric   if (config->thinLTOIndexOnly) {
1930b57cec5SDimitry Andric     auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
1940b57cec5SDimitry Andric     backend = lto::createWriteIndexesThinBackend(
1955ffd83dbSDimitry Andric         std::string(config->thinLTOPrefixReplace.first),
1965ffd83dbSDimitry Andric         std::string(config->thinLTOPrefixReplace.second),
1970b57cec5SDimitry Andric         config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
1985ffd83dbSDimitry Andric   } else {
1995ffd83dbSDimitry Andric     backend = lto::createInProcessThinBackend(
2005ffd83dbSDimitry Andric         llvm::heavyweight_hardware_concurrency(config->thinLTOJobs));
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric 
20385868e8aSDimitry Andric   ltoObj = std::make_unique<lto::LTO>(createConfig(), backend,
2040b57cec5SDimitry Andric                                        config->ltoPartitions);
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   // Initialize usedStartStop.
207480093f4SDimitry Andric   for (Symbol *sym : symtab->symbols()) {
2080b57cec5SDimitry Andric     StringRef s = sym->getName();
2090b57cec5SDimitry Andric     for (StringRef prefix : {"__start_", "__stop_"})
2100b57cec5SDimitry Andric       if (s.startswith(prefix))
2110b57cec5SDimitry Andric         usedStartStop.insert(s.substr(prefix.size()));
212480093f4SDimitry Andric   }
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric BitcodeCompiler::~BitcodeCompiler() = default;
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric void BitcodeCompiler::add(BitcodeFile &f) {
2180b57cec5SDimitry Andric   lto::InputFile &obj = *f.obj;
2190b57cec5SDimitry Andric   bool isExec = !config->shared && !config->relocatable;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   if (config->thinLTOIndexOnly)
2220b57cec5SDimitry Andric     thinIndices.insert(obj.getName());
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   ArrayRef<Symbol *> syms = f.getSymbols();
2250b57cec5SDimitry Andric   ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
2260b57cec5SDimitry Andric   std::vector<lto::SymbolResolution> resols(syms.size());
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   // Provide a resolution to the LTO API for each symbol.
2290b57cec5SDimitry Andric   for (size_t i = 0, e = syms.size(); i != e; ++i) {
2300b57cec5SDimitry Andric     Symbol *sym = syms[i];
2310b57cec5SDimitry Andric     const lto::InputFile::Symbol &objSym = objSyms[i];
2320b57cec5SDimitry Andric     lto::SymbolResolution &r = resols[i];
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric     // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
2350b57cec5SDimitry Andric     // reports two symbols for module ASM defined. Without this check, lld
2360b57cec5SDimitry Andric     // flags an undefined in IR with a definition in ASM as prevailing.
2370b57cec5SDimitry Andric     // Once IRObjectFile is fixed to report only one symbol this hack can
2380b57cec5SDimitry Andric     // be removed.
2390b57cec5SDimitry Andric     r.Prevailing = !objSym.isUndefined() && sym->file == &f;
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric     // We ask LTO to preserve following global symbols:
2420b57cec5SDimitry Andric     // 1) All symbols when doing relocatable link, so that them can be used
2430b57cec5SDimitry Andric     //    for doing final link.
2440b57cec5SDimitry Andric     // 2) Symbols that are used in regular objects.
2450b57cec5SDimitry Andric     // 3) C named sections if we have corresponding __start_/__stop_ symbol.
2460b57cec5SDimitry Andric     // 4) Symbols that are defined in bitcode files and used for dynamic linking.
2470b57cec5SDimitry Andric     r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
2480b57cec5SDimitry Andric                             (r.Prevailing && sym->includeInDynsym()) ||
2490b57cec5SDimitry Andric                             usedStartStop.count(objSym.getSectionName());
2500b57cec5SDimitry Andric     const auto *dr = dyn_cast<Defined>(sym);
2510b57cec5SDimitry Andric     r.FinalDefinitionInLinkageUnit =
2520b57cec5SDimitry Andric         (isExec || sym->visibility != STV_DEFAULT) && dr &&
2530b57cec5SDimitry Andric         // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
2540b57cec5SDimitry Andric         // will be generated by for them, triggering linker errors.
2550b57cec5SDimitry Andric         // Symbol section is always null for bitcode symbols, hence the check
2560b57cec5SDimitry Andric         // for isElf(). Skip linker script defined symbols as well: they have
2570b57cec5SDimitry Andric         // no File defined.
2580b57cec5SDimitry Andric         !(dr->section == nullptr && (!sym->file || sym->file->isElf()));
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric     if (r.Prevailing)
2610b57cec5SDimitry Andric       sym->replace(Undefined{nullptr, sym->getName(), STB_GLOBAL, STV_DEFAULT,
2620b57cec5SDimitry Andric                              sym->type});
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric     // We tell LTO to not apply interprocedural optimization for wrapped
2650b57cec5SDimitry Andric     // (with --wrap) symbols because otherwise LTO would inline them while
2660b57cec5SDimitry Andric     // their values are still not final.
2670b57cec5SDimitry Andric     r.LinkerRedefined = !sym->canInline;
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric   checkError(ltoObj->add(std::move(f.obj), resols));
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric // If LazyObjFile has not been added to link, emit empty index files.
2730b57cec5SDimitry Andric // This is needed because this is what GNU gold plugin does and we have a
2740b57cec5SDimitry Andric // distributed build system that depends on that behavior.
2750b57cec5SDimitry Andric static void thinLTOCreateEmptyIndexFiles() {
2760b57cec5SDimitry Andric   for (LazyObjFile *f : lazyObjFiles) {
2775ffd83dbSDimitry Andric     if (f->fetched || !isBitcode(f->mb))
2780b57cec5SDimitry Andric       continue;
2790b57cec5SDimitry Andric     std::string path = replaceThinLTOSuffix(getThinLTOOutputFile(f->getName()));
2800b57cec5SDimitry Andric     std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");
2810b57cec5SDimitry Andric     if (!os)
2820b57cec5SDimitry Andric       continue;
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric     ModuleSummaryIndex m(/*HaveGVs*/ false);
2850b57cec5SDimitry Andric     m.setSkipModuleByDistributedBackend();
2860b57cec5SDimitry Andric     WriteIndexToFile(m, *os);
2870b57cec5SDimitry Andric     if (config->thinLTOEmitImportsFiles)
2880b57cec5SDimitry Andric       openFile(path + ".imports");
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric // Merge all the bitcode files we have seen, codegen the result
2930b57cec5SDimitry Andric // and return the resulting ObjectFile(s).
2940b57cec5SDimitry Andric std::vector<InputFile *> BitcodeCompiler::compile() {
2950b57cec5SDimitry Andric   unsigned maxTasks = ltoObj->getMaxTasks();
2960b57cec5SDimitry Andric   buf.resize(maxTasks);
2970b57cec5SDimitry Andric   files.resize(maxTasks);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   // The --thinlto-cache-dir option specifies the path to a directory in which
3000b57cec5SDimitry Andric   // to cache native object files for ThinLTO incremental builds. If a path was
3010b57cec5SDimitry Andric   // specified, configure LTO to use it as the cache directory.
3020b57cec5SDimitry Andric   lto::NativeObjectCache cache;
3030b57cec5SDimitry Andric   if (!config->thinLTOCacheDir.empty())
3040b57cec5SDimitry Andric     cache = check(
3050b57cec5SDimitry Andric         lto::localCache(config->thinLTOCacheDir,
3060b57cec5SDimitry Andric                         [&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
3070b57cec5SDimitry Andric                           files[task] = std::move(mb);
3080b57cec5SDimitry Andric                         }));
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   if (!bitcodeFiles.empty())
3110b57cec5SDimitry Andric     checkError(ltoObj->run(
3120b57cec5SDimitry Andric         [&](size_t task) {
31385868e8aSDimitry Andric           return std::make_unique<lto::NativeObjectStream>(
31485868e8aSDimitry Andric               std::make_unique<raw_svector_ostream>(buf[task]));
3150b57cec5SDimitry Andric         },
3160b57cec5SDimitry Andric         cache));
3170b57cec5SDimitry Andric 
3185ffd83dbSDimitry Andric   // Emit empty index files for non-indexed files but not in single-module mode.
3195ffd83dbSDimitry Andric   if (config->thinLTOModulesToCompile.empty()) {
3200b57cec5SDimitry Andric     for (StringRef s : thinIndices) {
3210b57cec5SDimitry Andric       std::string path = getThinLTOOutputFile(s);
3220b57cec5SDimitry Andric       openFile(path + ".thinlto.bc");
3230b57cec5SDimitry Andric       if (config->thinLTOEmitImportsFiles)
3240b57cec5SDimitry Andric         openFile(path + ".imports");
3250b57cec5SDimitry Andric     }
3265ffd83dbSDimitry Andric   }
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   if (config->thinLTOIndexOnly) {
3290b57cec5SDimitry Andric     thinLTOCreateEmptyIndexFiles();
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric     if (!config->ltoObjPath.empty())
3320b57cec5SDimitry Andric       saveBuffer(buf[0], config->ltoObjPath);
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric     // ThinLTO with index only option is required to generate only the index
3350b57cec5SDimitry Andric     // files. After that, we exit from linker and ThinLTO backend runs in a
3360b57cec5SDimitry Andric     // distributed environment.
3370b57cec5SDimitry Andric     if (indexFile)
3380b57cec5SDimitry Andric       indexFile->close();
3390b57cec5SDimitry Andric     return {};
3400b57cec5SDimitry Andric   }
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   if (!config->thinLTOCacheDir.empty())
3430b57cec5SDimitry Andric     pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy);
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric   if (!config->ltoObjPath.empty()) {
3460b57cec5SDimitry Andric     saveBuffer(buf[0], config->ltoObjPath);
3470b57cec5SDimitry Andric     for (unsigned i = 1; i != maxTasks; ++i)
3480b57cec5SDimitry Andric       saveBuffer(buf[i], config->ltoObjPath + Twine(i));
3490b57cec5SDimitry Andric   }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   if (config->saveTemps) {
3525ffd83dbSDimitry Andric     if (!buf[0].empty())
3530b57cec5SDimitry Andric       saveBuffer(buf[0], config->outputFile + ".lto.o");
3540b57cec5SDimitry Andric     for (unsigned i = 1; i != maxTasks; ++i)
3550b57cec5SDimitry Andric       saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
3560b57cec5SDimitry Andric   }
3570b57cec5SDimitry Andric 
3585ffd83dbSDimitry Andric   if (config->ltoEmitAsm) {
3595ffd83dbSDimitry Andric     saveBuffer(buf[0], config->outputFile);
3605ffd83dbSDimitry Andric     for (unsigned i = 1; i != maxTasks; ++i)
3615ffd83dbSDimitry Andric       saveBuffer(buf[i], config->outputFile + Twine(i));
3625ffd83dbSDimitry Andric     return {};
3635ffd83dbSDimitry Andric   }
3645ffd83dbSDimitry Andric 
3650b57cec5SDimitry Andric   std::vector<InputFile *> ret;
3660b57cec5SDimitry Andric   for (unsigned i = 0; i != maxTasks; ++i)
3670b57cec5SDimitry Andric     if (!buf[i].empty())
3680b57cec5SDimitry Andric       ret.push_back(createObjectFile(MemoryBufferRef(buf[i], "lto.tmp")));
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   for (std::unique_ptr<MemoryBuffer> &file : files)
3710b57cec5SDimitry Andric     if (file)
3720b57cec5SDimitry Andric       ret.push_back(createObjectFile(*file));
3730b57cec5SDimitry Andric   return ret;
3740b57cec5SDimitry Andric }
375