LLVM 20.0.0git
ThinLTOCodeGenerator.cpp
Go to the documentation of this file.
1//===-ThinLTOCodeGenerator.cpp - LLVM Link Time Optimizer -----------------===//
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 Thin Link Time Optimization library. This library is
10// intended to be used by linker to optimize code at link time.
11//
12//===----------------------------------------------------------------------===//
13
16
17#include "llvm/ADT/ScopeExit.h"
18#include "llvm/ADT/Statistic.h"
27#include "llvm/Config/llvm-config.h"
28#include "llvm/IR/DebugInfo.h"
30#include "llvm/IR/LLVMContext.h"
33#include "llvm/IR/Mangler.h"
35#include "llvm/IR/Verifier.h"
37#include "llvm/LTO/LTO.h"
44#include "llvm/Support/Debug.h"
45#include "llvm/Support/Error.h"
48#include "llvm/Support/Path.h"
49#include "llvm/Support/SHA1.h"
63
64#include <numeric>
65
66#if !defined(_MSC_VER) && !defined(__MINGW32__)
67#include <unistd.h>
68#else
69#include <io.h>
70#endif
71
72using namespace llvm;
73using namespace ThinLTOCodeGeneratorImpl;
74
75#define DEBUG_TYPE "thinlto"
76
77namespace llvm {
78// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
86}
87
88// Default to using all available threads in the system, but using only one
89// thred per core, as indicated by the usage of
90// heavyweight_hardware_concurrency() below.
91static cl::opt<int> ThreadCount("threads", cl::init(0));
92
93// Simple helper to save temporary files for debug.
94static void saveTempBitcode(const Module &TheModule, StringRef TempDir,
95 unsigned count, StringRef Suffix) {
96 if (TempDir.empty())
97 return;
98 // User asked to save temps, let dump the bitcode file after import.
99 std::string SaveTempPath = (TempDir + llvm::Twine(count) + Suffix).str();
100 std::error_code EC;
101 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
102 if (EC)
103 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
104 " to save optimized bitcode\n");
105 WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true);
106}
107
108static const GlobalValueSummary *
110 // If there is any strong definition anywhere, get it.
111 auto StrongDefForLinker = llvm::find_if(
112 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
113 auto Linkage = Summary->linkage();
116 });
117 if (StrongDefForLinker != GVSummaryList.end())
118 return StrongDefForLinker->get();
119 // Get the first *linker visible* definition for this global in the summary
120 // list.
121 auto FirstDefForLinker = llvm::find_if(
122 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
123 auto Linkage = Summary->linkage();
125 });
126 // Extern templates can be emitted as available_externally.
127 if (FirstDefForLinker == GVSummaryList.end())
128 return nullptr;
129 return FirstDefForLinker->get();
130}
131
132// Populate map of GUID to the prevailing copy for any multiply defined
133// symbols. Currently assume first copy is prevailing, or any strong
134// definition. Can be refined with Linker information in the future.
136 const ModuleSummaryIndex &Index,
138 auto HasMultipleCopies = [&](const GlobalValueSummaryList &GVSummaryList) {
139 return GVSummaryList.size() > 1;
140 };
141
142 for (auto &I : Index) {
143 if (HasMultipleCopies(I.second.SummaryList))
144 PrevailingCopy[I.first] =
145 getFirstDefinitionForLinker(I.second.SummaryList);
146 }
147}
148
150generateModuleMap(std::vector<std::unique_ptr<lto::InputFile>> &Modules) {
152 for (auto &M : Modules) {
153 LLVM_DEBUG(dbgs() << "Adding module " << M->getName() << " to ModuleMap\n");
154 assert(!ModuleMap.contains(M->getName()) &&
155 "Expect unique Buffer Identifier");
156 ModuleMap[M->getName()] = M.get();
157 }
158 return ModuleMap;
159}
160
161static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index,
162 bool ClearDSOLocalOnDeclarations) {
163 renameModuleForThinLTO(TheModule, Index, ClearDSOLocalOnDeclarations);
164}
165
166namespace {
167class ThinLTODiagnosticInfo : public DiagnosticInfo {
168 const Twine &Msg;
169public:
170 ThinLTODiagnosticInfo(const Twine &DiagMsg,
171 DiagnosticSeverity Severity = DS_Error)
172 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
173 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
174};
175}
176
177/// Verify the module and strip broken debug info.
178static void verifyLoadedModule(Module &TheModule) {
179 bool BrokenDebugInfo = false;
180 if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo))
181 report_fatal_error("Broken module found, compilation aborted!");
182 if (BrokenDebugInfo) {
183 TheModule.getContext().diagnose(ThinLTODiagnosticInfo(
184 "Invalid debug info found, debug info will be stripped", DS_Warning));
185 StripDebugInfo(TheModule);
186 }
187}
188
189static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
190 LLVMContext &Context,
191 bool Lazy,
192 bool IsImporting) {
193 auto &Mod = Input->getSingleBitcodeModule();
194 SMDiagnostic Err;
196 Lazy ? Mod.getLazyModule(Context,
197 /* ShouldLazyLoadMetadata */ true, IsImporting)
198 : Mod.parseModule(Context);
199 if (!ModuleOrErr) {
200 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
201 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
202 SourceMgr::DK_Error, EIB.message());
203 Err.print("ThinLTO", errs());
204 });
205 report_fatal_error("Can't load module, abort.");
206 }
207 if (!Lazy)
208 verifyLoadedModule(*ModuleOrErr.get());
209 return std::move(*ModuleOrErr);
210}
211
212static void
215 const FunctionImporter::ImportMapTy &ImportList,
216 bool ClearDSOLocalOnDeclarations) {
217 auto Loader = [&](StringRef Identifier) {
218 auto &Input = ModuleMap[Identifier];
219 return loadModuleFromInput(Input, TheModule.getContext(),
220 /*Lazy=*/true, /*IsImporting*/ true);
221 };
222
223 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
224 Expected<bool> Result = Importer.importFunctions(TheModule, ImportList);
225 if (!Result) {
226 handleAllErrors(Result.takeError(), [&](ErrorInfoBase &EIB) {
227 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
228 SourceMgr::DK_Error, EIB.message());
229 Err.print("ThinLTO", errs());
230 });
231 report_fatal_error("importFunctions failed");
232 }
233 // Verify again after cross-importing.
234 verifyLoadedModule(TheModule);
235}
236
237static void optimizeModule(Module &TheModule, TargetMachine &TM,
238 unsigned OptLevel, bool Freestanding,
239 bool DebugPassManager, ModuleSummaryIndex *Index) {
240 std::optional<PGOOptions> PGOOpt;
245
247 StandardInstrumentations SI(TheModule.getContext(), DebugPassManager);
248 SI.registerCallbacks(PIC, &MAM);
250 PTO.LoopVectorization = true;
251 PTO.SLPVectorization = true;
252 PassBuilder PB(&TM, PTO, PGOOpt, &PIC);
253
254 std::unique_ptr<TargetLibraryInfoImpl> TLII(
255 new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())));
256 if (Freestanding)
257 TLII->disableAllFunctions();
258 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
259
260 // Register all the basic analyses with the managers.
266
268
270
271 switch (OptLevel) {
272 default:
273 llvm_unreachable("Invalid optimization level");
274 case 0:
276 break;
277 case 1:
279 break;
280 case 2:
282 break;
283 case 3:
285 break;
286 }
287
288 MPM.addPass(PB.buildThinLTODefaultPipeline(OL, Index));
289
290 MPM.run(TheModule, MAM);
291}
292
293static void
295 DenseSet<GlobalValue::GUID> &PreservedGUID) {
296 for (const auto &Sym : File.symbols()) {
297 if (Sym.isUsed())
298 PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
299 }
300}
301
302// Convert the PreservedSymbols map from "Name" based to "GUID" based.
305 const Triple &TheTriple,
307 // Iterate the symbols in the input file and if the input has preserved symbol
308 // compute the GUID for the symbol.
309 for (const auto &Sym : File.symbols()) {
310 if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())
312 Sym.getIRName(), GlobalValue::ExternalLinkage, "")));
313 }
314}
315
319 const Triple &TheTriple) {
320 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
322 GUIDPreservedSymbols);
323 return GUIDPreservedSymbols;
324}
325
326static std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
327 TargetMachine &TM) {
329
330 // CodeGen
331 {
334
335 // Setup the codegen now.
336 if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,
337 /* DisableVerify */ true))
338 report_fatal_error("Failed to setup codegen");
339
340 // Run codegen now. resulting binary is in OutputBuffer.
341 PM.run(TheModule);
342 }
343 return std::make_unique<SmallVectorMemoryBuffer>(
344 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
345}
346
347namespace {
348/// Manage caching for a single Module.
349class ModuleCacheEntry {
350 SmallString<128> EntryPath;
351
352public:
353 // Create a cache entry. This compute a unique hash for the Module considering
354 // the current list of export/import, and offer an interface to query to
355 // access the content in the cache.
356 ModuleCacheEntry(
357 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
358 const FunctionImporter::ImportMapTy &ImportList,
359 const FunctionImporter::ExportSetTy &ExportList,
360 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
361 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
362 bool Freestanding, const TargetMachineBuilder &TMBuilder) {
363 if (CachePath.empty())
364 return;
365
366 if (!Index.modulePaths().count(ModuleID))
367 // The module does not have an entry, it can't have a hash at all
368 return;
369
370 if (all_of(Index.getModuleHash(ModuleID),
371 [](uint32_t V) { return V == 0; }))
372 // No hash entry, no caching!
373 return;
374
376 Conf.OptLevel = OptLevel;
377 Conf.Options = TMBuilder.Options;
378 Conf.CPU = TMBuilder.MCpu;
379 Conf.MAttrs.push_back(TMBuilder.MAttr);
380 Conf.RelocModel = TMBuilder.RelocModel;
381 Conf.CGOptLevel = TMBuilder.CGOptLevel;
382 Conf.Freestanding = Freestanding;
383 std::string Key =
384 computeLTOCacheKey(Conf, Index, ModuleID, ImportList, ExportList,
385 ResolvedODR, DefinedGVSummaries);
386
387 // This choice of file name allows the cache to be pruned (see pruneCache()
388 // in include/llvm/Support/CachePruning.h).
389 sys::path::append(EntryPath, CachePath, Twine("llvmcache-", Key));
390 }
391
392 // Access the path to this entry in the cache.
393 StringRef getEntryPath() { return EntryPath; }
394
395 // Try loading the buffer for this cache entry.
396 ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
397 if (EntryPath.empty())
398 return std::error_code();
399 SmallString<64> ResultPath;
401 Twine(EntryPath), sys::fs::OF_UpdateAtime, &ResultPath);
402 if (!FDOrErr)
403 return errorToErrorCode(FDOrErr.takeError());
405 *FDOrErr, EntryPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
406 sys::fs::closeFile(*FDOrErr);
407 return MBOrErr;
408 }
409
410 // Cache the Produced object file
411 void write(const MemoryBuffer &OutputBuffer) {
412 if (EntryPath.empty())
413 return;
414
415 if (auto Err = llvm::writeToOutput(
416 EntryPath, [&OutputBuffer](llvm::raw_ostream &OS) -> llvm::Error {
418 return llvm::Error::success();
419 }))
420 report_fatal_error(llvm::formatv("ThinLTO: Can't write file {0}: {1}",
421 EntryPath,
422 toString(std::move(Err)).c_str()));
423 }
424};
425} // end anonymous namespace
426
427static std::unique_ptr<MemoryBuffer>
430 const FunctionImporter::ImportMapTy &ImportList,
431 const FunctionImporter::ExportSetTy &ExportList,
432 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
433 const GVSummaryMapTy &DefinedGlobals,
434 const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
435 bool DisableCodeGen, StringRef SaveTempsDir,
436 bool Freestanding, unsigned OptLevel, unsigned count,
437 bool DebugPassManager) {
438 // "Benchmark"-like optimization: single-source case
439 bool SingleModule = (ModuleMap.size() == 1);
440
441 // When linking an ELF shared object, dso_local should be dropped. We
442 // conservatively do this for -fpic.
443 bool ClearDSOLocalOnDeclarations =
444 TM.getTargetTriple().isOSBinFormatELF() &&
445 TM.getRelocationModel() != Reloc::Static &&
446 TheModule.getPIELevel() == PIELevel::Default;
447
448 if (!SingleModule) {
449 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
450
451 // Apply summary-based prevailing-symbol resolution decisions.
452 thinLTOFinalizeInModule(TheModule, DefinedGlobals, /*PropagateAttrs=*/true);
453
454 // Save temps: after promotion.
455 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
456 }
457
458 // Be friendly and don't nuke totally the module when the client didn't
459 // supply anything to preserve.
460 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
461 // Apply summary-based internalization decisions.
462 thinLTOInternalizeModule(TheModule, DefinedGlobals);
463 }
464
465 // Save internalized bitcode
466 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
467
468 if (!SingleModule)
469 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
470 ClearDSOLocalOnDeclarations);
471
472 // Do this after any importing so that imported code is updated.
473 // See comment at call to updateVCallVisibilityInIndex() for why
474 // WholeProgramVisibilityEnabledInLTO is false.
476 /* WholeProgramVisibilityEnabledInLTO */ false);
477
478 // Save temps: after cross-module import.
479 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
480
481 optimizeModule(TheModule, TM, OptLevel, Freestanding, DebugPassManager,
482 &Index);
483
484 saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
485
486 if (DisableCodeGen) {
487 // Configured to stop before CodeGen, serialize the bitcode and return.
489 {
491 ProfileSummaryInfo PSI(TheModule);
492 auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI);
493 WriteBitcodeToFile(TheModule, OS, true, &Index);
494 }
495 return std::make_unique<SmallVectorMemoryBuffer>(
496 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
497 }
498
499 return codegenModule(TheModule, TM);
500}
501
502/// Resolve prevailing symbols. Record resolutions in the \p ResolvedODR map
503/// for caching, and in the \p Index for application during the ThinLTO
504/// backends. This is needed for correctness for exported symbols (ensure
505/// at least one copy kept) and a compile-time optimization (to drop duplicate
506/// copies when possible).
508 ModuleSummaryIndex &Index,
509 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
510 &ResolvedODR,
511 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
513 &PrevailingCopy) {
514
515 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
516 const auto &Prevailing = PrevailingCopy.find(GUID);
517 // Not in map means that there was only one copy, which must be prevailing.
518 if (Prevailing == PrevailingCopy.end())
519 return true;
520 return Prevailing->second == S;
521 };
522
523 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
525 GlobalValue::LinkageTypes NewLinkage) {
526 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
527 };
528
529 // TODO Conf.VisibilityScheme can be lto::Config::ELF for ELF.
530 lto::Config Conf;
531 thinLTOResolvePrevailingInIndex(Conf, Index, isPrevailing, recordNewLinkage,
532 GUIDPreservedSymbols);
533}
534
535// Initialize the TargetMachine builder for a given Triple
536static void initTMBuilder(TargetMachineBuilder &TMBuilder,
537 const Triple &TheTriple) {
538 if (TMBuilder.MCpu.empty())
539 TMBuilder.MCpu = lto::getThinLTODefaultCPU(TheTriple);
540 TMBuilder.TheTriple = std::move(TheTriple);
541}
542
544 MemoryBufferRef Buffer(Data, Identifier);
545
546 auto InputOrError = lto::InputFile::create(Buffer);
547 if (!InputOrError)
548 report_fatal_error(Twine("ThinLTO cannot create input file: ") +
549 toString(InputOrError.takeError()));
550
551 auto TripleStr = (*InputOrError)->getTargetTriple();
552 Triple TheTriple(TripleStr);
553
554 if (Modules.empty())
555 initTMBuilder(TMBuilder, Triple(TheTriple));
556 else if (TMBuilder.TheTriple != TheTriple) {
557 if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))
558 report_fatal_error("ThinLTO modules with incompatible triples not "
559 "supported");
560 initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
561 }
562
563 Modules.emplace_back(std::move(*InputOrError));
564}
565
567 PreservedSymbols.insert(Name);
568}
569
571 // FIXME: At the moment, we don't take advantage of this extra information,
572 // we're conservatively considering cross-references as preserved.
573 // CrossReferencedSymbols.insert(Name);
574 PreservedSymbols.insert(Name);
575}
576
577// TargetMachine factory
578std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
579 std::string ErrMsg;
580 const Target *TheTarget =
581 TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
582 if (!TheTarget) {
583 report_fatal_error(Twine("Can't load target for this Triple: ") + ErrMsg);
584 }
585
586 // Use MAttr as the default set of features.
587 SubtargetFeatures Features(MAttr);
588 Features.getDefaultSubtargetFeatures(TheTriple);
589 std::string FeatureStr = Features.getString();
590
591 std::unique_ptr<TargetMachine> TM(
592 TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options,
593 RelocModel, std::nullopt, CGOptLevel));
594 assert(TM && "Cannot create target machine");
595
596 return TM;
597}
598
599/**
600 * Produce the combined summary index from all the bitcode files:
601 * "thin-link".
602 */
603std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
604 std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
605 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
606 for (auto &Mod : Modules) {
607 auto &M = Mod->getSingleBitcodeModule();
608 if (Error Err = M.readSummary(*CombinedIndex, Mod->getName())) {
609 // FIXME diagnose
611 std::move(Err), errs(),
612 "error: can't create module summary index for buffer: ");
613 return nullptr;
614 }
615 }
616 return CombinedIndex;
617}
618
619namespace {
620struct IsExported {
622 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols;
623
624 IsExported(
626 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
627 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
628
629 bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
630 const auto &ExportList = ExportLists.find(ModuleIdentifier);
631 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
632 GUIDPreservedSymbols.count(VI.getGUID());
633 }
634};
635
636struct IsPrevailing {
639 &PrevailingCopy)
640 : PrevailingCopy(PrevailingCopy) {}
641
642 bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {
643 const auto &Prevailing = PrevailingCopy.find(GUID);
644 // Not in map means that there was only one copy, which must be prevailing.
645 if (Prevailing == PrevailingCopy.end())
646 return true;
647 return Prevailing->second == S;
648 };
649};
650} // namespace
651
653 ModuleSummaryIndex &Index,
654 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
655 // We have no symbols resolution available. And can't do any better now in the
656 // case where the prevailing symbol is in a native object. It can be refined
657 // with linker information in the future.
658 auto isPrevailing = [&](GlobalValue::GUID G) {
660 };
661 computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols, isPrevailing,
662 /* ImportEnabled = */ true);
663}
664
665/**
666 * Perform promotion and renaming of exported internal functions.
667 * Index is updated to reflect linkage changes from weak resolution.
668 */
670 const lto::InputFile &File) {
671 auto ModuleCount = Index.modulePaths().size();
672 auto ModuleIdentifier = TheModule.getModuleIdentifier();
673
674 // Collect for each module the list of function it defines (GUID -> Summary).
675 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries;
676 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
677
678 // Convert the preserved symbols set from string to GUID
679 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
680 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
681
682 // Add used symbol to the preserved symbols.
683 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
684
685 // Compute "dead" symbols, we don't want to import/export these!
686 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
687
688 // Compute prevailing symbols
690 computePrevailingCopies(Index, PrevailingCopy);
691
692 // Generate import/export list
693 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
695 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
696 IsPrevailing(PrevailingCopy), ImportLists,
697 ExportLists);
698
699 // Resolve prevailing symbols
701 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
702 PrevailingCopy);
703
704 thinLTOFinalizeInModule(TheModule,
705 ModuleToDefinedGVSummaries[ModuleIdentifier],
706 /*PropagateAttrs=*/false);
707
708 // Promote the exported values in the index, so that they are promoted
709 // in the module.
711 Index, IsExported(ExportLists, GUIDPreservedSymbols),
712 IsPrevailing(PrevailingCopy));
713
714 // FIXME Set ClearDSOLocalOnDeclarations.
715 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
716}
717
718/**
719 * Perform cross-module importing for the module identified by ModuleIdentifier.
720 */
722 ModuleSummaryIndex &Index,
723 const lto::InputFile &File) {
724 auto ModuleMap = generateModuleMap(Modules);
725 auto ModuleCount = Index.modulePaths().size();
726
727 // Collect for each module the list of function it defines (GUID -> Summary).
728 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
729 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
730
731 // Convert the preserved symbols set from string to GUID
732 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
733 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
734
735 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
736
737 // Compute "dead" symbols, we don't want to import/export these!
738 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
739
740 // Compute prevailing symbols
742 computePrevailingCopies(Index, PrevailingCopy);
743
744 // Generate import/export list
745 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
747 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
748 IsPrevailing(PrevailingCopy), ImportLists,
749 ExportLists);
750 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
751
752 // FIXME Set ClearDSOLocalOnDeclarations.
753 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
754 /*ClearDSOLocalOnDeclarations=*/false);
755}
756
757/**
758 * Compute the list of summaries needed for importing into module.
759 */
761 Module &TheModule, ModuleSummaryIndex &Index,
762 ModuleToSummariesForIndexTy &ModuleToSummariesForIndex,
763 GVSummaryPtrSet &DecSummaries, const lto::InputFile &File) {
764 auto ModuleCount = Index.modulePaths().size();
765 auto ModuleIdentifier = TheModule.getModuleIdentifier();
766
767 // Collect for each module the list of function it defines (GUID -> Summary).
768 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
769 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
770
771 // Convert the preserved symbols set from string to GUID
772 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
773 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
774
775 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
776
777 // Compute "dead" symbols, we don't want to import/export these!
778 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
779
780 // Compute prevailing symbols
782 computePrevailingCopies(Index, PrevailingCopy);
783
784 // Generate import/export list
785 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
787 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
788 IsPrevailing(PrevailingCopy), ImportLists,
789 ExportLists);
790
792 ModuleIdentifier, ModuleToDefinedGVSummaries,
793 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
794}
795
796/**
797 * Emit the list of files needed for importing into module.
798 */
800 ModuleSummaryIndex &Index,
801 const lto::InputFile &File) {
802 auto ModuleCount = Index.modulePaths().size();
803 auto ModuleIdentifier = TheModule.getModuleIdentifier();
804
805 // Collect for each module the list of function it defines (GUID -> Summary).
806 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
807 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
808
809 // Convert the preserved symbols set from string to GUID
810 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
811 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
812
813 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
814
815 // Compute "dead" symbols, we don't want to import/export these!
816 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
817
818 // Compute prevailing symbols
820 computePrevailingCopies(Index, PrevailingCopy);
821
822 // Generate import/export list
823 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
825 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
826 IsPrevailing(PrevailingCopy), ImportLists,
827 ExportLists);
828
829 // 'EmitImportsFiles' emits the list of modules from which to import from, and
830 // the set of keys in `ModuleToSummariesForIndex` should be a superset of keys
831 // in `DecSummaries`, so no need to use `DecSummaries` in `EmitImportFiles`.
832 GVSummaryPtrSet DecSummaries;
833 ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
835 ModuleIdentifier, ModuleToDefinedGVSummaries,
836 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
837
838 if (Error EC = EmitImportsFiles(ModuleIdentifier, OutputName,
839 ModuleToSummariesForIndex))
840 report_fatal_error(Twine("Failed to open ") + OutputName +
841 " to save imports lists\n");
842}
843
844/**
845 * Perform internalization. Runs promote and internalization together.
846 * Index is updated to reflect linkage changes.
847 */
849 ModuleSummaryIndex &Index,
850 const lto::InputFile &File) {
851 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
852 auto ModuleCount = Index.modulePaths().size();
853 auto ModuleIdentifier = TheModule.getModuleIdentifier();
854
855 // Convert the preserved symbols set from string to GUID
856 auto GUIDPreservedSymbols =
857 computeGUIDPreservedSymbols(File, PreservedSymbols, TMBuilder.TheTriple);
858
859 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
860
861 // Collect for each module the list of function it defines (GUID -> Summary).
862 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
863 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
864
865 // Compute "dead" symbols, we don't want to import/export these!
866 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
867
868 // Compute prevailing symbols
870 computePrevailingCopies(Index, PrevailingCopy);
871
872 // Generate import/export list
873 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
875 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
876 IsPrevailing(PrevailingCopy), ImportLists,
877 ExportLists);
878 auto &ExportList = ExportLists[ModuleIdentifier];
879
880 // Be friendly and don't nuke totally the module when the client didn't
881 // supply anything to preserve.
882 if (ExportList.empty() && GUIDPreservedSymbols.empty())
883 return;
884
885 // Resolve prevailing symbols
887 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
888 PrevailingCopy);
889
890 // Promote the exported values in the index, so that they are promoted
891 // in the module.
893 Index, IsExported(ExportLists, GUIDPreservedSymbols),
894 IsPrevailing(PrevailingCopy));
895
896 // FIXME Set ClearDSOLocalOnDeclarations.
897 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
898
899 // Internalization
900 thinLTOFinalizeInModule(TheModule,
901 ModuleToDefinedGVSummaries[ModuleIdentifier],
902 /*PropagateAttrs=*/false);
903
904 thinLTOInternalizeModule(TheModule,
905 ModuleToDefinedGVSummaries[ModuleIdentifier]);
906}
907
908/**
909 * Perform post-importing ThinLTO optimizations.
910 */
912 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
913
914 // Optimize now
915 optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,
916 DebugPassManager, nullptr);
917}
918
919/// Write out the generated object file, either from CacheEntryPath or from
920/// OutputBuffer, preferring hard-link when possible.
921/// Returns the path to the generated file in SavedObjectsDirectoryPath.
922std::string
924 const MemoryBuffer &OutputBuffer) {
925 auto ArchName = TMBuilder.TheTriple.getArchName();
926 SmallString<128> OutputPath(SavedObjectsDirectoryPath);
927 llvm::sys::path::append(OutputPath,
928 Twine(count) + "." + ArchName + ".thinlto.o");
929 OutputPath.c_str(); // Ensure the string is null terminated.
930 if (sys::fs::exists(OutputPath))
931 sys::fs::remove(OutputPath);
932
933 // We don't return a memory buffer to the linker, just a list of files.
934 if (!CacheEntryPath.empty()) {
935 // Cache is enabled, hard-link the entry (or copy if hard-link fails).
936 auto Err = sys::fs::create_hard_link(CacheEntryPath, OutputPath);
937 if (!Err)
938 return std::string(OutputPath);
939 // Hard linking failed, try to copy.
940 Err = sys::fs::copy_file(CacheEntryPath, OutputPath);
941 if (!Err)
942 return std::string(OutputPath);
943 // Copy failed (could be because the CacheEntry was removed from the cache
944 // in the meantime by another process), fall back and try to write down the
945 // buffer to the output.
946 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
947 << "' to '" << OutputPath << "'\n";
948 }
949 // No cache entry, just write out the buffer.
950 std::error_code Err;
951 raw_fd_ostream OS(OutputPath, Err, sys::fs::OF_None);
952 if (Err)
953 report_fatal_error(Twine("Can't open output '") + OutputPath + "'\n");
954 OS << OutputBuffer.getBuffer();
955 return std::string(OutputPath);
956}
957
958// Main entry point for the ThinLTO processing
960 timeTraceProfilerBegin("ThinLink", StringRef(""));
961 auto TimeTraceScopeExit = llvm::make_scope_exit([]() {
964 });
965 // Prepare the resulting object vector
966 assert(ProducedBinaries.empty() && "The generator should not be reused");
967 if (SavedObjectsDirectoryPath.empty())
968 ProducedBinaries.resize(Modules.size());
969 else {
970 sys::fs::create_directories(SavedObjectsDirectoryPath);
971 bool IsDir;
972 sys::fs::is_directory(SavedObjectsDirectoryPath, IsDir);
973 if (!IsDir)
974 report_fatal_error(Twine("Unexistent dir: '") + SavedObjectsDirectoryPath + "'");
975 ProducedBinaryFiles.resize(Modules.size());
976 }
977
978 if (CodeGenOnly) {
979 // Perform only parallel codegen and return.
981 int count = 0;
982 for (auto &Mod : Modules) {
983 Pool.async([&](int count) {
984 LLVMContext Context;
986
987 // Parse module now
988 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
989 /*IsImporting*/ false);
990
991 // CodeGen
992 auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
993 if (SavedObjectsDirectoryPath.empty())
994 ProducedBinaries[count] = std::move(OutputBuffer);
995 else
996 ProducedBinaryFiles[count] =
997 writeGeneratedObject(count, "", *OutputBuffer);
998 }, count++);
999 }
1000
1001 return;
1002 }
1003
1004 // Sequential linking phase
1005 auto Index = linkCombinedIndex();
1006
1007 // Save temps: index.
1008 if (!SaveTempsDir.empty()) {
1009 auto SaveTempPath = SaveTempsDir + "index.bc";
1010 std::error_code EC;
1011 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
1012 if (EC)
1013 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
1014 " to save optimized bitcode\n");
1015 writeIndexToFile(*Index, OS);
1016 }
1017
1018
1019 // Prepare the module map.
1020 auto ModuleMap = generateModuleMap(Modules);
1021 auto ModuleCount = Modules.size();
1022
1023 // Collect for each module the list of function it defines (GUID -> Summary).
1024 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
1025 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1026
1027 // Convert the preserved symbols set from string to GUID, this is needed for
1028 // computing the caching hash and the internalization.
1029 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1030 for (const auto &M : Modules)
1031 computeGUIDPreservedSymbols(*M, PreservedSymbols, TMBuilder.TheTriple,
1032 GUIDPreservedSymbols);
1033
1034 // Add used symbol from inputs to the preserved symbols.
1035 for (const auto &M : Modules)
1036 addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
1037
1038 // Compute "dead" symbols, we don't want to import/export these!
1039 computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
1040
1041 // Currently there is no support for enabling whole program visibility via a
1042 // linker option in the old LTO API, but this call allows it to be specified
1043 // via the internal option. Must be done before WPD below.
1044 if (hasWholeProgramVisibility(/* WholeProgramVisibilityEnabledInLTO */ false))
1045 Index->setWithWholeProgramVisibility();
1046
1047 // FIXME: This needs linker information via a TBD new interface
1049 /*WholeProgramVisibilityEnabledInLTO=*/false,
1050 // FIXME: These need linker information via a
1051 // TBD new interface.
1052 /*DynamicExportSymbols=*/{},
1053 /*VisibleToRegularObjSymbols=*/{});
1054
1055 // Perform index-based WPD. This will return immediately if there are
1056 // no index entries in the typeIdMetadata map (e.g. if we are instead
1057 // performing IR-based WPD in hybrid regular/thin LTO mode).
1058 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1059 std::set<GlobalValue::GUID> ExportedGUIDs;
1060 runWholeProgramDevirtOnIndex(*Index, ExportedGUIDs, LocalWPDTargetsMap);
1061 for (auto GUID : ExportedGUIDs)
1062 GUIDPreservedSymbols.insert(GUID);
1063
1064 // Compute prevailing symbols
1066 computePrevailingCopies(*Index, PrevailingCopy);
1067
1068 // Collect the import/export lists for all modules from the call-graph in the
1069 // combined index.
1070 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
1072 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries,
1073 IsPrevailing(PrevailingCopy), ImportLists,
1074 ExportLists);
1075
1076 // We use a std::map here to be able to have a defined ordering when
1077 // producing a hash for the cache entry.
1078 // FIXME: we should be able to compute the caching hash for the entry based
1079 // on the index, and nuke this map.
1081
1082 // Resolve prevailing symbols, this has to be computed early because it
1083 // impacts the caching.
1084 resolvePrevailingInIndex(*Index, ResolvedODR, GUIDPreservedSymbols,
1085 PrevailingCopy);
1086
1087 // Use global summary-based analysis to identify symbols that can be
1088 // internalized (because they aren't exported or preserved as per callback).
1089 // Changes are made in the index, consumed in the ThinLTO backends.
1091 IsExported(ExportLists, GUIDPreservedSymbols),
1092 LocalWPDTargetsMap);
1094 *Index, IsExported(ExportLists, GUIDPreservedSymbols),
1095 IsPrevailing(PrevailingCopy));
1096
1097 thinLTOPropagateFunctionAttrs(*Index, IsPrevailing(PrevailingCopy));
1098
1099 // Make sure that every module has an entry in the ExportLists, ImportList,
1100 // GVSummary and ResolvedODR maps to enable threaded access to these maps
1101 // below.
1102 for (auto &Module : Modules) {
1103 auto ModuleIdentifier = Module->getName();
1104 ExportLists[ModuleIdentifier];
1105 ImportLists[ModuleIdentifier];
1106 ResolvedODR[ModuleIdentifier];
1107 ModuleToDefinedGVSummaries[ModuleIdentifier];
1108 }
1109
1110 std::vector<BitcodeModule *> ModulesVec;
1111 ModulesVec.reserve(Modules.size());
1112 for (auto &Mod : Modules)
1113 ModulesVec.push_back(&Mod->getSingleBitcodeModule());
1114 std::vector<int> ModulesOrdering = lto::generateModulesOrdering(ModulesVec);
1115
1118
1119 TimeTraceScopeExit.release();
1120
1121 // Parallel optimizer + codegen
1122 {
1124 for (auto IndexCount : ModulesOrdering) {
1125 auto &Mod = Modules[IndexCount];
1126 Pool.async([&](int count) {
1127 auto ModuleIdentifier = Mod->getName();
1128 auto &ExportList = ExportLists[ModuleIdentifier];
1129
1130 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
1131
1132 // The module may be cached, this helps handling it.
1133 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
1134 ImportLists[ModuleIdentifier], ExportList,
1135 ResolvedODR[ModuleIdentifier],
1136 DefinedGVSummaries, OptLevel, Freestanding,
1137 TMBuilder);
1138 auto CacheEntryPath = CacheEntry.getEntryPath();
1139
1140 {
1141 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
1142 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
1143 << " '" << CacheEntryPath << "' for buffer "
1144 << count << " " << ModuleIdentifier << "\n");
1145
1146 if (ErrOrBuffer) {
1147 // Cache Hit!
1148 if (SavedObjectsDirectoryPath.empty())
1149 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
1150 else
1151 ProducedBinaryFiles[count] = writeGeneratedObject(
1152 count, CacheEntryPath, *ErrOrBuffer.get());
1153 return;
1154 }
1155 }
1156
1157 LLVMContext Context;
1160 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
1163 if (!DiagFileOrErr) {
1164 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
1165 report_fatal_error("ThinLTO: Can't get an output file for the "
1166 "remarks");
1167 }
1168
1169 // Parse module now
1170 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1171 /*IsImporting*/ false);
1172
1173 // Save temps: original file.
1174 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
1175
1176 auto &ImportList = ImportLists[ModuleIdentifier];
1177 // Run the main process now, and generates a binary
1178 auto OutputBuffer = ProcessThinLTOModule(
1179 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
1180 ExportList, GUIDPreservedSymbols,
1181 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
1182 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,
1183 DebugPassManager);
1184
1185 // Commit to the cache (if enabled)
1186 CacheEntry.write(*OutputBuffer);
1187
1188 if (SavedObjectsDirectoryPath.empty()) {
1189 // We need to generated a memory buffer for the linker.
1190 if (!CacheEntryPath.empty()) {
1191 // When cache is enabled, reload from the cache if possible.
1192 // Releasing the buffer from the heap and reloading it from the
1193 // cache file with mmap helps us to lower memory pressure.
1194 // The freed memory can be used for the next input file.
1195 // The final binary link will read from the VFS cache (hopefully!)
1196 // or from disk (if the memory pressure was too high).
1197 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
1198 if (auto EC = ReloadedBufferOrErr.getError()) {
1199 // On error, keep the preexisting buffer and print a diagnostic.
1200 errs() << "remark: can't reload cached file '" << CacheEntryPath
1201 << "': " << EC.message() << "\n";
1202 } else {
1203 OutputBuffer = std::move(*ReloadedBufferOrErr);
1204 }
1205 }
1206 ProducedBinaries[count] = std::move(OutputBuffer);
1207 return;
1208 }
1209 ProducedBinaryFiles[count] = writeGeneratedObject(
1210 count, CacheEntryPath, *OutputBuffer);
1211 }, IndexCount);
1212 }
1213 }
1214
1215 pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);
1216
1217 // If statistics were requested, print them out now.
1221}
This file provides a bitcode writing pass.
#define LLVM_DEBUG(...)
Definition: Debug.h:106
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
Provides passes for computing function attributes based on interprocedural analyses.
This file implements a simple parser to decode commandline option for remarks hotness threshold that ...
static const char * PreservedSymbols[]
Definition: IRSymtab.cpp:49
static LVOptions Options
Definition: LVOptions.cpp:25
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This is the interface to build a ModuleSummaryIndex for a module.
CGSCCAnalysisManager CGAM
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines classes/functions to handle pass execution timing information with interfaces for...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This header defines a class that provides bookkeeping for all standard (i.e in-tree) pass instrumenta...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
This file contains some functions that are useful when dealing with strings.
static void crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, const FunctionImporter::ImportMapTy &ImportList, bool ClearDSOLocalOnDeclarations)
static void computeDeadSymbolsInIndex(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
static StringMap< lto::InputFile * > generateModuleMap(std::vector< std::unique_ptr< lto::InputFile > > &Modules)
static void initTMBuilder(TargetMachineBuilder &TMBuilder, const Triple &TheTriple)
static void resolvePrevailingInIndex(ModuleSummaryIndex &Index, StringMap< std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > > &ResolvedODR, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)
Resolve prevailing symbols.
static void computePrevailingCopies(const ModuleSummaryIndex &Index, DenseMap< GlobalValue::GUID, const GlobalValueSummary * > &PrevailingCopy)
static void saveTempBitcode(const Module &TheModule, StringRef TempDir, unsigned count, StringRef Suffix)
static void verifyLoadedModule(Module &TheModule)
Verify the module and strip broken debug info.
static void addUsedSymbolToPreservedGUID(const lto::InputFile &File, DenseSet< GlobalValue::GUID > &PreservedGUID)
static std::unique_ptr< MemoryBuffer > ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index, StringMap< lto::InputFile * > &ModuleMap, TargetMachine &TM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, const GVSummaryMapTy &DefinedGlobals, const ThinLTOCodeGenerator::CachingOptions &CacheOptions, bool DisableCodeGen, StringRef SaveTempsDir, bool Freestanding, unsigned OptLevel, unsigned count, bool DebugPassManager)
static cl::opt< int > ThreadCount("threads", cl::init(0))
static std::unique_ptr< MemoryBuffer > codegenModule(Module &TheModule, TargetMachine &TM)
static void optimizeModule(Module &TheModule, TargetMachine &TM, unsigned OptLevel, bool Freestanding, bool DebugPassManager, ModuleSummaryIndex *Index)
static void computeGUIDPreservedSymbols(const lto::InputFile &File, const StringSet<> &PreservedSymbols, const Triple &TheTriple, DenseSet< GlobalValue::GUID > &GUIDs)
static std::unique_ptr< Module > loadModuleFromInput(lto::InputFile *Input, LLVMContext &Context, bool Lazy, bool IsImporting)
static const GlobalValueSummary * getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList)
static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations)
char * getBuffer()
Definition: Utility.h:180
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:471
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
iterator end()
Definition: DenseMap.h:84
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition: DenseMap.h:103
Implements a dense probed hash-table based set.
Definition: DenseSet.h:278
This is the base abstract class for diagnostic reporting in the backend.
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
Interface for custom diagnostic printing.
Base class for error info classes.
Definition: Error.h:45
Represents either an error or a value T.
Definition: ErrorOr.h:56
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
The map maintains the list of imports.
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.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:379
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:595
bool isWeakForLinker() const
Definition: GlobalValue.h:552
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
Definition: Globals.cpp:184
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition: GlobalValue.h:51
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
void enableDebugTypeODRUniquing()
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
void setDiscardValueNames(bool Discard)
Set the Context runtime configuration to discard all value name (but GlobalValue).
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:51
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
StringRef getBuffer() const
Definition: MemoryBuffer.h:70
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
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:302
StringRef getName() const
Get a short "name" for the module.
Definition: Module.h:285
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:298
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:268
PIELevel::Level getPIELevel() const
Returns the PIE level (small or large model)
Definition: Module.cpp:633
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:105
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build a 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.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Definition: PassManager.h:195
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
Tunable parameters for passes in the default pipelines.
Definition: PassBuilder.h:43
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:58
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:54
Analysis providing profile information.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:281
A non-threaded implementation.
Definition: ThreadPool.h:218
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
const char * c_str()
Definition: SmallString.h:259
bool empty() const
Definition: SmallVector.h:81
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
This class provides an interface to register all the standard pass instrumentations and manages their...
unsigned size() const
Definition: StringMap.h:104
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
bool contains(StringRef Key) const
contains - Return true if the element is in the map, false otherwise.
Definition: StringMap.h:273
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:38
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.
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:77
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, CodeGenOptLevel OL=CodeGenOptLevel::Default, bool JIT=false) const
createTargetMachine - Create a target specific machine implementation for the specified Triple.
void preserveSymbol(StringRef Name)
Adds to a list of all global symbols that must exist in the final generated code.
void run()
Process all the modules that were added to the code generator in parallel.
void crossReferenceSymbol(StringRef Name)
Adds to a list of all global symbols that are cross-referenced between ThinLTO files.
void addModule(StringRef Identifier, StringRef Data)
Add given module to the code generator.
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Definition: ThreadPool.h:78
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
std::string merge(const Triple &Other) const
Merge target triples.
Definition: Triple.cpp:2050
StringRef getArchName() const
Get the architecture (first) component of the triple.
Definition: Triple.cpp:1341
bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Definition: Triple.cpp:2026
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:213
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:95
PassManager manages ModulePassManagers.
bool run(Module &M)
run - Execute all of the passes scheduled for execution.
An input file.
Definition: LTO.h:115
static Expected< std::unique_ptr< InputFile > > create(MemoryBufferRef Object)
Create an InputFile.
Definition: LTO.cpp:554
BitcodeModule & getSingleBitcodeModule()
Definition: LTO.cpp:587
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:460
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
void optimize(Module &Module)
Perform post-importing ThinLTO optimizations.
std::unique_ptr< ModuleSummaryIndex > linkCombinedIndex()
Produce the combined summary index from all the bitcode files: "thin-link".
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform cross-module importing for the module identified by ModuleIdentifier.
void emitImports(Module &Module, StringRef OutputName, ModuleSummaryIndex &Index, const lto::InputFile &File)
Compute and emit the imported files for module at ModulePath.
void internalize(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform internalization.
void gatherImportedSummariesForModule(Module &Module, ModuleSummaryIndex &Index, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries, const lto::InputFile &File)
Compute the list of summaries and the subset of declaration summaries needed for importing into modul...
void promote(Module &Module, ModuleSummaryIndex &Index, const lto::InputFile &File)
Perform promotion and renaming of exported internal functions, and additionally resolve weak and link...
std::string writeGeneratedObject(int count, StringRef CacheEntryPath, const MemoryBuffer &OutputBuffer)
Write temporary object file to SavedObjectDirectoryPath, write symlink to Cache directory if needed.
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.
Key
PAL metadata keys.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
StringLiteral getThinLTODefaultCPU(const Triple &TheTriple)
Definition: LTO.cpp:1721
std::vector< int > generateModulesOrdering(ArrayRef< BitcodeModule * > R)
Produces a container ordering for optimal multi-threaded processing.
Definition: LTO.cpp:2135
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:2091
std::error_code closeFile(file_t &F)
Close the file object.
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1077
@ OF_UpdateAtime
Force files Atime to be updated on access.
Definition: FileSystem.h:782
std::error_code create_hard_link(const Twine &to, const Twine &from)
Create a hard link from from to to, or return an error.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
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
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition: Path.cpp:1016
Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
bool is_directory(const basic_file_status &status)
Does status represent a directory?
Definition: Path.cpp:1092
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
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
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:65
cl::opt< std::string > RemarksFormat("lto-pass-remarks-format", cl::desc("The format used for serializing remarks (default: YAML)"), cl::value_desc("format"), cl::init("yaml"))
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1739
cl::opt< bool > LTODiscardValueNames("lto-discard-value-names", cl::desc("Strip names from Value during LTO (other than GlobalValue)."), cl::init(false), cl::Hidden)
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.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition: ScopeExit.h:59
cl::opt< std::string > RemarksPasses("lto-pass-remarks-filter", cl::desc("Only record optimization remarks from passes whose " "names match the given regular expression"), cl::value_desc("regex"))
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:977
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Propagate function attributes for function summaries along the index's callgraph during thinlink.
void 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...
ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})
Direct function to compute a ModuleSummaryIndex from a given module.
void reportAndResetTimings(raw_ostream *OutStream=nullptr)
If -time-passes has been specified, report the timings immediately and then reset the timers to zero.
@ DK_Linker
bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
void thinLTOInternalizeAndPromoteInIndex(ModuleSummaryIndex &Index, function_ref< bool(StringRef, ValueInfo)> isExported, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Update the linkages in the given Index to mark exported values as external and non-exported values as...
Definition: LTO.cpp:541
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition: DWP.cpp:625
bool timeTraceProfilerEnabled()
Is the time trace profiler enabled, i.e. initialized?
Definition: TimeProfiler.h:129
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:167
Error writeToOutput(StringRef OutputFileName, std::function< Error(raw_ostream &)> Write)
This helper creates an output stream and then passes it to Write.
bool AreStatisticsEnabled()
Check if statistics are enabled.
Definition: Statistic.cpp:139
cl::opt< bool > RemarksWithHotness("lto-pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden)
void timeTraceProfilerEnd()
Manually end the last time section.
cl::opt< std::string > RemarksFilename("lto-pass-remarks-output", cl::desc("Output filename for pass remarks"), cl::value_desc("filename"))
void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
void thinLTOResolvePrevailingInIndex(const lto::Config &C, ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, function_ref< void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> recordNewLinkage, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols)
Resolve linkage for prevailing symbols in the Index.
Definition: LTO.cpp:440
std::vector< std::unique_ptr< GlobalValueSummary > > GlobalValueSummaryList
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Definition: DebugInfo.cpp:608
@ Mod
The access may modify the value stored in memory.
void PrintStatistics()
Print statistics to the file returned by CreateInfoOutputFile().
Definition: Statistic.cpp:229
void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
bool pruneCache(StringRef Path, CachePruningPolicy Policy, const std::vector< std::unique_ptr< MemoryBuffer > > &Files={})
Peform pruning using the supplied policy, returns true if pruning occurred, i.e.
void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:1938
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
@ DS_Warning
@ DS_Error
cl::opt< std::optional< uint64_t >, false, remarks::HotnessThresholdParser > RemarksHotnessThreshold("lto-pass-remarks-hotness-threshold", cl::desc("Minimum profile count required for an " "optimization remark to be output." " Use 'auto' to apply the threshold from profile summary."), cl::value_desc("uint or 'auto'"), cl::init(0), cl::Hidden)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1766
std::string computeLTOCacheKey(const lto::Config &Conf, const ModuleSummaryIndex &Index, StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map< GlobalValue::GUID, GlobalValue::LinkageTypes > &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, const DenseSet< GlobalValue::GUID > &CfiFunctionDefs={}, const DenseSet< GlobalValue::GUID > &CfiFunctionDecls={})
Computes a unique hash for the Module considering the current list of export/import and other global ...
Definition: LTO.cpp:99
const char * toString(DWARFSectionKind Kind)
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
Definition: Error.cpp:117
void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
bool verifyModule(const Module &M, raw_ostream *OS=nullptr, bool *BrokenDebugInfo=nullptr)
Check a module for errors.
Definition: Verifier.cpp:7308
TimeTraceProfilerEntry * timeTraceProfilerBegin(StringRef Name, StringRef Detail)
Manually begin a time section, with the given Name and Detail.
void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
Helper to gather options relevant to the target machine creation.
std::unique_ptr< TargetMachine > create() const
Struct that holds a reference to a particular GUID in a global value summary.
LTO configuration.
Definition: Config.h:41
std::vector< std::string > MAttrs
Definition: Config.h:50
CodeGenOptLevel CGOptLevel
Definition: Config.h:57
std::string CPU
Definition: Config.h:48
TargetOptions Options
Definition: Config.h:49
unsigned OptLevel
Definition: Config.h:59
std::optional< Reloc::Model > RelocModel
Definition: Config.h:55
bool Freestanding
Flag to indicate that the optimizer should not assume builtins are present on the target.
Definition: Config.h:65