xref: /openbsd-src/gnu/llvm/lld/ELF/LTO.cpp (revision dfe94b169149f14cc1aee2cf6dad58a8d9a1860c)
1ece8a530Spatrick //===- LTO.cpp ------------------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick 
9ece8a530Spatrick #include "LTO.h"
10ece8a530Spatrick #include "Config.h"
11ece8a530Spatrick #include "InputFiles.h"
12ece8a530Spatrick #include "SymbolTable.h"
13ece8a530Spatrick #include "Symbols.h"
14ece8a530Spatrick #include "lld/Common/Args.h"
15ece8a530Spatrick #include "lld/Common/ErrorHandler.h"
16*dfe94b16Srobert #include "lld/Common/Strings.h"
17ece8a530Spatrick #include "lld/Common/TargetOptionsCommandFlags.h"
18ece8a530Spatrick #include "llvm/ADT/SmallString.h"
19ece8a530Spatrick #include "llvm/ADT/StringRef.h"
20ece8a530Spatrick #include "llvm/ADT/Twine.h"
21ece8a530Spatrick #include "llvm/BinaryFormat/ELF.h"
22ece8a530Spatrick #include "llvm/Bitcode/BitcodeWriter.h"
23ece8a530Spatrick #include "llvm/LTO/Config.h"
24ece8a530Spatrick #include "llvm/LTO/LTO.h"
25*dfe94b16Srobert #include "llvm/Support/Caching.h"
26ece8a530Spatrick #include "llvm/Support/CodeGen.h"
27ece8a530Spatrick #include "llvm/Support/Error.h"
28ece8a530Spatrick #include "llvm/Support/FileSystem.h"
29ece8a530Spatrick #include "llvm/Support/MemoryBuffer.h"
30ece8a530Spatrick #include <algorithm>
31ece8a530Spatrick #include <cstddef>
32ece8a530Spatrick #include <memory>
33ece8a530Spatrick #include <string>
34ece8a530Spatrick #include <system_error>
35ece8a530Spatrick #include <vector>
36ece8a530Spatrick 
37ece8a530Spatrick using namespace llvm;
38ece8a530Spatrick using namespace llvm::object;
39ece8a530Spatrick using namespace llvm::ELF;
40bb684c34Spatrick using namespace lld;
41bb684c34Spatrick using namespace lld::elf;
42ece8a530Spatrick 
43ece8a530Spatrick // Creates an empty file to store a list of object files for final
44ece8a530Spatrick // linking of distributed ThinLTO.
openFile(StringRef file)45ece8a530Spatrick static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) {
46ece8a530Spatrick   std::error_code ec;
47ece8a530Spatrick   auto ret =
48ece8a530Spatrick       std::make_unique<raw_fd_ostream>(file, ec, sys::fs::OpenFlags::OF_None);
49ece8a530Spatrick   if (ec) {
50ece8a530Spatrick     error("cannot open " + file + ": " + ec.message());
51ece8a530Spatrick     return nullptr;
52ece8a530Spatrick   }
53ece8a530Spatrick   return ret;
54ece8a530Spatrick }
55ece8a530Spatrick 
561cf9926bSpatrick // The merged bitcode after LTO is large. Try opening a file stream that
571cf9926bSpatrick // supports reading, seeking and writing. Such a file allows BitcodeWriter to
581cf9926bSpatrick // flush buffered data to reduce memory consumption. If this fails, open a file
591cf9926bSpatrick // stream that supports only write.
openLTOOutputFile(StringRef file)601cf9926bSpatrick static std::unique_ptr<raw_fd_ostream> openLTOOutputFile(StringRef file) {
611cf9926bSpatrick   std::error_code ec;
621cf9926bSpatrick   std::unique_ptr<raw_fd_ostream> fs =
631cf9926bSpatrick       std::make_unique<raw_fd_stream>(file, ec);
641cf9926bSpatrick   if (!ec)
651cf9926bSpatrick     return fs;
661cf9926bSpatrick   return openFile(file);
671cf9926bSpatrick }
681cf9926bSpatrick 
getThinLTOOutputFile(StringRef modulePath)69ece8a530Spatrick static std::string getThinLTOOutputFile(StringRef modulePath) {
70bb684c34Spatrick   return lto::getThinLTOOutputFile(
71bb684c34Spatrick       std::string(modulePath), std::string(config->thinLTOPrefixReplace.first),
72bb684c34Spatrick       std::string(config->thinLTOPrefixReplace.second));
73ece8a530Spatrick }
74ece8a530Spatrick 
createConfig()75ece8a530Spatrick static lto::Config createConfig() {
76ece8a530Spatrick   lto::Config c;
77ece8a530Spatrick 
78ece8a530Spatrick   // LLD supports the new relocations and address-significance tables.
79ece8a530Spatrick   c.Options = initTargetOptionsFromCodeGenFlags();
80ece8a530Spatrick   c.Options.EmitAddrsig = true;
81*dfe94b16Srobert   for (StringRef C : config->mllvmOpts)
82*dfe94b16Srobert     c.MllvmArgs.emplace_back(C.str());
83ece8a530Spatrick 
84ece8a530Spatrick   // Always emit a section per function/datum with LTO.
85ece8a530Spatrick   c.Options.FunctionSections = true;
86ece8a530Spatrick   c.Options.DataSections = true;
87ece8a530Spatrick 
88bb684c34Spatrick   // Check if basic block sections must be used.
891cf9926bSpatrick   // Allowed values for --lto-basic-block-sections are "all", "labels",
90bb684c34Spatrick   // "<file name specifying basic block ids>", or none.  This is the equivalent
91bb684c34Spatrick   // of -fbasic-block-sections= flag in clang.
92bb684c34Spatrick   if (!config->ltoBasicBlockSections.empty()) {
93bb684c34Spatrick     if (config->ltoBasicBlockSections == "all") {
94bb684c34Spatrick       c.Options.BBSections = BasicBlockSection::All;
95bb684c34Spatrick     } else if (config->ltoBasicBlockSections == "labels") {
96bb684c34Spatrick       c.Options.BBSections = BasicBlockSection::Labels;
97bb684c34Spatrick     } else if (config->ltoBasicBlockSections == "none") {
98bb684c34Spatrick       c.Options.BBSections = BasicBlockSection::None;
99bb684c34Spatrick     } else {
100bb684c34Spatrick       ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
101bb684c34Spatrick           MemoryBuffer::getFile(config->ltoBasicBlockSections.str());
102bb684c34Spatrick       if (!MBOrErr) {
103bb684c34Spatrick         error("cannot open " + config->ltoBasicBlockSections + ":" +
104bb684c34Spatrick               MBOrErr.getError().message());
105bb684c34Spatrick       } else {
106bb684c34Spatrick         c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
107bb684c34Spatrick       }
108bb684c34Spatrick       c.Options.BBSections = BasicBlockSection::List;
109bb684c34Spatrick     }
110bb684c34Spatrick   }
111bb684c34Spatrick 
112bb684c34Spatrick   c.Options.UniqueBasicBlockSectionNames =
113bb684c34Spatrick       config->ltoUniqueBasicBlockSectionNames;
114bb684c34Spatrick 
115ece8a530Spatrick   if (auto relocModel = getRelocModelFromCMModel())
116ece8a530Spatrick     c.RelocModel = *relocModel;
117ece8a530Spatrick   else if (config->relocatable)
118*dfe94b16Srobert     c.RelocModel = std::nullopt;
119ece8a530Spatrick   else if (config->isPic)
120ece8a530Spatrick     c.RelocModel = Reloc::PIC_;
121ece8a530Spatrick   else
122ece8a530Spatrick     c.RelocModel = Reloc::Static;
123ece8a530Spatrick 
124ece8a530Spatrick   c.CodeModel = getCodeModelFromCMModel();
125ece8a530Spatrick   c.DisableVerify = config->disableVerify;
126ece8a530Spatrick   c.DiagHandler = diagnosticHandler;
127ece8a530Spatrick   c.OptLevel = config->ltoo;
128ece8a530Spatrick   c.CPU = getCPUStr();
129ece8a530Spatrick   c.MAttrs = getMAttrs();
130ece8a530Spatrick   c.CGOptLevel = args::getCGOptLevel(config->ltoo);
131ece8a530Spatrick 
132ece8a530Spatrick   c.PTO.LoopVectorization = c.OptLevel > 1;
133ece8a530Spatrick   c.PTO.SLPVectorization = c.OptLevel > 1;
134ece8a530Spatrick 
135ece8a530Spatrick   // Set up a custom pipeline if we've been asked to.
136bb684c34Spatrick   c.OptPipeline = std::string(config->ltoNewPmPasses);
137bb684c34Spatrick   c.AAPipeline = std::string(config->ltoAAPipeline);
138ece8a530Spatrick 
139ece8a530Spatrick   // Set up optimization remarks if we've been asked to.
140bb684c34Spatrick   c.RemarksFilename = std::string(config->optRemarksFilename);
141bb684c34Spatrick   c.RemarksPasses = std::string(config->optRemarksPasses);
142ece8a530Spatrick   c.RemarksWithHotness = config->optRemarksWithHotness;
1431cf9926bSpatrick   c.RemarksHotnessThreshold = config->optRemarksHotnessThreshold;
144bb684c34Spatrick   c.RemarksFormat = std::string(config->optRemarksFormat);
145ece8a530Spatrick 
146*dfe94b16Srobert   // Set up output file to emit statistics.
147*dfe94b16Srobert   c.StatsFile = std::string(config->optStatsFilename);
148*dfe94b16Srobert 
149bb684c34Spatrick   c.SampleProfile = std::string(config->ltoSampleProfile);
150*dfe94b16Srobert   for (StringRef pluginFn : config->passPlugins)
151*dfe94b16Srobert     c.PassPlugins.push_back(std::string(pluginFn));
152ece8a530Spatrick   c.DebugPassManager = config->ltoDebugPassManager;
153bb684c34Spatrick   c.DwoDir = std::string(config->dwoDir);
154ece8a530Spatrick 
155bb684c34Spatrick   c.HasWholeProgramVisibility = config->ltoWholeProgramVisibility;
156bb684c34Spatrick   c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
157bb684c34Spatrick 
158bb684c34Spatrick   for (const llvm::StringRef &name : config->thinLTOModulesToCompile)
159bb684c34Spatrick     c.ThinLTOModulesToCompile.emplace_back(name);
160bb684c34Spatrick 
161bb684c34Spatrick   c.TimeTraceEnabled = config->timeTraceEnabled;
162bb684c34Spatrick   c.TimeTraceGranularity = config->timeTraceGranularity;
163bb684c34Spatrick 
164bb684c34Spatrick   c.CSIRProfile = std::string(config->ltoCSProfileFile);
165ece8a530Spatrick   c.RunCSIRInstr = config->ltoCSProfileGenerate;
166*dfe94b16Srobert   c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
167*dfe94b16Srobert 
168*dfe94b16Srobert   c.OpaquePointers = config->opaquePointers;
169ece8a530Spatrick 
170ece8a530Spatrick   if (config->emitLLVM) {
171ece8a530Spatrick     c.PostInternalizeModuleHook = [](size_t task, const Module &m) {
1721cf9926bSpatrick       if (std::unique_ptr<raw_fd_ostream> os =
1731cf9926bSpatrick               openLTOOutputFile(config->outputFile))
174ece8a530Spatrick         WriteBitcodeToFile(m, *os, false);
175ece8a530Spatrick       return false;
176ece8a530Spatrick     };
177ece8a530Spatrick   }
178ece8a530Spatrick 
179*dfe94b16Srobert   if (config->ltoEmitAsm) {
180bb684c34Spatrick     c.CGFileType = CGFT_AssemblyFile;
181*dfe94b16Srobert     c.Options.MCOptions.AsmVerbose = true;
182*dfe94b16Srobert   }
183bb684c34Spatrick 
184*dfe94b16Srobert   if (!config->saveTempsArgs.empty())
185ece8a530Spatrick     checkError(c.addSaveTemps(config->outputFile.str() + ".",
186*dfe94b16Srobert                               /*UseInputModulePath*/ true,
187*dfe94b16Srobert                               config->saveTempsArgs));
188ece8a530Spatrick   return c;
189ece8a530Spatrick }
190ece8a530Spatrick 
BitcodeCompiler()191ece8a530Spatrick BitcodeCompiler::BitcodeCompiler() {
192ece8a530Spatrick   // Initialize indexFile.
193ece8a530Spatrick   if (!config->thinLTOIndexOnlyArg.empty())
194ece8a530Spatrick     indexFile = openFile(config->thinLTOIndexOnlyArg);
195ece8a530Spatrick 
196ece8a530Spatrick   // Initialize ltoObj.
197ece8a530Spatrick   lto::ThinBackend backend;
198ece8a530Spatrick   auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
199*dfe94b16Srobert   if (config->thinLTOIndexOnly) {
200ece8a530Spatrick     backend = lto::createWriteIndexesThinBackend(
201bb684c34Spatrick         std::string(config->thinLTOPrefixReplace.first),
202bb684c34Spatrick         std::string(config->thinLTOPrefixReplace.second),
203ece8a530Spatrick         config->thinLTOEmitImportsFiles, indexFile.get(), onIndexWrite);
204bb684c34Spatrick   } else {
205bb684c34Spatrick     backend = lto::createInProcessThinBackend(
206*dfe94b16Srobert         llvm::heavyweight_hardware_concurrency(config->thinLTOJobs),
207*dfe94b16Srobert         onIndexWrite, config->thinLTOEmitIndexFiles,
208*dfe94b16Srobert         config->thinLTOEmitImportsFiles);
209ece8a530Spatrick   }
210ece8a530Spatrick 
211ece8a530Spatrick   ltoObj = std::make_unique<lto::LTO>(createConfig(), backend,
212ece8a530Spatrick                                        config->ltoPartitions);
213ece8a530Spatrick 
214ece8a530Spatrick   // Initialize usedStartStop.
215*dfe94b16Srobert   if (ctx.bitcodeFiles.empty())
216*dfe94b16Srobert     return;
217*dfe94b16Srobert   for (Symbol *sym : symtab.getSymbols()) {
218*dfe94b16Srobert     if (sym->isPlaceholder())
219*dfe94b16Srobert       continue;
220ece8a530Spatrick     StringRef s = sym->getName();
221ece8a530Spatrick     for (StringRef prefix : {"__start_", "__stop_"})
222ece8a530Spatrick       if (s.startswith(prefix))
223ece8a530Spatrick         usedStartStop.insert(s.substr(prefix.size()));
224ece8a530Spatrick   }
225ece8a530Spatrick }
226ece8a530Spatrick 
227ece8a530Spatrick BitcodeCompiler::~BitcodeCompiler() = default;
228ece8a530Spatrick 
add(BitcodeFile & f)229ece8a530Spatrick void BitcodeCompiler::add(BitcodeFile &f) {
230ece8a530Spatrick   lto::InputFile &obj = *f.obj;
231ece8a530Spatrick   bool isExec = !config->shared && !config->relocatable;
232ece8a530Spatrick 
233*dfe94b16Srobert   if (config->thinLTOEmitIndexFiles)
234ece8a530Spatrick     thinIndices.insert(obj.getName());
235ece8a530Spatrick 
236ece8a530Spatrick   ArrayRef<Symbol *> syms = f.getSymbols();
237ece8a530Spatrick   ArrayRef<lto::InputFile::Symbol> objSyms = obj.symbols();
238ece8a530Spatrick   std::vector<lto::SymbolResolution> resols(syms.size());
239ece8a530Spatrick 
240ece8a530Spatrick   // Provide a resolution to the LTO API for each symbol.
241ece8a530Spatrick   for (size_t i = 0, e = syms.size(); i != e; ++i) {
242ece8a530Spatrick     Symbol *sym = syms[i];
243ece8a530Spatrick     const lto::InputFile::Symbol &objSym = objSyms[i];
244ece8a530Spatrick     lto::SymbolResolution &r = resols[i];
245ece8a530Spatrick 
246ece8a530Spatrick     // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
247ece8a530Spatrick     // reports two symbols for module ASM defined. Without this check, lld
248ece8a530Spatrick     // flags an undefined in IR with a definition in ASM as prevailing.
249ece8a530Spatrick     // Once IRObjectFile is fixed to report only one symbol this hack can
250ece8a530Spatrick     // be removed.
251ece8a530Spatrick     r.Prevailing = !objSym.isUndefined() && sym->file == &f;
252ece8a530Spatrick 
253ece8a530Spatrick     // We ask LTO to preserve following global symbols:
254ece8a530Spatrick     // 1) All symbols when doing relocatable link, so that them can be used
255ece8a530Spatrick     //    for doing final link.
256ece8a530Spatrick     // 2) Symbols that are used in regular objects.
257ece8a530Spatrick     // 3) C named sections if we have corresponding __start_/__stop_ symbol.
258*dfe94b16Srobert     // 4) Symbols that are defined in bitcode files and used for dynamic
259*dfe94b16Srobert     //    linking.
260*dfe94b16Srobert     // 5) Symbols that will be referenced after linker wrapping is performed.
261ece8a530Spatrick     r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj ||
262*dfe94b16Srobert                             sym->referencedAfterWrap ||
263ece8a530Spatrick                             (r.Prevailing && sym->includeInDynsym()) ||
264ece8a530Spatrick                             usedStartStop.count(objSym.getSectionName());
2651cf9926bSpatrick     // Identify symbols exported dynamically, and that therefore could be
2661cf9926bSpatrick     // referenced by a shared library not visible to the linker.
267*dfe94b16Srobert     r.ExportDynamic =
268*dfe94b16Srobert         sym->computeBinding() != STB_LOCAL &&
269*dfe94b16Srobert         (config->exportDynamic || sym->exportDynamic || sym->inDynamicList);
270ece8a530Spatrick     const auto *dr = dyn_cast<Defined>(sym);
271ece8a530Spatrick     r.FinalDefinitionInLinkageUnit =
272*dfe94b16Srobert         (isExec || sym->visibility() != STV_DEFAULT) && dr &&
273ece8a530Spatrick         // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
274ece8a530Spatrick         // will be generated by for them, triggering linker errors.
275ece8a530Spatrick         // Symbol section is always null for bitcode symbols, hence the check
276ece8a530Spatrick         // for isElf(). Skip linker script defined symbols as well: they have
277ece8a530Spatrick         // no File defined.
278ece8a530Spatrick         !(dr->section == nullptr && (!sym->file || sym->file->isElf()));
279ece8a530Spatrick 
280ece8a530Spatrick     if (r.Prevailing)
281*dfe94b16Srobert       Undefined(nullptr, StringRef(), STB_GLOBAL, STV_DEFAULT, sym->type)
282*dfe94b16Srobert           .overwrite(*sym);
283ece8a530Spatrick 
284ece8a530Spatrick     // We tell LTO to not apply interprocedural optimization for wrapped
285ece8a530Spatrick     // (with --wrap) symbols because otherwise LTO would inline them while
286ece8a530Spatrick     // their values are still not final.
287*dfe94b16Srobert     r.LinkerRedefined = sym->scriptDefined;
288ece8a530Spatrick   }
289ece8a530Spatrick   checkError(ltoObj->add(std::move(f.obj), resols));
290ece8a530Spatrick }
291ece8a530Spatrick 
292ece8a530Spatrick // If LazyObjFile has not been added to link, emit empty index files.
293ece8a530Spatrick // This is needed because this is what GNU gold plugin does and we have a
294ece8a530Spatrick // distributed build system that depends on that behavior.
thinLTOCreateEmptyIndexFiles()295ece8a530Spatrick static void thinLTOCreateEmptyIndexFiles() {
296*dfe94b16Srobert   DenseSet<StringRef> linkedBitCodeFiles;
297*dfe94b16Srobert   for (BitcodeFile *f : ctx.bitcodeFiles)
298*dfe94b16Srobert     linkedBitCodeFiles.insert(f->getName());
299*dfe94b16Srobert 
300*dfe94b16Srobert   for (BitcodeFile *f : ctx.lazyBitcodeFiles) {
301*dfe94b16Srobert     if (!f->lazy)
302ece8a530Spatrick       continue;
303*dfe94b16Srobert     if (linkedBitCodeFiles.contains(f->getName()))
304*dfe94b16Srobert       continue;
305*dfe94b16Srobert     std::string path =
306*dfe94b16Srobert         replaceThinLTOSuffix(getThinLTOOutputFile(f->obj->getName()));
307ece8a530Spatrick     std::unique_ptr<raw_fd_ostream> os = openFile(path + ".thinlto.bc");
308ece8a530Spatrick     if (!os)
309ece8a530Spatrick       continue;
310ece8a530Spatrick 
311ece8a530Spatrick     ModuleSummaryIndex m(/*HaveGVs*/ false);
312ece8a530Spatrick     m.setSkipModuleByDistributedBackend();
313*dfe94b16Srobert     writeIndexToFile(m, *os);
314ece8a530Spatrick     if (config->thinLTOEmitImportsFiles)
315ece8a530Spatrick       openFile(path + ".imports");
316ece8a530Spatrick   }
317ece8a530Spatrick }
318ece8a530Spatrick 
319ece8a530Spatrick // Merge all the bitcode files we have seen, codegen the result
320ece8a530Spatrick // and return the resulting ObjectFile(s).
compile()321ece8a530Spatrick std::vector<InputFile *> BitcodeCompiler::compile() {
322ece8a530Spatrick   unsigned maxTasks = ltoObj->getMaxTasks();
323ece8a530Spatrick   buf.resize(maxTasks);
324ece8a530Spatrick   files.resize(maxTasks);
325ece8a530Spatrick 
326ece8a530Spatrick   // The --thinlto-cache-dir option specifies the path to a directory in which
327ece8a530Spatrick   // to cache native object files for ThinLTO incremental builds. If a path was
328ece8a530Spatrick   // specified, configure LTO to use it as the cache directory.
329*dfe94b16Srobert   FileCache cache;
330ece8a530Spatrick   if (!config->thinLTOCacheDir.empty())
331*dfe94b16Srobert     cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
332*dfe94b16Srobert                              [&](size_t task, const Twine &moduleName,
333*dfe94b16Srobert                                  std::unique_ptr<MemoryBuffer> mb) {
334ece8a530Spatrick                                files[task] = std::move(mb);
335ece8a530Spatrick                              }));
336ece8a530Spatrick 
337*dfe94b16Srobert   if (!ctx.bitcodeFiles.empty())
338ece8a530Spatrick     checkError(ltoObj->run(
339*dfe94b16Srobert         [&](size_t task, const Twine &moduleName) {
340*dfe94b16Srobert           return std::make_unique<CachedFileStream>(
341ece8a530Spatrick               std::make_unique<raw_svector_ostream>(buf[task]));
342ece8a530Spatrick         },
343ece8a530Spatrick         cache));
344ece8a530Spatrick 
345bb684c34Spatrick   // Emit empty index files for non-indexed files but not in single-module mode.
346bb684c34Spatrick   if (config->thinLTOModulesToCompile.empty()) {
347ece8a530Spatrick     for (StringRef s : thinIndices) {
348ece8a530Spatrick       std::string path = getThinLTOOutputFile(s);
349ece8a530Spatrick       openFile(path + ".thinlto.bc");
350ece8a530Spatrick       if (config->thinLTOEmitImportsFiles)
351ece8a530Spatrick         openFile(path + ".imports");
352ece8a530Spatrick     }
353bb684c34Spatrick   }
354ece8a530Spatrick 
355*dfe94b16Srobert   if (config->thinLTOEmitIndexFiles)
356ece8a530Spatrick     thinLTOCreateEmptyIndexFiles();
357ece8a530Spatrick 
358*dfe94b16Srobert   if (config->thinLTOIndexOnly) {
359ece8a530Spatrick     if (!config->ltoObjPath.empty())
360ece8a530Spatrick       saveBuffer(buf[0], config->ltoObjPath);
361ece8a530Spatrick 
362ece8a530Spatrick     // ThinLTO with index only option is required to generate only the index
363ece8a530Spatrick     // files. After that, we exit from linker and ThinLTO backend runs in a
364ece8a530Spatrick     // distributed environment.
365ece8a530Spatrick     if (indexFile)
366ece8a530Spatrick       indexFile->close();
367ece8a530Spatrick     return {};
368ece8a530Spatrick   }
369ece8a530Spatrick 
370ece8a530Spatrick   if (!config->thinLTOCacheDir.empty())
371*dfe94b16Srobert     pruneCache(config->thinLTOCacheDir, config->thinLTOCachePolicy, files);
372ece8a530Spatrick 
373ece8a530Spatrick   if (!config->ltoObjPath.empty()) {
374ece8a530Spatrick     saveBuffer(buf[0], config->ltoObjPath);
375ece8a530Spatrick     for (unsigned i = 1; i != maxTasks; ++i)
376ece8a530Spatrick       saveBuffer(buf[i], config->ltoObjPath + Twine(i));
377ece8a530Spatrick   }
378ece8a530Spatrick 
379*dfe94b16Srobert   if (config->saveTempsArgs.contains("prelink")) {
380bb684c34Spatrick     if (!buf[0].empty())
381ece8a530Spatrick       saveBuffer(buf[0], config->outputFile + ".lto.o");
382ece8a530Spatrick     for (unsigned i = 1; i != maxTasks; ++i)
383ece8a530Spatrick       saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
384ece8a530Spatrick   }
385ece8a530Spatrick 
386bb684c34Spatrick   if (config->ltoEmitAsm) {
387bb684c34Spatrick     saveBuffer(buf[0], config->outputFile);
388bb684c34Spatrick     for (unsigned i = 1; i != maxTasks; ++i)
389bb684c34Spatrick       saveBuffer(buf[i], config->outputFile + Twine(i));
390bb684c34Spatrick     return {};
391bb684c34Spatrick   }
392bb684c34Spatrick 
393ece8a530Spatrick   std::vector<InputFile *> ret;
394ece8a530Spatrick   for (unsigned i = 0; i != maxTasks; ++i)
395ece8a530Spatrick     if (!buf[i].empty())
396*dfe94b16Srobert       ret.push_back(createObjFile(MemoryBufferRef(buf[i], "lto.tmp")));
397ece8a530Spatrick 
398ece8a530Spatrick   for (std::unique_ptr<MemoryBuffer> &file : files)
399ece8a530Spatrick     if (file)
400*dfe94b16Srobert       ret.push_back(createObjFile(*file));
401ece8a530Spatrick   return ret;
402ece8a530Spatrick }
403