LLVM 17.0.0git
LTOBackend.cpp
Go to the documentation of this file.
1//===-LTOBackend.cpp - LLVM Link Time Optimizer Backend -------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the "backend" phase of LTO, i.e. it performs
10// optimization and code generation on a loaded module. It is generally used
11// internally by the LTO class but can also be used independently, for example
12// to implement a standalone ThinLTO backend.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/LTO/LTOBackend.h"
25#include "llvm/IR/PassManager.h"
26#include "llvm/IR/Verifier.h"
27#include "llvm/LTO/LTO.h"
34#include "llvm/Support/Error.h"
37#include "llvm/Support/Path.h"
48#include <optional>
49
50using namespace llvm;
51using namespace lto;
52
53#define DEBUG_TYPE "lto-backend"
54
56 DoNotEmbed = 0,
59};
60
62 "lto-embed-bitcode", cl::init(LTOBitcodeEmbedding::DoNotEmbed),
64 "Do not embed"),
66 "Embed after all optimization passes"),
68 "post-merge-pre-opt",
69 "Embed post merge, but before optimizations")),
70 cl::desc("Embed LLVM bitcode in object files produced by LTO"));
71
73 "thinlto-assume-merged", cl::init(false),
74 cl::desc("Assume the input has already undergone ThinLTO function "
75 "importing and the other pre-optimization pipeline changes."));
76
77namespace llvm {
79}
80
81[[noreturn]] static void reportOpenError(StringRef Path, Twine Msg) {
82 errs() << "failed to open " << Path << ": " << Msg << '\n';
83 errs().flush();
84 exit(1);
85}
86
87Error Config::addSaveTemps(std::string OutputFileName, bool UseInputModulePath,
88 const DenseSet<StringRef> &SaveTempsArgs) {
90
91 std::error_code EC;
92 if (SaveTempsArgs.empty() || SaveTempsArgs.contains("resolution")) {
94 std::make_unique<raw_fd_ostream>(OutputFileName + "resolution.txt", EC,
96 if (EC) {
97 ResolutionFile.reset();
98 return errorCodeToError(EC);
99 }
100 }
101
102 auto setHook = [&](std::string PathSuffix, ModuleHookFn &Hook) {
103 // Keep track of the hook provided by the linker, which also needs to run.
104 ModuleHookFn LinkerHook = Hook;
105 Hook = [=](unsigned Task, const Module &M) {
106 // If the linker's hook returned false, we need to pass that result
107 // through.
108 if (LinkerHook && !LinkerHook(Task, M))
109 return false;
110
111 std::string PathPrefix;
112 // If this is the combined module (not a ThinLTO backend compile) or the
113 // user hasn't requested using the input module's path, emit to a file
114 // named from the provided OutputFileName with the Task ID appended.
115 if (M.getModuleIdentifier() == "ld-temp.o" || !UseInputModulePath) {
116 PathPrefix = OutputFileName;
117 if (Task != (unsigned)-1)
118 PathPrefix += utostr(Task) + ".";
119 } else
120 PathPrefix = M.getModuleIdentifier() + ".";
121 std::string Path = PathPrefix + PathSuffix + ".bc";
122 std::error_code EC;
124 // Because -save-temps is a debugging feature, we report the error
125 // directly and exit.
126 if (EC)
127 reportOpenError(Path, EC.message());
128 WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false);
129 return true;
130 };
131 };
132
133 auto SaveCombinedIndex =
134 [=](const ModuleSummaryIndex &Index,
135 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
136 std::string Path = OutputFileName + "index.bc";
137 std::error_code EC;
139 // Because -save-temps is a debugging feature, we report the error
140 // directly and exit.
141 if (EC)
142 reportOpenError(Path, EC.message());
144
145 Path = OutputFileName + "index.dot";
147 if (EC)
148 reportOpenError(Path, EC.message());
149 Index.exportToDot(OSDot, GUIDPreservedSymbols);
150 return true;
151 };
152
153 if (SaveTempsArgs.empty()) {
154 setHook("0.preopt", PreOptModuleHook);
155 setHook("1.promote", PostPromoteModuleHook);
156 setHook("2.internalize", PostInternalizeModuleHook);
157 setHook("3.import", PostImportModuleHook);
158 setHook("4.opt", PostOptModuleHook);
159 setHook("5.precodegen", PreCodeGenModuleHook);
160 CombinedIndexHook = SaveCombinedIndex;
161 } else {
162 if (SaveTempsArgs.contains("preopt"))
163 setHook("0.preopt", PreOptModuleHook);
164 if (SaveTempsArgs.contains("promote"))
165 setHook("1.promote", PostPromoteModuleHook);
166 if (SaveTempsArgs.contains("internalize"))
167 setHook("2.internalize", PostInternalizeModuleHook);
168 if (SaveTempsArgs.contains("import"))
169 setHook("3.import", PostImportModuleHook);
170 if (SaveTempsArgs.contains("opt"))
171 setHook("4.opt", PostOptModuleHook);
172 if (SaveTempsArgs.contains("precodegen"))
173 setHook("5.precodegen", PreCodeGenModuleHook);
174 if (SaveTempsArgs.contains("combinedindex"))
175 CombinedIndexHook = SaveCombinedIndex;
176 }
177
178 return Error::success();
179}
180
181#define HANDLE_EXTENSION(Ext) \
182 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
183#include "llvm/Support/Extension.def"
184
186 PassBuilder &PB) {
187#define HANDLE_EXTENSION(Ext) \
188 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
189#include "llvm/Support/Extension.def"
190
191 // Load requested pass plugins and let them register pass builder callbacks
192 for (auto &PluginFN : PassPlugins) {
193 auto PassPlugin = PassPlugin::Load(PluginFN);
194 if (!PassPlugin) {
195 errs() << "Failed to load passes from '" << PluginFN
196 << "'. Request ignored.\n";
197 continue;
198 }
199
201 }
202}
203
204static std::unique_ptr<TargetMachine>
205createTargetMachine(const Config &Conf, const Target *TheTarget, Module &M) {
206 StringRef TheTriple = M.getTargetTriple();
207 SubtargetFeatures Features;
208 Features.getDefaultSubtargetFeatures(Triple(TheTriple));
209 for (const std::string &A : Conf.MAttrs)
210 Features.AddFeature(A);
211
212 std::optional<Reloc::Model> RelocModel;
213 if (Conf.RelocModel)
214 RelocModel = *Conf.RelocModel;
215 else if (M.getModuleFlag("PIC Level"))
216 RelocModel =
217 M.getPICLevel() == PICLevel::NotPIC ? Reloc::Static : Reloc::PIC_;
218
219 std::optional<CodeModel::Model> CodeModel;
220 if (Conf.CodeModel)
221 CodeModel = *Conf.CodeModel;
222 else
223 CodeModel = M.getCodeModel();
224
225 std::unique_ptr<TargetMachine> TM(TheTarget->createTargetMachine(
226 TheTriple, Conf.CPU, Features.getString(), Conf.Options, RelocModel,
227 CodeModel, Conf.CGOptLevel));
228 assert(TM && "Failed to create target machine");
229 return TM;
230}
231
232static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
233 unsigned OptLevel, bool IsThinLTO,
234 ModuleSummaryIndex *ExportSummary,
235 const ModuleSummaryIndex *ImportSummary) {
236 auto FS = vfs::getRealFileSystem();
237 std::optional<PGOOptions> PGOOpt;
238 if (!Conf.SampleProfile.empty())
239 PGOOpt = PGOOptions(Conf.SampleProfile, "", Conf.ProfileRemapping, FS,
241 else if (Conf.RunCSIRInstr) {
242 PGOOpt = PGOOptions("", Conf.CSIRProfile, Conf.ProfileRemapping, FS,
244 Conf.AddFSDiscriminator);
245 } else if (!Conf.CSIRProfile.empty()) {
246 PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping, FS,
248 Conf.AddFSDiscriminator);
250 } else if (Conf.AddFSDiscriminator) {
251 PGOOpt = PGOOptions("", "", "", nullptr, PGOOptions::NoAction,
253 }
254 TM->setPGOOption(PGOOpt);
255
260
263 SI.registerCallbacks(PIC, &MAM);
264 PassBuilder PB(TM, Conf.PTO, PGOOpt, &PIC);
265
267
268 std::unique_ptr<TargetLibraryInfoImpl> TLII(
269 new TargetLibraryInfoImpl(Triple(TM->getTargetTriple())));
270 if (Conf.Freestanding)
271 TLII->disableAllFunctions();
272 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
273
274 // Parse a custom AA pipeline if asked to.
275 if (!Conf.AAPipeline.empty()) {
276 AAManager AA;
277 if (auto Err = PB.parseAAPipeline(AA, Conf.AAPipeline)) {
278 report_fatal_error(Twine("unable to parse AA pipeline description '") +
279 Conf.AAPipeline + "': " + toString(std::move(Err)));
280 }
281 // Register the AA manager first so that our version is the one used.
282 FAM.registerPass([&] { return std::move(AA); });
283 }
284
285 // Register all the basic analyses with the managers.
291
293
294 if (!Conf.DisableVerify)
296
298
299 switch (OptLevel) {
300 default:
301 llvm_unreachable("Invalid optimization level");
302 case 0:
304 break;
305 case 1:
307 break;
308 case 2:
310 break;
311 case 3:
313 break;
314 }
315
316 // Parse a custom pipeline if asked to.
317 if (!Conf.OptPipeline.empty()) {
318 if (auto Err = PB.parsePassPipeline(MPM, Conf.OptPipeline)) {
319 report_fatal_error(Twine("unable to parse pass pipeline description '") +
320 Conf.OptPipeline + "': " + toString(std::move(Err)));
321 }
322 } else if (Conf.UseDefaultPipeline) {
324 } else if (IsThinLTO) {
325 MPM.addPass(PB.buildThinLTODefaultPipeline(OL, ImportSummary));
326 } else {
327 MPM.addPass(PB.buildLTODefaultPipeline(OL, ExportSummary));
328 }
329
330 if (!Conf.DisableVerify)
332
333 MPM.run(Mod, MAM);
334}
335
336bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
337 bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
338 const ModuleSummaryIndex *ImportSummary,
339 const std::vector<uint8_t> &CmdArgs) {
340 if (EmbedBitcode == LTOBitcodeEmbedding::EmbedPostMergePreOptimized) {
341 // FIXME: the motivation for capturing post-merge bitcode and command line
342 // is replicating the compilation environment from bitcode, without needing
343 // to understand the dependencies (the functions to be imported). This
344 // assumes a clang - based invocation, case in which we have the command
345 // line.
346 // It's not very clear how the above motivation would map in the
347 // linker-based case, so we currently don't plumb the command line args in
348 // that case.
349 if (CmdArgs.empty())
351 dbgs() << "Post-(Thin)LTO merge bitcode embedding was requested, but "
352 "command line arguments are not available");
354 /*EmbedBitcode*/ true, /*EmbedCmdline*/ true,
355 /*Cmdline*/ CmdArgs);
356 }
357 // FIXME: Plumb the combined index into the new pass manager.
358 runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
359 ImportSummary);
360 return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
361}
362
363static void codegen(const Config &Conf, TargetMachine *TM,
364 AddStreamFn AddStream, unsigned Task, Module &Mod,
365 const ModuleSummaryIndex &CombinedIndex) {
366 if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod))
367 return;
368
369 if (EmbedBitcode == LTOBitcodeEmbedding::EmbedOptimized)
371 /*EmbedBitcode*/ true,
372 /*EmbedCmdline*/ false,
373 /*CmdArgs*/ std::vector<uint8_t>());
374
375 std::unique_ptr<ToolOutputFile> DwoOut;
377 if (!Conf.DwoDir.empty()) {
378 std::error_code EC;
379 if (auto EC = llvm::sys::fs::create_directories(Conf.DwoDir))
380 report_fatal_error(Twine("Failed to create directory ") + Conf.DwoDir +
381 ": " + EC.message());
382
383 DwoFile = Conf.DwoDir;
384 sys::path::append(DwoFile, std::to_string(Task) + ".dwo");
385 TM->Options.MCOptions.SplitDwarfFile = std::string(DwoFile);
386 } else
387 TM->Options.MCOptions.SplitDwarfFile = Conf.SplitDwarfFile;
388
389 if (!DwoFile.empty()) {
390 std::error_code EC;
391 DwoOut = std::make_unique<ToolOutputFile>(DwoFile, EC, sys::fs::OF_None);
392 if (EC)
393 report_fatal_error(Twine("Failed to open ") + DwoFile + ": " +
394 EC.message());
395 }
396
398 AddStream(Task, Mod.getModuleIdentifier());
399 if (Error Err = StreamOrErr.takeError())
400 report_fatal_error(std::move(Err));
401 std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
402 TM->Options.ObjectFilenameForDebug = Stream->ObjectPathName;
403
404 legacy::PassManager CodeGenPasses;
405 TargetLibraryInfoImpl TLII(Triple(Mod.getTargetTriple()));
406 CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
407 CodeGenPasses.add(
409 if (Conf.PreCodeGenPassesHook)
410 Conf.PreCodeGenPassesHook(CodeGenPasses);
411 if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,
412 DwoOut ? &DwoOut->os() : nullptr,
413 Conf.CGFileType))
414 report_fatal_error("Failed to setup codegen");
415 CodeGenPasses.run(Mod);
416
417 if (DwoOut)
418 DwoOut->keep();
419}
420
421static void splitCodeGen(const Config &C, TargetMachine *TM,
422 AddStreamFn AddStream,
423 unsigned ParallelCodeGenParallelismLevel, Module &Mod,
424 const ModuleSummaryIndex &CombinedIndex) {
425 ThreadPool CodegenThreadPool(
426 heavyweight_hardware_concurrency(ParallelCodeGenParallelismLevel));
427 unsigned ThreadCount = 0;
428 const Target *T = &TM->getTarget();
429
431 Mod, ParallelCodeGenParallelismLevel,
432 [&](std::unique_ptr<Module> MPart) {
433 // We want to clone the module in a new context to multi-thread the
434 // codegen. We do it by serializing partition modules to bitcode
435 // (while still on the main thread, in order to avoid data races) and
436 // spinning up new threads which deserialize the partitions into
437 // separate contexts.
438 // FIXME: Provide a more direct way to do this in LLVM.
440 raw_svector_ostream BCOS(BC);
441 WriteBitcodeToFile(*MPart, BCOS);
442
443 // Enqueue the task
444 CodegenThreadPool.async(
445 [&](const SmallString<0> &BC, unsigned ThreadId) {
446 LTOLLVMContext Ctx(C);
448 MemoryBufferRef(StringRef(BC.data(), BC.size()), "ld-temp.o"),
449 Ctx);
450 if (!MOrErr)
451 report_fatal_error("Failed to read bitcode");
452 std::unique_ptr<Module> MPartInCtx = std::move(MOrErr.get());
453
454 std::unique_ptr<TargetMachine> TM =
455 createTargetMachine(C, T, *MPartInCtx);
456
457 codegen(C, TM.get(), AddStream, ThreadId, *MPartInCtx,
458 CombinedIndex);
459 },
460 // Pass BC using std::move to ensure that it get moved rather than
461 // copied into the thread's context.
462 std::move(BC), ThreadCount++);
463 },
464 false);
465
466 // Because the inner lambda (which runs in a worker thread) captures our local
467 // variables, we need to wait for the worker threads to terminate before we
468 // can leave the function scope.
469 CodegenThreadPool.wait();
470}
471
473 Module &Mod) {
474 if (!C.OverrideTriple.empty())
475 Mod.setTargetTriple(C.OverrideTriple);
476 else if (Mod.getTargetTriple().empty())
477 Mod.setTargetTriple(C.DefaultTriple);
478
479 std::string Msg;
480 const Target *T = TargetRegistry::lookupTarget(Mod.getTargetTriple(), Msg);
481 if (!T)
482 return make_error<StringError>(Msg, inconvertibleErrorCode());
483 return T;
484}
485
487 std::unique_ptr<ToolOutputFile> DiagOutputFile) {
488 // Make sure we flush the diagnostic remarks file in case the linker doesn't
489 // call the global destructors before exiting.
490 if (!DiagOutputFile)
491 return Error::success();
492 DiagOutputFile->keep();
493 DiagOutputFile->os().flush();
494 return Error::success();
495}
496
498 unsigned ParallelCodeGenParallelismLevel, Module &Mod,
499 ModuleSummaryIndex &CombinedIndex) {
501 if (!TOrErr)
502 return TOrErr.takeError();
503
504 std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, Mod);
505
506 if (!C.CodeGenOnly) {
507 if (!opt(C, TM.get(), 0, Mod, /*IsThinLTO=*/false,
508 /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
509 /*CmdArgs*/ std::vector<uint8_t>()))
510 return Error::success();
511 }
512
513 if (ParallelCodeGenParallelismLevel == 1) {
514 codegen(C, TM.get(), AddStream, 0, Mod, CombinedIndex);
515 } else {
516 splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, Mod,
517 CombinedIndex);
518 }
519 return Error::success();
520}
521
522static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals,
523 const ModuleSummaryIndex &Index) {
524 std::vector<GlobalValue*> DeadGVs;
525 for (auto &GV : Mod.global_values())
526 if (GlobalValueSummary *GVS = DefinedGlobals.lookup(GV.getGUID()))
527 if (!Index.isGlobalValueLive(GVS)) {
528 DeadGVs.push_back(&GV);
530 }
531
532 // Now that all dead bodies have been dropped, delete the actual objects
533 // themselves when possible.
534 for (GlobalValue *GV : DeadGVs) {
535 GV->removeDeadConstantUsers();
536 // Might reference something defined in native object (i.e. dropped a
537 // non-prevailing IR def, but we need to keep the declaration).
538 if (GV->use_empty())
539 GV->eraseFromParent();
540 }
541}
542
543Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
544 Module &Mod, const ModuleSummaryIndex &CombinedIndex,
545 const FunctionImporter::ImportMapTy &ImportList,
546 const GVSummaryMapTy &DefinedGlobals,
548 const std::vector<uint8_t> &CmdArgs) {
550 if (!TOrErr)
551 return TOrErr.takeError();
552
553 std::unique_ptr<TargetMachine> TM = createTargetMachine(Conf, *TOrErr, Mod);
554
555 // Setup optimization remarks.
556 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
557 Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
559 Task);
560 if (!DiagFileOrErr)
561 return DiagFileOrErr.takeError();
562 auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
563
564 // Set the partial sample profile ratio in the profile summary module flag of
565 // the module, if applicable.
566 Mod.setPartialSampleProfileRatio(CombinedIndex);
567
569
570 if (Conf.CodeGenOnly) {
571 codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
572 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
573 }
574
575 if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
576 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
577
578 auto OptimizeAndCodegen =
579 [&](Module &Mod, TargetMachine *TM,
580 std::unique_ptr<ToolOutputFile> DiagnosticOutputFile) {
581 if (!opt(Conf, TM, Task, Mod, /*IsThinLTO=*/true,
582 /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
583 CmdArgs))
584 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
585
586 codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);
587 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
588 };
589
591 return OptimizeAndCodegen(Mod, TM.get(), std::move(DiagnosticOutputFile));
592
593 // When linking an ELF shared object, dso_local should be dropped. We
594 // conservatively do this for -fpic.
595 bool ClearDSOLocalOnDeclarations =
596 TM->getTargetTriple().isOSBinFormatELF() &&
597 TM->getRelocationModel() != Reloc::Static &&
598 Mod.getPIELevel() == PIELevel::Default;
599 renameModuleForThinLTO(Mod, CombinedIndex, ClearDSOLocalOnDeclarations);
600
601 dropDeadSymbols(Mod, DefinedGlobals, CombinedIndex);
602
603 thinLTOFinalizeInModule(Mod, DefinedGlobals, /*PropagateAttrs=*/true);
604
605 if (Conf.PostPromoteModuleHook && !Conf.PostPromoteModuleHook(Task, Mod))
606 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
607
608 if (!DefinedGlobals.empty())
609 thinLTOInternalizeModule(Mod, DefinedGlobals);
610
611 if (Conf.PostInternalizeModuleHook &&
612 !Conf.PostInternalizeModuleHook(Task, Mod))
613 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
614
615 auto ModuleLoader = [&](StringRef Identifier) {
616 assert(Mod.getContext().isODRUniquingDebugTypes() &&
617 "ODR Type uniquing should be enabled on the context");
618 if (ModuleMap) {
619 auto I = ModuleMap->find(Identifier);
620 assert(I != ModuleMap->end());
621 return I->second.getLazyModule(Mod.getContext(),
622 /*ShouldLazyLoadMetadata=*/true,
623 /*IsImporting*/ true);
624 }
625
627 llvm::MemoryBuffer::getFile(Identifier);
628 if (!MBOrErr)
629 return Expected<std::unique_ptr<llvm::Module>>(make_error<StringError>(
630 Twine("Error loading imported file ") + Identifier + " : ",
631 MBOrErr.getError()));
632
633 Expected<BitcodeModule> BMOrErr = findThinLTOModule(**MBOrErr);
634 if (!BMOrErr)
635 return Expected<std::unique_ptr<llvm::Module>>(make_error<StringError>(
636 Twine("Error loading imported file ") + Identifier + " : " +
637 toString(BMOrErr.takeError()),
639
641 BMOrErr->getLazyModule(Mod.getContext(),
642 /*ShouldLazyLoadMetadata=*/true,
643 /*IsImporting*/ true);
644 if (MOrErr)
645 (*MOrErr)->setOwnedMemoryBuffer(std::move(*MBOrErr));
646 return MOrErr;
647 };
648
649 FunctionImporter Importer(CombinedIndex, ModuleLoader,
650 ClearDSOLocalOnDeclarations);
651 if (Error Err = Importer.importFunctions(Mod, ImportList).takeError())
652 return Err;
653
654 if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
655 return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
656
657 return OptimizeAndCodegen(Mod, TM.get(), std::move(DiagnosticOutputFile));
658}
659
661 if (ThinLTOAssumeMerged && BMs.size() == 1)
662 return BMs.begin();
663
664 for (BitcodeModule &BM : BMs) {
665 Expected<BitcodeLTOInfo> LTOInfo = BM.getLTOInfo();
666 if (LTOInfo && LTOInfo->IsThinLTO)
667 return &BM;
668 }
669 return nullptr;
670}
671
674 if (!BMsOrErr)
675 return BMsOrErr.takeError();
676
677 // The bitcode file may contain multiple modules, we want the one that is
678 // marked as being the ThinLTO module.
679 if (const BitcodeModule *Bm = lto::findThinLTOModule(*BMsOrErr))
680 return *Bm;
681
682 return make_error<StringError>("Could not find module summary",
684}
685
687 const ModuleSummaryIndex &CombinedIndex,
688 FunctionImporter::ImportMapTy &ImportList) {
690 return true;
691 // We can simply import the values mentioned in the combined index, since
692 // we should only invoke this using the individual indexes written out
693 // via a WriteIndexesThinBackend.
694 for (const auto &GlobalList : CombinedIndex) {
695 // Ignore entries for undefined references.
696 if (GlobalList.second.SummaryList.empty())
697 continue;
698
699 auto GUID = GlobalList.first;
700 for (const auto &Summary : GlobalList.second.SummaryList) {
701 // Skip the summaries for the importing module. These are included to
702 // e.g. record required linkage changes.
703 if (Summary->modulePath() == M.getModuleIdentifier())
704 continue;
705 // Add an entry to provoke importing by thinBackend.
706 ImportList[Summary->modulePath()].insert(GUID);
707 }
708 }
709 return true;
710}
arm prera ldst opt
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This header provides classes for managing passes over SCCs of the call graph.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:678
#define LLVM_DEBUG(X)
Definition: Debug.h:101
static cl::opt< bool > ThinLTOAssumeMerged("thinlto-assume-merged", cl::init(false), cl::desc("Assume the input has already undergone ThinLTO function " "importing and the other pre-optimization pipeline changes."))
static void reportOpenError(StringRef Path, Twine Msg)
Definition: LTOBackend.cpp:81
LTOBitcodeEmbedding
Definition: LTOBackend.cpp:55
static cl::opt< LTOBitcodeEmbedding > EmbedBitcode("lto-embed-bitcode", cl::init(LTOBitcodeEmbedding::DoNotEmbed), cl::values(clEnumValN(LTOBitcodeEmbedding::DoNotEmbed, "none", "Do not embed"), clEnumValN(LTOBitcodeEmbedding::EmbedOptimized, "optimized", "Embed after all optimization passes"), clEnumValN(LTOBitcodeEmbedding::EmbedPostMergePreOptimized, "post-merge-pre-opt", "Embed post merge, but before optimizations")), cl::desc("Embed LLVM bitcode in object files produced by LTO"))
static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, const ModuleSummaryIndex &Index)
Definition: LTOBackend.cpp:522
static Expected< const Target * > initAndLookupTarget(const Config &C, Module &Mod)
Definition: LTOBackend.cpp:472
static void codegen(const Config &Conf, TargetMachine *TM, AddStreamFn AddStream, unsigned Task, Module &Mod, const ModuleSummaryIndex &CombinedIndex)
Definition: LTOBackend.cpp:363
static void RegisterPassPlugins(ArrayRef< std::string > PassPlugins, PassBuilder &PB)
Definition: LTOBackend.cpp:185
static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM, unsigned OptLevel, bool IsThinLTO, ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary)
Definition: LTOBackend.cpp:232
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
#define I(x, y, z)
Definition: MD5.cpp:58
This is the interface to build a ModuleSummaryIndex for a module.
static std::unique_ptr< TargetMachine > createTargetMachine(Function *F, CodeGenOpt::Level OptLevel)
Create the TargetMachine object to query the backend for optimization preferences.
CGSCCAnalysisManager CGAM
ModulePassManager MPM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const char LLVMTargetMachineRef TM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines various interfaces for pass management in LLVM.
@ SI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This header defines a class that provides bookkeeping for all standard (i.e in-tree) pass instrumenta...
Defines the virtual file system interface vfs::FileSystem.
A manager for alias analyses.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:836
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
Represents a module in a bitcode file.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:202
bool empty() const
Definition: DenseMap.h:98
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Represents either an error or a value T.
Definition: ErrorOr.h:56
std::error_code getError() const
Definition: ErrorOr.h:153
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
The function importer is automatically importing function from other modules based on the provided su...
Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
Function and variable summary information to aid decisions and implementation of importing.
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
iterator end()
Definition: MapVector.h:72
iterator find(const KeyT &Key)
Definition: MapVector.h:147
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
Class to hold module path string table and global value map, and encapsulate methods for operating on...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:305
iterator begin() const
Definition: ArrayRef.h:354
static const OptimizationLevel O3
Optimize for fast execution as much as possible.
static const OptimizationLevel O0
Disable as many optimizations as possible.
static const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
Definition: PassBuilder.h:100
Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM)
Cross register the analysis managers through their proxies.
ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level, bool LTOPreLink=false)
Build a per-module default optimization pipeline.
Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level, ModuleSummaryIndex *ExportSummary)
Build an LTO default optimization pipeline to a pass manager.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build an ThinLTO default optimization pipeline to a pass manager.
void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same< PassT, PassManager >::value > addPass(PassT &&Pass)
Definition: PassManager.h:544
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Definition: PassManager.h:498
A loaded pass plugin.
Definition: PassPlugin.h:60
static Expected< PassPlugin > Load(const std::string &Filename)
Attempts to load a pass plugin from a given file.
Definition: PassPlugin.cpp:16
void registerPassBuilderCallbacks(PassBuilder &PB) const
Invoke the PassBuilder callback registration.
Definition: PassPlugin.h:82
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:289
This class provides an interface to register all the standard pass instrumentations and manages their...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:286
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Manages the enabling and disabling of subtarget specific features.
void getDefaultSubtargetFeatures(const Triple &Triple)
Adds the default features for the specified target triple.
std::string getString() const
Returns features as a string.
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
Analysis pass providing the TargetLibraryInfo.
Implementation of the target library information.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
Target - Wrapper for Target specific information.
TargetMachine * createTargetMachine(StringRef TT, StringRef CPU, StringRef Features, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM=std::nullopt, CodeGenOpt::Level OL=CodeGenOpt::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
A ThreadPool for asynchronous parallel execution on a defined number of threads.
Definition: ThreadPool.h:52
void wait()
Blocking wait for all the threads to complete and the queue to be empty.
Definition: ThreadPool.cpp:202
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition: ThreadPool.h:66
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Create a verifier pass.
Definition: Verifier.h:132
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:185
PassManager manages ModulePassManagers.
void add(Pass *P) override
Add a pass to the queue of passes to run.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:454
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
Interfaces for registering analysis passes, producing common pass manager configurations,...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:703
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, Module &M, const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector< StringRef, BitcodeModule > *ModuleMap, const std::vector< uint8_t > &CmdArgs=std::vector< uint8_t >())
Runs a ThinLTO backend.
Definition: LTOBackend.cpp:543
BitcodeModule * findThinLTOModule(MutableArrayRef< BitcodeModule > BMs)
Returns the BitcodeModule that is ThinLTO.
Definition: LTOBackend.cpp:660
Error backend(const Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, Module &M, ModuleSummaryIndex &CombinedIndex)
Runs a regular LTO backend.
Definition: LTOBackend.cpp:497
Error finalizeOptimizationRemarks(std::unique_ptr< ToolOutputFile > DiagOutputFile)
Definition: LTOBackend.cpp:486
bool initImportList(const Module &M, const ModuleSummaryIndex &CombinedIndex, FunctionImporter::ImportMapTy &ImportList)
Distributed ThinLTO: collect the referenced modules based on module summary and initialize ImportList...
Definition: LTOBackend.cpp:686
Expected< std::unique_ptr< ToolOutputFile > > setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::optional< uint64_t > RemarksHotnessThreshold=0, int Count=-1)
Setup optimization remarks.
Definition: LTO.cpp:1656
bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, bool IsThinLTO, ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary, const std::vector< uint8_t > &CmdArgs)
Runs middle-end LTO optimizations on Mod.
Definition: LTOBackend.cpp:336
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition: FileSystem.h:770
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
Definition: Path.cpp:967
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ThreadPoolStrategy heavyweight_hardware_concurrency(unsigned ThreadCount=0)
Returns a thread strategy for tasks requiring significant memory or other resources.
Definition: Threading.h:162
Expected< std::unique_ptr< Module > > parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, ParserCallbacks Callbacks={})
Read the specified bitcode file, returning the module.
void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)
Write the specified module to the specified raw output stream.
cl::opt< bool > NoPGOWarnMismatch
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const std::map< std::string, GVSummaryMapTy > *ModuleToSummariesForIndex=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
std::function< Expected< std::unique_ptr< CachedFileStream > >(unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
Definition: Caching.h:42
bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
void embedBitcodeInModule(Module &M, MemoryBufferRef Buf, bool EmbedBitcode, bool EmbedCmdline, const std::vector< uint8_t > &CmdArgs)
If EmbedBitcode is set, save a copy of the llvm IR as data in the __LLVM,__bitcode section (....
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
Expected< std::vector< BitcodeModule > > getBitcodeModuleList(MemoryBufferRef Buffer)
Returns a list of modules in the specified bitcode buffer.
void splitCodeGen(Module &M, ArrayRef< raw_pwrite_stream * > OSs, ArrayRef< llvm::raw_pwrite_stream * > BCOSs, const std::function< std::unique_ptr< TargetMachine >()> &TMFactory, CodeGenFileType FileType=CGFT_ObjectFile, bool PreserveLocals=false)
Split M into OSs.size() partitions, and generate code for each.
Definition: ParallelCG.cpp:38
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
ImmutablePass * createImmutableModuleSummaryIndexWrapperPass(const ModuleSummaryIndex *Index)
void SplitModule(Module &M, unsigned N, function_ref< void(std::unique_ptr< Module > MPart)> ModuleCallback, bool PreserveLocals=false)
Splits the module M into N linkable partitions.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:92
void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
A struct capturing PGO tunables.
Definition: PGOOptions.h:27
static const Target * lookupTarget(const std::string &Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
LTO configuration.
Definition: Config.h:41
std::function< bool(unsigned Task, const Module &)> ModuleHookFn
The following callbacks deal with tasks, which normally represent the entire optimization and code ge...
Definition: Config.h:215
bool DebugPassManager
Whether to emit the pass manager debuggging informations.
Definition: Config.h:162
bool AddFSDiscriminator
Add FSAFDO discriminators.
Definition: Config.h:180
std::optional< uint64_t > RemarksHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
Definition: Config.h:156
Error addSaveTemps(std::string OutputFileName, bool UseInputModulePath=false, const DenseSet< StringRef > &SaveTempsArgs={})
This is a convenience function that configures this Config object to write temporary files named afte...
Definition: LTOBackend.cpp:87
ModuleHookFn PreOptModuleHook
This module hook is called after linking (regular LTO) or loading (ThinLTO) the module,...
Definition: Config.h:219
CombinedIndexHookFn CombinedIndexHook
Definition: Config.h:251
std::optional< CodeModel::Model > CodeModel
Definition: Config.h:56
std::string AAPipeline
Definition: Config.h:101
std::function< void(legacy::PassManager &)> PreCodeGenPassesHook
For adding passes that run right before codegen.
Definition: Config.h:54
bool CodeGenOnly
Disable entirely the optimizer, including importing for ThinLTO.
Definition: Config.h:70
bool DisableVerify
Definition: Config.h:60
std::vector< std::string > MAttrs
Definition: Config.h:50
PipelineTuningOptions PTO
Tunable parameters for passes in the default pipelines.
Definition: Config.h:189
std::unique_ptr< raw_ostream > ResolutionFile
If this field is set, LTO will write input file paths and symbol resolutions here in llvm-lto2 comman...
Definition: Config.h:186
std::string CPU
Definition: Config.h:48
std::string DwoDir
The directory to store .dwo files.
Definition: Config.h:121
std::string RemarksFilename
Optimization remarks file path.
Definition: Config.h:135
bool UseDefaultPipeline
Use the standard optimization pipeline.
Definition: Config.h:63
ModuleHookFn PostPromoteModuleHook
This hook is called after promoting any internal functions (ThinLTO-specific).
Definition: Config.h:223
std::string ProfileRemapping
Name remapping file for profile data.
Definition: Config.h:118
TargetOptions Options
Definition: Config.h:49
std::string SplitDwarfFile
The name for the split debug info file used for the DW_AT_[GNU_]dwo_name attribute in the skeleton CU...
Definition: Config.h:127
std::string SplitDwarfOutput
The path to write a .dwo file to.
Definition: Config.h:132
CodeGenOpt::Level CGOptLevel
Definition: Config.h:57
ModuleHookFn PostOptModuleHook
This module hook is called after optimization is complete.
Definition: Config.h:232
std::string RemarksPasses
Optimization remarks pass filter.
Definition: Config.h:138
std::string OptPipeline
If this field is set, the set of passes run in the middle-end optimizer will be the one specified by ...
Definition: Config.h:96
bool RunCSIRInstr
Run PGO context sensitive IR instrumentation.
Definition: Config.h:73
ModuleHookFn PostInternalizeModuleHook
This hook is called after internalizing the module.
Definition: Config.h:226
unsigned OptLevel
Definition: Config.h:59
ModuleHookFn PostImportModuleHook
This hook is called after importing from other modules (ThinLTO-specific).
Definition: Config.h:229
bool RemarksWithHotness
Whether to emit optimization remarks with hotness informations.
Definition: Config.h:141
std::vector< std::string > PassPlugins
Definition: Config.h:52
std::string CSIRProfile
Context Sensitive PGO profile path.
Definition: Config.h:112
ModuleHookFn PreCodeGenModuleHook
This module hook is called before code generation.
Definition: Config.h:237
std::optional< Reloc::Model > RelocModel
Definition: Config.h:55
bool ShouldDiscardValueNames
Definition: Config.h:176
bool PGOWarnMismatch
Turn on/off the warning about a hash mismatch in the PGO profile data.
Definition: Config.h:76
CodeGenFileType CGFileType
Definition: Config.h:58
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
Definition: Config.h:67
std::string SampleProfile
Sample PGO profile path.
Definition: Config.h:115
std::string RemarksFormat
The format used for serializing remarks (default: YAML).
Definition: Config.h:159
A derived class of LLVMContext that initializes itself according to a given Config object.
Definition: Config.h:290