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 if (renameModuleForThinLTO(TheModule, Index, ClearDSOLocalOnDeclarations))
164 report_fatal_error("renameModuleForThinLTO failed");
165}
166
167namespace {
168class ThinLTODiagnosticInfo : public DiagnosticInfo {
169 const Twine &Msg;
170public:
171 ThinLTODiagnosticInfo(const Twine &DiagMsg,
172 DiagnosticSeverity Severity = DS_Error)
173 : DiagnosticInfo(DK_Linker, Severity), Msg(DiagMsg) {}
174 void print(DiagnosticPrinter &DP) const override { DP << Msg; }
175};
176}
177
178/// Verify the module and strip broken debug info.
179static void verifyLoadedModule(Module &TheModule) {
180 bool BrokenDebugInfo = false;
181 if (verifyModule(TheModule, &dbgs(), &BrokenDebugInfo))
182 report_fatal_error("Broken module found, compilation aborted!");
183 if (BrokenDebugInfo) {
184 TheModule.getContext().diagnose(ThinLTODiagnosticInfo(
185 "Invalid debug info found, debug info will be stripped", DS_Warning));
186 StripDebugInfo(TheModule);
187 }
188}
189
190static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile *Input,
191 LLVMContext &Context,
192 bool Lazy,
193 bool IsImporting) {
194 auto &Mod = Input->getSingleBitcodeModule();
195 SMDiagnostic Err;
197 Lazy ? Mod.getLazyModule(Context,
198 /* ShouldLazyLoadMetadata */ true, IsImporting)
199 : Mod.parseModule(Context);
200 if (!ModuleOrErr) {
201 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
202 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
203 SourceMgr::DK_Error, EIB.message());
204 Err.print("ThinLTO", errs());
205 });
206 report_fatal_error("Can't load module, abort.");
207 }
208 if (!Lazy)
209 verifyLoadedModule(*ModuleOrErr.get());
210 return std::move(*ModuleOrErr);
211}
212
213static void
216 const FunctionImporter::ImportMapTy &ImportList,
217 bool ClearDSOLocalOnDeclarations) {
218 auto Loader = [&](StringRef Identifier) {
219 auto &Input = ModuleMap[Identifier];
220 return loadModuleFromInput(Input, TheModule.getContext(),
221 /*Lazy=*/true, /*IsImporting*/ true);
222 };
223
224 FunctionImporter Importer(Index, Loader, ClearDSOLocalOnDeclarations);
225 Expected<bool> Result = Importer.importFunctions(TheModule, ImportList);
226 if (!Result) {
227 handleAllErrors(Result.takeError(), [&](ErrorInfoBase &EIB) {
228 SMDiagnostic Err = SMDiagnostic(TheModule.getModuleIdentifier(),
229 SourceMgr::DK_Error, EIB.message());
230 Err.print("ThinLTO", errs());
231 });
232 report_fatal_error("importFunctions failed");
233 }
234 // Verify again after cross-importing.
235 verifyLoadedModule(TheModule);
236}
237
238static void optimizeModule(Module &TheModule, TargetMachine &TM,
239 unsigned OptLevel, bool Freestanding,
240 bool DebugPassManager, ModuleSummaryIndex *Index) {
241 std::optional<PGOOptions> PGOOpt;
246
248 StandardInstrumentations SI(TheModule.getContext(), DebugPassManager);
249 SI.registerCallbacks(PIC, &MAM);
251 PTO.LoopVectorization = true;
252 PTO.SLPVectorization = true;
253 PassBuilder PB(&TM, PTO, PGOOpt, &PIC);
254
255 std::unique_ptr<TargetLibraryInfoImpl> TLII(
256 new TargetLibraryInfoImpl(Triple(TM.getTargetTriple())));
257 if (Freestanding)
258 TLII->disableAllFunctions();
259 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
260
261 // Register all the basic analyses with the managers.
267
269
271
272 switch (OptLevel) {
273 default:
274 llvm_unreachable("Invalid optimization level");
275 case 0:
277 break;
278 case 1:
280 break;
281 case 2:
283 break;
284 case 3:
286 break;
287 }
288
289 MPM.addPass(PB.buildThinLTODefaultPipeline(OL, Index));
290
291 MPM.run(TheModule, MAM);
292}
293
294static void
296 DenseSet<GlobalValue::GUID> &PreservedGUID) {
297 for (const auto &Sym : File.symbols()) {
298 if (Sym.isUsed())
299 PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
300 }
301}
302
303// Convert the PreservedSymbols map from "Name" based to "GUID" based.
306 const Triple &TheTriple,
308 // Iterate the symbols in the input file and if the input has preserved symbol
309 // compute the GUID for the symbol.
310 for (const auto &Sym : File.symbols()) {
311 if (PreservedSymbols.count(Sym.getName()) && !Sym.getIRName().empty())
313 Sym.getIRName(), GlobalValue::ExternalLinkage, "")));
314 }
315}
316
320 const Triple &TheTriple) {
321 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols(PreservedSymbols.size());
323 GUIDPreservedSymbols);
324 return GUIDPreservedSymbols;
325}
326
327static std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
328 TargetMachine &TM) {
330
331 // CodeGen
332 {
335
336 // Setup the codegen now.
337 if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,
338 /* DisableVerify */ true))
339 report_fatal_error("Failed to setup codegen");
340
341 // Run codegen now. resulting binary is in OutputBuffer.
342 PM.run(TheModule);
343 }
344 return std::make_unique<SmallVectorMemoryBuffer>(
345 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
346}
347
348namespace {
349/// Manage caching for a single Module.
350class ModuleCacheEntry {
351 SmallString<128> EntryPath;
352
353public:
354 // Create a cache entry. This compute a unique hash for the Module considering
355 // the current list of export/import, and offer an interface to query to
356 // access the content in the cache.
357 ModuleCacheEntry(
358 StringRef CachePath, const ModuleSummaryIndex &Index, StringRef ModuleID,
359 const FunctionImporter::ImportMapTy &ImportList,
360 const FunctionImporter::ExportSetTy &ExportList,
361 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
362 const GVSummaryMapTy &DefinedGVSummaries, unsigned OptLevel,
363 bool Freestanding, const TargetMachineBuilder &TMBuilder) {
364 if (CachePath.empty())
365 return;
366
367 if (!Index.modulePaths().count(ModuleID))
368 // The module does not have an entry, it can't have a hash at all
369 return;
370
371 if (all_of(Index.getModuleHash(ModuleID),
372 [](uint32_t V) { return V == 0; }))
373 // No hash entry, no caching!
374 return;
375
377 Conf.OptLevel = OptLevel;
378 Conf.Options = TMBuilder.Options;
379 Conf.CPU = TMBuilder.MCpu;
380 Conf.MAttrs.push_back(TMBuilder.MAttr);
381 Conf.RelocModel = TMBuilder.RelocModel;
382 Conf.CGOptLevel = TMBuilder.CGOptLevel;
383 Conf.Freestanding = Freestanding;
384 std::string Key =
385 computeLTOCacheKey(Conf, Index, ModuleID, ImportList, ExportList,
386 ResolvedODR, DefinedGVSummaries);
387
388 // This choice of file name allows the cache to be pruned (see pruneCache()
389 // in include/llvm/Support/CachePruning.h).
390 sys::path::append(EntryPath, CachePath, Twine("llvmcache-", Key));
391 }
392
393 // Access the path to this entry in the cache.
394 StringRef getEntryPath() { return EntryPath; }
395
396 // Try loading the buffer for this cache entry.
397 ErrorOr<std::unique_ptr<MemoryBuffer>> tryLoadingBuffer() {
398 if (EntryPath.empty())
399 return std::error_code();
400 SmallString<64> ResultPath;
402 Twine(EntryPath), sys::fs::OF_UpdateAtime, &ResultPath);
403 if (!FDOrErr)
404 return errorToErrorCode(FDOrErr.takeError());
406 *FDOrErr, EntryPath, /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
407 sys::fs::closeFile(*FDOrErr);
408 return MBOrErr;
409 }
410
411 // Cache the Produced object file
412 void write(const MemoryBuffer &OutputBuffer) {
413 if (EntryPath.empty())
414 return;
415
416 if (auto Err = llvm::writeToOutput(
417 EntryPath, [&OutputBuffer](llvm::raw_ostream &OS) -> llvm::Error {
419 return llvm::Error::success();
420 }))
421 report_fatal_error(llvm::formatv("ThinLTO: Can't write file {0}: {1}",
422 EntryPath,
423 toString(std::move(Err)).c_str()));
424 }
425};
426} // end anonymous namespace
427
428static std::unique_ptr<MemoryBuffer>
431 const FunctionImporter::ImportMapTy &ImportList,
432 const FunctionImporter::ExportSetTy &ExportList,
433 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
434 const GVSummaryMapTy &DefinedGlobals,
435 const ThinLTOCodeGenerator::CachingOptions &CacheOptions,
436 bool DisableCodeGen, StringRef SaveTempsDir,
437 bool Freestanding, unsigned OptLevel, unsigned count,
438 bool DebugPassManager) {
439 // "Benchmark"-like optimization: single-source case
440 bool SingleModule = (ModuleMap.size() == 1);
441
442 // When linking an ELF shared object, dso_local should be dropped. We
443 // conservatively do this for -fpic.
444 bool ClearDSOLocalOnDeclarations =
445 TM.getTargetTriple().isOSBinFormatELF() &&
446 TM.getRelocationModel() != Reloc::Static &&
447 TheModule.getPIELevel() == PIELevel::Default;
448
449 if (!SingleModule) {
450 promoteModule(TheModule, Index, ClearDSOLocalOnDeclarations);
451
452 // Apply summary-based prevailing-symbol resolution decisions.
453 thinLTOFinalizeInModule(TheModule, DefinedGlobals, /*PropagateAttrs=*/true);
454
455 // Save temps: after promotion.
456 saveTempBitcode(TheModule, SaveTempsDir, count, ".1.promoted.bc");
457 }
458
459 // Be friendly and don't nuke totally the module when the client didn't
460 // supply anything to preserve.
461 if (!ExportList.empty() || !GUIDPreservedSymbols.empty()) {
462 // Apply summary-based internalization decisions.
463 thinLTOInternalizeModule(TheModule, DefinedGlobals);
464 }
465
466 // Save internalized bitcode
467 saveTempBitcode(TheModule, SaveTempsDir, count, ".2.internalized.bc");
468
469 if (!SingleModule)
470 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
471 ClearDSOLocalOnDeclarations);
472
473 // Do this after any importing so that imported code is updated.
474 // See comment at call to updateVCallVisibilityInIndex() for why
475 // WholeProgramVisibilityEnabledInLTO is false.
477 /* WholeProgramVisibilityEnabledInLTO */ false);
478
479 // Save temps: after cross-module import.
480 saveTempBitcode(TheModule, SaveTempsDir, count, ".3.imported.bc");
481
482 optimizeModule(TheModule, TM, OptLevel, Freestanding, DebugPassManager,
483 &Index);
484
485 saveTempBitcode(TheModule, SaveTempsDir, count, ".4.opt.bc");
486
487 if (DisableCodeGen) {
488 // Configured to stop before CodeGen, serialize the bitcode and return.
490 {
492 ProfileSummaryInfo PSI(TheModule);
493 auto Index = buildModuleSummaryIndex(TheModule, nullptr, &PSI);
494 WriteBitcodeToFile(TheModule, OS, true, &Index);
495 }
496 return std::make_unique<SmallVectorMemoryBuffer>(
497 std::move(OutputBuffer), /*RequiresNullTerminator=*/false);
498 }
499
500 return codegenModule(TheModule, TM);
501}
502
503/// Resolve prevailing symbols. Record resolutions in the \p ResolvedODR map
504/// for caching, and in the \p Index for application during the ThinLTO
505/// backends. This is needed for correctness for exported symbols (ensure
506/// at least one copy kept) and a compile-time optimization (to drop duplicate
507/// copies when possible).
509 ModuleSummaryIndex &Index,
510 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>>
511 &ResolvedODR,
512 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
514 &PrevailingCopy) {
515
516 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
517 const auto &Prevailing = PrevailingCopy.find(GUID);
518 // Not in map means that there was only one copy, which must be prevailing.
519 if (Prevailing == PrevailingCopy.end())
520 return true;
521 return Prevailing->second == S;
522 };
523
524 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
526 GlobalValue::LinkageTypes NewLinkage) {
527 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
528 };
529
530 // TODO Conf.VisibilityScheme can be lto::Config::ELF for ELF.
531 lto::Config Conf;
532 thinLTOResolvePrevailingInIndex(Conf, Index, isPrevailing, recordNewLinkage,
533 GUIDPreservedSymbols);
534}
535
536// Initialize the TargetMachine builder for a given Triple
537static void initTMBuilder(TargetMachineBuilder &TMBuilder,
538 const Triple &TheTriple) {
539 if (TMBuilder.MCpu.empty())
540 TMBuilder.MCpu = lto::getThinLTODefaultCPU(TheTriple);
541 TMBuilder.TheTriple = std::move(TheTriple);
542}
543
545 MemoryBufferRef Buffer(Data, Identifier);
546
547 auto InputOrError = lto::InputFile::create(Buffer);
548 if (!InputOrError)
549 report_fatal_error(Twine("ThinLTO cannot create input file: ") +
550 toString(InputOrError.takeError()));
551
552 auto TripleStr = (*InputOrError)->getTargetTriple();
553 Triple TheTriple(TripleStr);
554
555 if (Modules.empty())
556 initTMBuilder(TMBuilder, Triple(TheTriple));
557 else if (TMBuilder.TheTriple != TheTriple) {
558 if (!TMBuilder.TheTriple.isCompatibleWith(TheTriple))
559 report_fatal_error("ThinLTO modules with incompatible triples not "
560 "supported");
561 initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
562 }
563
564 Modules.emplace_back(std::move(*InputOrError));
565}
566
568 PreservedSymbols.insert(Name);
569}
570
572 // FIXME: At the moment, we don't take advantage of this extra information,
573 // we're conservatively considering cross-references as preserved.
574 // CrossReferencedSymbols.insert(Name);
575 PreservedSymbols.insert(Name);
576}
577
578// TargetMachine factory
579std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
580 std::string ErrMsg;
581 const Target *TheTarget =
582 TargetRegistry::lookupTarget(TheTriple.str(), ErrMsg);
583 if (!TheTarget) {
584 report_fatal_error(Twine("Can't load target for this Triple: ") + ErrMsg);
585 }
586
587 // Use MAttr as the default set of features.
588 SubtargetFeatures Features(MAttr);
589 Features.getDefaultSubtargetFeatures(TheTriple);
590 std::string FeatureStr = Features.getString();
591
592 std::unique_ptr<TargetMachine> TM(
593 TheTarget->createTargetMachine(TheTriple.str(), MCpu, FeatureStr, Options,
594 RelocModel, std::nullopt, CGOptLevel));
595 assert(TM && "Cannot create target machine");
596
597 return TM;
598}
599
600/**
601 * Produce the combined summary index from all the bitcode files:
602 * "thin-link".
603 */
604std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
605 std::unique_ptr<ModuleSummaryIndex> CombinedIndex =
606 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
607 for (auto &Mod : Modules) {
608 auto &M = Mod->getSingleBitcodeModule();
609 if (Error Err = M.readSummary(*CombinedIndex, Mod->getName())) {
610 // FIXME diagnose
612 std::move(Err), errs(),
613 "error: can't create module summary index for buffer: ");
614 return nullptr;
615 }
616 }
617 return CombinedIndex;
618}
619
620namespace {
621struct IsExported {
623 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols;
624
625 IsExported(
627 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)
628 : ExportLists(ExportLists), GUIDPreservedSymbols(GUIDPreservedSymbols) {}
629
630 bool operator()(StringRef ModuleIdentifier, ValueInfo VI) const {
631 const auto &ExportList = ExportLists.find(ModuleIdentifier);
632 return (ExportList != ExportLists.end() && ExportList->second.count(VI)) ||
633 GUIDPreservedSymbols.count(VI.getGUID());
634 }
635};
636
637struct IsPrevailing {
640 &PrevailingCopy)
641 : PrevailingCopy(PrevailingCopy) {}
642
643 bool operator()(GlobalValue::GUID GUID, const GlobalValueSummary *S) const {
644 const auto &Prevailing = PrevailingCopy.find(GUID);
645 // Not in map means that there was only one copy, which must be prevailing.
646 if (Prevailing == PrevailingCopy.end())
647 return true;
648 return Prevailing->second == S;
649 };
650};
651} // namespace
652
654 ModuleSummaryIndex &Index,
655 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) {
656 // We have no symbols resolution available. And can't do any better now in the
657 // case where the prevailing symbol is in a native object. It can be refined
658 // with linker information in the future.
659 auto isPrevailing = [&](GlobalValue::GUID G) {
661 };
662 computeDeadSymbolsWithConstProp(Index, GUIDPreservedSymbols, isPrevailing,
663 /* ImportEnabled = */ true);
664}
665
666/**
667 * Perform promotion and renaming of exported internal functions.
668 * Index is updated to reflect linkage changes from weak resolution.
669 */
671 const lto::InputFile &File) {
672 auto ModuleCount = Index.modulePaths().size();
673 auto ModuleIdentifier = TheModule.getModuleIdentifier();
674
675 // Collect for each module the list of function it defines (GUID -> Summary).
676 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries;
677 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
678
679 // Convert the preserved symbols set from string to GUID
680 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
681 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
682
683 // Add used symbol to the preserved symbols.
684 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
685
686 // Compute "dead" symbols, we don't want to import/export these!
687 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
688
689 // Compute prevailing symbols
691 computePrevailingCopies(Index, PrevailingCopy);
692
693 // Generate import/export list
694 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
696 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
697 IsPrevailing(PrevailingCopy), ImportLists,
698 ExportLists);
699
700 // Resolve prevailing symbols
702 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
703 PrevailingCopy);
704
705 thinLTOFinalizeInModule(TheModule,
706 ModuleToDefinedGVSummaries[ModuleIdentifier],
707 /*PropagateAttrs=*/false);
708
709 // Promote the exported values in the index, so that they are promoted
710 // in the module.
712 Index, IsExported(ExportLists, GUIDPreservedSymbols),
713 IsPrevailing(PrevailingCopy));
714
715 // FIXME Set ClearDSOLocalOnDeclarations.
716 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
717}
718
719/**
720 * Perform cross-module importing for the module identified by ModuleIdentifier.
721 */
723 ModuleSummaryIndex &Index,
724 const lto::InputFile &File) {
725 auto ModuleMap = generateModuleMap(Modules);
726 auto ModuleCount = Index.modulePaths().size();
727
728 // Collect for each module the list of function it defines (GUID -> Summary).
729 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
730 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
731
732 // Convert the preserved symbols set from string to GUID
733 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
734 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
735
736 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
737
738 // Compute "dead" symbols, we don't want to import/export these!
739 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
740
741 // Compute prevailing symbols
743 computePrevailingCopies(Index, PrevailingCopy);
744
745 // Generate import/export list
746 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
748 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
749 IsPrevailing(PrevailingCopy), ImportLists,
750 ExportLists);
751 auto &ImportList = ImportLists[TheModule.getModuleIdentifier()];
752
753 // FIXME Set ClearDSOLocalOnDeclarations.
754 crossImportIntoModule(TheModule, Index, ModuleMap, ImportList,
755 /*ClearDSOLocalOnDeclarations=*/false);
756}
757
758/**
759 * Compute the list of summaries needed for importing into module.
760 */
762 Module &TheModule, ModuleSummaryIndex &Index,
763 ModuleToSummariesForIndexTy &ModuleToSummariesForIndex,
764 GVSummaryPtrSet &DecSummaries, const lto::InputFile &File) {
765 auto ModuleCount = Index.modulePaths().size();
766 auto ModuleIdentifier = TheModule.getModuleIdentifier();
767
768 // Collect for each module the list of function it defines (GUID -> Summary).
769 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
770 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
771
772 // Convert the preserved symbols set from string to GUID
773 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
774 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
775
776 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
777
778 // Compute "dead" symbols, we don't want to import/export these!
779 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
780
781 // Compute prevailing symbols
783 computePrevailingCopies(Index, PrevailingCopy);
784
785 // Generate import/export list
786 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
788 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
789 IsPrevailing(PrevailingCopy), ImportLists,
790 ExportLists);
791
793 ModuleIdentifier, ModuleToDefinedGVSummaries,
794 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
795}
796
797/**
798 * Emit the list of files needed for importing into module.
799 */
801 ModuleSummaryIndex &Index,
802 const lto::InputFile &File) {
803 auto ModuleCount = Index.modulePaths().size();
804 auto ModuleIdentifier = TheModule.getModuleIdentifier();
805
806 // Collect for each module the list of function it defines (GUID -> Summary).
807 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
808 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
809
810 // Convert the preserved symbols set from string to GUID
811 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
812 File, PreservedSymbols, Triple(TheModule.getTargetTriple()));
813
814 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
815
816 // Compute "dead" symbols, we don't want to import/export these!
817 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
818
819 // Compute prevailing symbols
821 computePrevailingCopies(Index, PrevailingCopy);
822
823 // Generate import/export list
824 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
826 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
827 IsPrevailing(PrevailingCopy), ImportLists,
828 ExportLists);
829
830 // 'EmitImportsFiles' emits the list of modules from which to import from, and
831 // the set of keys in `ModuleToSummariesForIndex` should be a superset of keys
832 // in `DecSummaries`, so no need to use `DecSummaries` in `EmitImportFiles`.
833 GVSummaryPtrSet DecSummaries;
834 ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
836 ModuleIdentifier, ModuleToDefinedGVSummaries,
837 ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
838
839 if (Error EC = EmitImportsFiles(ModuleIdentifier, OutputName,
840 ModuleToSummariesForIndex))
841 report_fatal_error(Twine("Failed to open ") + OutputName +
842 " to save imports lists\n");
843}
844
845/**
846 * Perform internalization. Runs promote and internalization together.
847 * Index is updated to reflect linkage changes.
848 */
850 ModuleSummaryIndex &Index,
851 const lto::InputFile &File) {
852 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
853 auto ModuleCount = Index.modulePaths().size();
854 auto ModuleIdentifier = TheModule.getModuleIdentifier();
855
856 // Convert the preserved symbols set from string to GUID
857 auto GUIDPreservedSymbols =
858 computeGUIDPreservedSymbols(File, PreservedSymbols, TMBuilder.TheTriple);
859
860 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
861
862 // Collect for each module the list of function it defines (GUID -> Summary).
863 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
864 Index.collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
865
866 // Compute "dead" symbols, we don't want to import/export these!
867 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
868
869 // Compute prevailing symbols
871 computePrevailingCopies(Index, PrevailingCopy);
872
873 // Generate import/export list
874 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
876 ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries,
877 IsPrevailing(PrevailingCopy), ImportLists,
878 ExportLists);
879 auto &ExportList = ExportLists[ModuleIdentifier];
880
881 // Be friendly and don't nuke totally the module when the client didn't
882 // supply anything to preserve.
883 if (ExportList.empty() && GUIDPreservedSymbols.empty())
884 return;
885
886 // Resolve prevailing symbols
888 resolvePrevailingInIndex(Index, ResolvedODR, GUIDPreservedSymbols,
889 PrevailingCopy);
890
891 // Promote the exported values in the index, so that they are promoted
892 // in the module.
894 Index, IsExported(ExportLists, GUIDPreservedSymbols),
895 IsPrevailing(PrevailingCopy));
896
897 // FIXME Set ClearDSOLocalOnDeclarations.
898 promoteModule(TheModule, Index, /*ClearDSOLocalOnDeclarations=*/false);
899
900 // Internalization
901 thinLTOFinalizeInModule(TheModule,
902 ModuleToDefinedGVSummaries[ModuleIdentifier],
903 /*PropagateAttrs=*/false);
904
905 thinLTOInternalizeModule(TheModule,
906 ModuleToDefinedGVSummaries[ModuleIdentifier]);
907}
908
909/**
910 * Perform post-importing ThinLTO optimizations.
911 */
913 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
914
915 // Optimize now
916 optimizeModule(TheModule, *TMBuilder.create(), OptLevel, Freestanding,
917 DebugPassManager, nullptr);
918}
919
920/// Write out the generated object file, either from CacheEntryPath or from
921/// OutputBuffer, preferring hard-link when possible.
922/// Returns the path to the generated file in SavedObjectsDirectoryPath.
923std::string
925 const MemoryBuffer &OutputBuffer) {
926 auto ArchName = TMBuilder.TheTriple.getArchName();
927 SmallString<128> OutputPath(SavedObjectsDirectoryPath);
928 llvm::sys::path::append(OutputPath,
929 Twine(count) + "." + ArchName + ".thinlto.o");
930 OutputPath.c_str(); // Ensure the string is null terminated.
931 if (sys::fs::exists(OutputPath))
932 sys::fs::remove(OutputPath);
933
934 // We don't return a memory buffer to the linker, just a list of files.
935 if (!CacheEntryPath.empty()) {
936 // Cache is enabled, hard-link the entry (or copy if hard-link fails).
937 auto Err = sys::fs::create_hard_link(CacheEntryPath, OutputPath);
938 if (!Err)
939 return std::string(OutputPath);
940 // Hard linking failed, try to copy.
941 Err = sys::fs::copy_file(CacheEntryPath, OutputPath);
942 if (!Err)
943 return std::string(OutputPath);
944 // Copy failed (could be because the CacheEntry was removed from the cache
945 // in the meantime by another process), fall back and try to write down the
946 // buffer to the output.
947 errs() << "remark: can't link or copy from cached entry '" << CacheEntryPath
948 << "' to '" << OutputPath << "'\n";
949 }
950 // No cache entry, just write out the buffer.
951 std::error_code Err;
952 raw_fd_ostream OS(OutputPath, Err, sys::fs::OF_None);
953 if (Err)
954 report_fatal_error(Twine("Can't open output '") + OutputPath + "'\n");
955 OS << OutputBuffer.getBuffer();
956 return std::string(OutputPath);
957}
958
959// Main entry point for the ThinLTO processing
961 timeTraceProfilerBegin("ThinLink", StringRef(""));
962 auto TimeTraceScopeExit = llvm::make_scope_exit([]() {
965 });
966 // Prepare the resulting object vector
967 assert(ProducedBinaries.empty() && "The generator should not be reused");
968 if (SavedObjectsDirectoryPath.empty())
969 ProducedBinaries.resize(Modules.size());
970 else {
971 sys::fs::create_directories(SavedObjectsDirectoryPath);
972 bool IsDir;
973 sys::fs::is_directory(SavedObjectsDirectoryPath, IsDir);
974 if (!IsDir)
975 report_fatal_error(Twine("Unexistent dir: '") + SavedObjectsDirectoryPath + "'");
976 ProducedBinaryFiles.resize(Modules.size());
977 }
978
979 if (CodeGenOnly) {
980 // Perform only parallel codegen and return.
982 int count = 0;
983 for (auto &Mod : Modules) {
984 Pool.async([&](int count) {
985 LLVMContext Context;
987
988 // Parse module now
989 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
990 /*IsImporting*/ false);
991
992 // CodeGen
993 auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
994 if (SavedObjectsDirectoryPath.empty())
995 ProducedBinaries[count] = std::move(OutputBuffer);
996 else
997 ProducedBinaryFiles[count] =
998 writeGeneratedObject(count, "", *OutputBuffer);
999 }, count++);
1000 }
1001
1002 return;
1003 }
1004
1005 // Sequential linking phase
1006 auto Index = linkCombinedIndex();
1007
1008 // Save temps: index.
1009 if (!SaveTempsDir.empty()) {
1010 auto SaveTempPath = SaveTempsDir + "index.bc";
1011 std::error_code EC;
1012 raw_fd_ostream OS(SaveTempPath, EC, sys::fs::OF_None);
1013 if (EC)
1014 report_fatal_error(Twine("Failed to open ") + SaveTempPath +
1015 " to save optimized bitcode\n");
1016 writeIndexToFile(*Index, OS);
1017 }
1018
1019
1020 // Prepare the module map.
1021 auto ModuleMap = generateModuleMap(Modules);
1022 auto ModuleCount = Modules.size();
1023
1024 // Collect for each module the list of function it defines (GUID -> Summary).
1025 DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries(ModuleCount);
1026 Index->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
1027
1028 // Convert the preserved symbols set from string to GUID, this is needed for
1029 // computing the caching hash and the internalization.
1030 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1031 for (const auto &M : Modules)
1032 computeGUIDPreservedSymbols(*M, PreservedSymbols, TMBuilder.TheTriple,
1033 GUIDPreservedSymbols);
1034
1035 // Add used symbol from inputs to the preserved symbols.
1036 for (const auto &M : Modules)
1037 addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
1038
1039 // Compute "dead" symbols, we don't want to import/export these!
1040 computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
1041
1042 // Currently there is no support for enabling whole program visibility via a
1043 // linker option in the old LTO API, but this call allows it to be specified
1044 // via the internal option. Must be done before WPD below.
1045 if (hasWholeProgramVisibility(/* WholeProgramVisibilityEnabledInLTO */ false))
1046 Index->setWithWholeProgramVisibility();
1047
1048 // FIXME: This needs linker information via a TBD new interface
1050 /*WholeProgramVisibilityEnabledInLTO=*/false,
1051 // FIXME: These need linker information via a
1052 // TBD new interface.
1053 /*DynamicExportSymbols=*/{},
1054 /*VisibleToRegularObjSymbols=*/{});
1055
1056 // Perform index-based WPD. This will return immediately if there are
1057 // no index entries in the typeIdMetadata map (e.g. if we are instead
1058 // performing IR-based WPD in hybrid regular/thin LTO mode).
1059 std::map<ValueInfo, std::vector<VTableSlotSummary>> LocalWPDTargetsMap;
1060 std::set<GlobalValue::GUID> ExportedGUIDs;
1061 runWholeProgramDevirtOnIndex(*Index, ExportedGUIDs, LocalWPDTargetsMap);
1062 for (auto GUID : ExportedGUIDs)
1063 GUIDPreservedSymbols.insert(GUID);
1064
1065 // Compute prevailing symbols
1067 computePrevailingCopies(*Index, PrevailingCopy);
1068
1069 // Collect the import/export lists for all modules from the call-graph in the
1070 // combined index.
1071 FunctionImporter::ImportListsTy ImportLists(ModuleCount);
1073 ComputeCrossModuleImport(*Index, ModuleToDefinedGVSummaries,
1074 IsPrevailing(PrevailingCopy), ImportLists,
1075 ExportLists);
1076
1077 // We use a std::map here to be able to have a defined ordering when
1078 // producing a hash for the cache entry.
1079 // FIXME: we should be able to compute the caching hash for the entry based
1080 // on the index, and nuke this map.
1082
1083 // Resolve prevailing symbols, this has to be computed early because it
1084 // impacts the caching.
1085 resolvePrevailingInIndex(*Index, ResolvedODR, GUIDPreservedSymbols,
1086 PrevailingCopy);
1087
1088 // Use global summary-based analysis to identify symbols that can be
1089 // internalized (because they aren't exported or preserved as per callback).
1090 // Changes are made in the index, consumed in the ThinLTO backends.
1092 IsExported(ExportLists, GUIDPreservedSymbols),
1093 LocalWPDTargetsMap);
1095 *Index, IsExported(ExportLists, GUIDPreservedSymbols),
1096 IsPrevailing(PrevailingCopy));
1097
1098 thinLTOPropagateFunctionAttrs(*Index, IsPrevailing(PrevailingCopy));
1099
1100 // Make sure that every module has an entry in the ExportLists, ImportList,
1101 // GVSummary and ResolvedODR maps to enable threaded access to these maps
1102 // below.
1103 for (auto &Module : Modules) {
1104 auto ModuleIdentifier = Module->getName();
1105 ExportLists[ModuleIdentifier];
1106 ImportLists[ModuleIdentifier];
1107 ResolvedODR[ModuleIdentifier];
1108 ModuleToDefinedGVSummaries[ModuleIdentifier];
1109 }
1110
1111 std::vector<BitcodeModule *> ModulesVec;
1112 ModulesVec.reserve(Modules.size());
1113 for (auto &Mod : Modules)
1114 ModulesVec.push_back(&Mod->getSingleBitcodeModule());
1115 std::vector<int> ModulesOrdering = lto::generateModulesOrdering(ModulesVec);
1116
1119
1120 TimeTraceScopeExit.release();
1121
1122 // Parallel optimizer + codegen
1123 {
1125 for (auto IndexCount : ModulesOrdering) {
1126 auto &Mod = Modules[IndexCount];
1127 Pool.async([&](int count) {
1128 auto ModuleIdentifier = Mod->getName();
1129 auto &ExportList = ExportLists[ModuleIdentifier];
1130
1131 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
1132
1133 // The module may be cached, this helps handling it.
1134 ModuleCacheEntry CacheEntry(CacheOptions.Path, *Index, ModuleIdentifier,
1135 ImportLists[ModuleIdentifier], ExportList,
1136 ResolvedODR[ModuleIdentifier],
1137 DefinedGVSummaries, OptLevel, Freestanding,
1138 TMBuilder);
1139 auto CacheEntryPath = CacheEntry.getEntryPath();
1140
1141 {
1142 auto ErrOrBuffer = CacheEntry.tryLoadingBuffer();
1143 LLVM_DEBUG(dbgs() << "Cache " << (ErrOrBuffer ? "hit" : "miss")
1144 << " '" << CacheEntryPath << "' for buffer "
1145 << count << " " << ModuleIdentifier << "\n");
1146
1147 if (ErrOrBuffer) {
1148 // Cache Hit!
1149 if (SavedObjectsDirectoryPath.empty())
1150 ProducedBinaries[count] = std::move(ErrOrBuffer.get());
1151 else
1152 ProducedBinaryFiles[count] = writeGeneratedObject(
1153 count, CacheEntryPath, *ErrOrBuffer.get());
1154 return;
1155 }
1156 }
1157
1158 LLVMContext Context;
1161 auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks(
1164 if (!DiagFileOrErr) {
1165 errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
1166 report_fatal_error("ThinLTO: Can't get an output file for the "
1167 "remarks");
1168 }
1169
1170 // Parse module now
1171 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1172 /*IsImporting*/ false);
1173
1174 // Save temps: original file.
1175 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
1176
1177 auto &ImportList = ImportLists[ModuleIdentifier];
1178 // Run the main process now, and generates a binary
1179 auto OutputBuffer = ProcessThinLTOModule(
1180 *TheModule, *Index, ModuleMap, *TMBuilder.create(), ImportList,
1181 ExportList, GUIDPreservedSymbols,
1182 ModuleToDefinedGVSummaries[ModuleIdentifier], CacheOptions,
1183 DisableCodeGen, SaveTempsDir, Freestanding, OptLevel, count,
1184 DebugPassManager);
1185
1186 // Commit to the cache (if enabled)
1187 CacheEntry.write(*OutputBuffer);
1188
1189 if (SavedObjectsDirectoryPath.empty()) {
1190 // We need to generated a memory buffer for the linker.
1191 if (!CacheEntryPath.empty()) {
1192 // When cache is enabled, reload from the cache if possible.
1193 // Releasing the buffer from the heap and reloading it from the
1194 // cache file with mmap helps us to lower memory pressure.
1195 // The freed memory can be used for the next input file.
1196 // The final binary link will read from the VFS cache (hopefully!)
1197 // or from disk (if the memory pressure was too high).
1198 auto ReloadedBufferOrErr = CacheEntry.tryLoadingBuffer();
1199 if (auto EC = ReloadedBufferOrErr.getError()) {
1200 // On error, keep the preexisting buffer and print a diagnostic.
1201 errs() << "remark: can't reload cached file '" << CacheEntryPath
1202 << "': " << EC.message() << "\n";
1203 } else {
1204 OutputBuffer = std::move(*ReloadedBufferOrErr);
1205 }
1206 }
1207 ProducedBinaries[count] = std::move(OutputBuffer);
1208 return;
1209 }
1210 ProducedBinaryFiles[count] = writeGeneratedObject(
1211 count, CacheEntryPath, *OutputBuffer);
1212 }, IndexCount);
1213 }
1214 }
1215
1216 pruneCache(CacheOptions.Path, CacheOptions.Policy, ProducedBinaries);
1217
1218 // If statistics were requested, print them out now.
1222}
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:2030
StringRef getArchName() const
Get the architecture (first) component of the triple.
Definition: Triple.cpp:1321
bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
Definition: Triple.cpp:2006
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.
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.
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 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