52#include <system_error>
58#define DEBUG_TYPE "function-import"
61 "Number of functions thin link decided to import");
63 "Number of hot functions thin link decided to import");
65 "Number of critical functions thin link decided to import");
67 "Number of global variables thin link decided to import");
68STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
70 "Number of global variables imported in backend");
71STATISTIC(NumImportedModules,
"Number of modules imported from");
72STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
73STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
77 cl::desc(
"Import functions with noinline attribute"));
82 cl::desc(
"Only import functions with less than N instructions"));
86 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
91 cl::desc(
"As we import functions, multiply the "
92 "`import-instr-limit` threshold by this factor "
93 "before processing newly imported functions"));
98 cl::desc(
"As we import functions called from hot callsite, multiply the "
99 "`import-instr-limit` threshold by this factor "
100 "before processing newly imported functions"));
104 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
110 "Multiply the `import-instr-limit` threshold for critical callsites"));
115 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
118 cl::desc(
"Print imported functions"));
122 cl::desc(
"Print information for functions rejected for importing"));
129 cl::desc(
"Enable import metadata like 'thinlto_src_module' and "
130 "'thinlto_src_file'"));
136 cl::desc(
"The summary file to use for function importing."));
142 cl::desc(
"Import all external functions in index."));
152 cl::desc(
"If true, import function declaration as fallback if the function "
153 "definition is not imported."));
164 "thinlto-workload-def",
165 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
166 "dictionary. The keys are root functions, the values are lists of "
167 "functions to import in the module defining the root. It is "
168 "assumed -funique-internal-linkage-names was used, to ensure "
169 "local linkage functions have unique names. For example: \n"
171 " \"rootFunction_1\": [\"function_to_import_1\", "
172 "\"function_to_import_2\"], \n"
173 " \"rootFunction_2\": [\"function_to_import_3\", "
174 "\"function_to_import_4\"] \n"
181 "thinlto-move-ctxprof-trees",
182 cl::desc(
"Move contextual profiling roots and the graphs under them in "
183 "their own module."),
193static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
199 std::unique_ptr<Module> Result =
203 Err.print(
"function-import",
errs());
232 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
236 [&Index, CalleeSummaryList,
237 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
240 auto *GVSummary = SummaryPtr.get();
241 if (!Index.isGlobalValueLive(GVSummary))
278 if (Summary->notEligibleToImport())
303 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
304 unsigned Threshold,
StringRef CallerModulePath,
308 TooLargeOrNoInlineSummary =
nullptr;
309 auto QualifiedCandidates =
311 for (
auto QualifiedValue : QualifiedCandidates) {
312 Reason = QualifiedValue.first;
321 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
323 TooLargeOrNoInlineSummary = Summary;
330 TooLargeOrNoInlineSummary = Summary;
349 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
350 if (!Imports.insert(Def).second)
362 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
365 if (!Imports.contains(Def))
366 Imports.insert(Decl);
372 for (
const auto &[SrcMod, GUID, ImportType] : *
this)
379std::optional<GlobalValueSummary::ImportKind>
382 if (
auto IDPair = IDs.getImportIDs(FromModule, GUID)) {
383 auto [Def, Decl] = *IDPair;
384 if (Imports.contains(Def))
386 if (Imports.contains(Decl))
402 bool shouldImportGlobal(
const ValueInfo &VI) {
403 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
404 if (GVS == DefinedGVSummaries.end())
416 if (VI.getSummaryList().size() > 1 &&
418 !IsPrevailing(VI.getGUID(), GVS->second))
427 for (
const auto &VI : Summary.refs()) {
428 if (!shouldImportGlobal(VI)) {
430 dbgs() <<
"Ref ignored! Target already in destination module.\n");
436 for (
const auto &RefSummary : VI.getSummaryList()) {
443 bool CanImportDecl =
false;
446 Summary.modulePath()) ||
447 !Index.canImportGlobalVar(GVS,
true,
450 ImportList.maybeAddDeclaration(RefSummary->modulePath(),
458 if (ImportList.addDefinition(RefSummary->modulePath(), VI.getGUID()) !=
464 NumImportedGlobalVarsThinLink++;
469 (*ExportLists)[RefSummary->modulePath()].insert(VI);
473 if (!Index.isWriteOnly(GVS))
487 : Index(Index), DefinedGVSummaries(DefinedGVSummaries),
488 IsPrevailing(IsPrevailing), ImportList(ImportList),
489 ExportLists(ExportLists) {}
493 onImportingSummaryImpl(Summary, Worklist);
494 while (!Worklist.
empty())
495 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
503 void computeImportForFunction(
535 static std::unique_ptr<ModuleImportsManager>
565 Filename = Filename.substr(0, Filename.find_last_of(
'.'));
567 auto SetIter = Workloads.
find(Filename);
569 if (SetIter == Workloads.end()) {
571 <<
" does not contain the root of any context.\n");
573 ModName, ImportList);
576 <<
" contains the root(s) of context(s).\n");
580 auto &ValueInfos = SetIter->second;
582 auto It = DefinedGVSummaries.
find(VI.getGUID());
583 if (It != DefinedGVSummaries.
end() &&
586 dbgs() <<
"[Workload] " << VI.name()
587 <<
" has the prevailing variant already in the module "
588 << ModName <<
". No need to import\n");
598 [&](
const auto &Candidate) {
600 <<
" from " << Candidate.second->modulePath()
601 <<
" ImportFailureReason: "
603 return Candidate.first ==
606 [](
const auto &Candidate) {
return Candidate.second; });
607 if (PotentialCandidates.empty()) {
609 <<
" because can't find eligible Callee. Guid is: "
610 << VI.getGUID() <<
"\n");
628 PotentialCandidates, [&](
const auto *Candidate) {
631 if (PrevailingCandidates.empty()) {
632 GVS = *PotentialCandidates.begin();
637 <<
"[Workload] Found multiple non-prevailing candidates for "
639 <<
". This is unexpected. Are module paths passed to the "
640 "compiler unique for the modules passed to the linker?");
649 GVS = *PrevailingCandidates.begin();
656 if (ExportingModule == ModName) {
658 <<
" because its defining module is the same as the "
662 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
663 << ExportingModule <<
" : " << VI.getGUID() <<
"\n");
667 (*ExportLists)[ExportingModule].insert(VI);
672 void loadFromJson() {
679 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
682 auto DbgReportIfAmbiguous = [&](
StringRef Name) {
684 dbgs() <<
"[Workload] Function name " << Name
685 <<
" present in the workload definition is ambiguous. Consider "
686 "compiling with -funique-internal-linkage-names.";
691 if (std::error_code EC = BufferOrErr.getError()) {
695 auto Buffer = std::move(BufferOrErr.get());
696 std::map<std::string, std::vector<std::string>> WorkloadDefs;
709 for (
const auto &Workload : WorkloadDefs) {
710 const auto &Root = Workload.first;
711 DbgReportIfAmbiguous(Root);
713 const auto &AllCallees = Workload.second;
714 auto RootIt = NameToValueInfo.
find(Root);
715 if (RootIt == NameToValueInfo.
end()) {
717 <<
" not found in this linkage unit.\n");
720 auto RootVI = RootIt->second;
721 if (RootVI.getSummaryList().size() != 1) {
723 <<
" should have exactly one summary, but has "
724 << RootVI.getSummaryList().size() <<
". Skipping.\n");
728 RootVI.getSummaryList().
front()->modulePath();
729 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
730 <<
" is : " << RootDefiningModule <<
"\n");
731 auto &Set = Workloads[RootDefiningModule];
732 for (
const auto &Callee : AllCallees) {
734 DbgReportIfAmbiguous(Callee);
735 auto ElemIt = NameToValueInfo.
find(Callee);
736 if (ElemIt == NameToValueInfo.
end()) {
740 Set.insert(ElemIt->second);
745 void loadFromCtxProf() {
748 if (std::error_code EC = BufferOrErr.getError()) {
752 auto Buffer = std::move(BufferOrErr.get());
760 const auto &CtxMap = Ctx->Contexts;
762 for (
const auto &[RootGuid, Root] : CtxMap) {
765 ContainedGUIDs.
clear();
767 auto RootVI =
Index.getValueInfo(RootGuid);
770 <<
" not found in this linkage unit.\n");
773 if (RootVI.getSummaryList().size() != 1) {
775 <<
" should have exactly one summary, but has "
776 << RootVI.getSummaryList().size() <<
". Skipping.\n");
779 std::string RootDefiningModule =
780 RootVI.getSummaryList().front()->modulePath().str();
782 RootDefiningModule = std::to_string(RootGuid);
784 dbgs() <<
"[Workload] Moving " << RootGuid
785 <<
" to a module with the filename without extension : "
786 << RootDefiningModule <<
"\n");
788 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << RootGuid
789 <<
" is : " << RootDefiningModule <<
"\n");
791 auto &Set = Workloads[RootDefiningModule];
792 Root.getContainedGuids(ContainedGUIDs);
793 Roots.insert(RootVI);
794 for (
auto Guid : ContainedGUIDs)
811 "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
819 for (
const auto &[Root, Set] : Workloads) {
820 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
821 <<
" distinct callees.\n";
822 for (
const auto &VI : Set) {
823 dbgs() <<
"[Workload] Root: " << Root
824 <<
" Would include: " << VI.getGUID() <<
"\n";
837 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
838 return std::unique_ptr<ModuleImportsManager>(
841 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
858 return "InterposableLinkage";
860 return "LocalLinkageNotInModule";
862 return "NotEligible";
872void ModuleImportsManager::computeImportForFunction(
873 const FunctionSummary &Summary,
const unsigned Threshold,
875 SmallVectorImpl<EdgeInfo> &Worklist, GlobalsImporter &GVImporter,
876 FunctionImporter::ImportMapTy &ImportList,
879 static int ImportCount = 0;
881 ValueInfo
VI =
Edge.first;
882 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
891 if (DefinedGVSummaries.
count(
VI.getGUID())) {
895 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
899 if (!canImport(VI)) {
901 dbgs() <<
"Skipping over " <<
VI.getGUID()
902 <<
" because its import is handled in a different module.");
903 assert(
VI.getSummaryList().size() == 1 &&
904 "The root was expected to be an external symbol");
918 const auto NewThreshold =
919 Threshold * GetBonusMultiplier(
Edge.second.getHotness());
921 auto IT = ImportThresholds.insert(std::make_pair(
922 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
923 bool PreviouslyVisited = !
IT.second;
924 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
925 auto &CalleeSummary = std::get<1>(
IT.first->second);
926 auto &FailureInfo = std::get<2>(
IT.first->second);
930 bool IsCriticalCallsite =
933 const FunctionSummary *ResolvedCalleeSummary =
nullptr;
935 assert(PreviouslyVisited);
940 if (NewThreshold <= ProcessedThreshold) {
942 dbgs() <<
"ignored! Target was already imported with Threshold "
943 << ProcessedThreshold <<
"\n");
947 ProcessedThreshold = NewThreshold;
952 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
954 dbgs() <<
"ignored! Target was already rejected with Threshold "
955 << ProcessedThreshold <<
"\n");
958 "Expected FailureInfo for previously rejected candidate");
959 FailureInfo->Attempts++;
967 const GlobalValueSummary *SummaryForDeclImport =
nullptr;
970 Summary.modulePath(), SummaryForDeclImport, Reason);
971 if (!CalleeSummary) {
975 StringRef DeclSourceModule = SummaryForDeclImport->
modulePath();
984 if (PreviouslyVisited) {
985 ProcessedThreshold = NewThreshold;
988 "Expected FailureInfo for previously rejected candidate");
989 FailureInfo->Reason = Reason;
990 FailureInfo->Attempts++;
991 FailureInfo->MaxHotness =
992 std::max(FailureInfo->MaxHotness,
Edge.second.getHotness());
996 "Expected no FailureInfo for newly rejected candidate");
997 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
998 VI,
Edge.second.getHotness(), Reason, 1);
1001 std::string Msg = std::string(
"Failed to import function ") +
1002 VI.name().str() +
" due to " +
1007 "Error importing module: ");
1011 <<
"ignored! No qualifying callee with summary found.\n");
1017 CalleeSummary = CalleeSummary->getBaseObject();
1021 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
1022 "selectCallee() didn't honor the threshold");
1024 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
1030 NumImportedFunctionsThinLink++;
1032 NumImportedHotFunctionsThinLink++;
1033 if (IsCriticalCallsite)
1034 NumImportedCriticalFunctionsThinLink++;
1041 (*ExportLists)[ExportModulePath].insert(VI);
1044 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
1053 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
1058 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
1074 for (
const auto &GVSummary : DefinedGVSummaries) {
1078 auto VI =
Index.getValueInfo(GVSummary.first);
1080 if (!
Index.isGlobalValueLive(GVSummary.second)) {
1090 computeImportForFunction(*FuncSummary,
ImportInstrLimit, DefinedGVSummaries,
1091 Worklist, GVI, ImportList, ImportThresholds);
1095 while (!Worklist.
empty()) {
1097 auto *Summary = std::get<0>(GVInfo);
1098 auto Threshold = std::get<1>(GVInfo);
1101 computeImportForFunction(*FS, Threshold, DefinedGVSummaries, Worklist,
1102 GVI, ImportList, ImportThresholds);
1108 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
1109 for (
auto &
I : ImportThresholds) {
1110 auto &ProcessedThreshold = std::get<0>(
I.second);
1111 auto &CalleeSummary = std::get<1>(
I.second);
1112 auto &FailureInfo = std::get<2>(
I.second);
1117 if (!FailureInfo->VI.getSummaryList().empty())
1119 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
1120 dbgs() << FailureInfo->VI
1122 <<
", Threshold = " << ProcessedThreshold
1123 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
1125 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1132 auto SL = VI.getSummaryList();
1140 if (
const auto &VI = Index.getValueInfo(
G))
1149 unsigned NumGVS = 0;
1150 for (
auto &VI : ExportSet)
1168 for (
const auto &[FromModule, GUID,
Type] : ImportList) {
1187 for (
const auto &ImportPerModule : ImportLists)
1188 for (
const auto &[FromModule, GUID, ImportType] : ImportPerModule.second)
1189 FlattenedImports.
insert(GUID);
1197 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1200 Index.findSummaryInModule(VI, ModulePath));
1201 return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) &&
1207 for (
auto &ExportPerModule : ExportLists)
1208 for (
auto &VI : ExportPerModule.second)
1209 if (!FlattenedImports.
count(VI.getGUID()) &&
1210 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1227 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1228 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1230 << DefinedGVSummaries.first <<
"'\n");
1231 MIS->computeImportForModule(DefinedGVSummaries.second,
1232 DefinedGVSummaries.first, ImportList);
1240 for (
auto &ELI : ExportLists) {
1244 const auto &DefinedGVSummaries =
1245 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1246 for (
auto &EI : ELI.second) {
1253 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1257 auto *S = DS->getSecond();
1258 S = S->getBaseObject();
1264 if (!Index.isWriteOnly(GVS))
1276 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1277 if (!DefinedGVSummaries.
count(EI->getGUID()))
1278 NewExports.
erase(EI++);
1282 ELI.second.insert_range(NewExports);
1289 for (
const auto &ModuleImports : ImportLists) {
1290 auto ModName = ModuleImports.first;
1291 auto &Exports = ExportLists[ModName];
1296 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1297 <<
" vars. Imports from " << Histogram.
size()
1299 for (
const auto &[SrcModName,
Stats] : Histogram) {
1301 <<
" function definitions and "
1303 <<
" function declarations imported from " << SrcModName
1306 <<
" global vars imported from " << SrcModName <<
"\n");
1318 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1319 << Histogram.
size() <<
" modules.\n");
1320 for (
const auto &[SrcModName,
Stats] : Histogram) {
1322 <<
" function definitions and "
1324 <<
" function declarations imported from " << SrcModName
1327 << SrcModName <<
"\n");
1349 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1352 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1354 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1369 for (
const auto &GlobalList : Index) {
1371 if (GlobalList.second.SummaryList.empty())
1374 auto GUID = GlobalList.first;
1375 assert(GlobalList.second.SummaryList.size() == 1 &&
1376 "Expected individual combined index to have one summary per GUID");
1377 auto &Summary = GlobalList.second.SummaryList[0];
1380 if (Summary->modulePath() == ModulePath)
1383 ImportList.
addGUID(Summary->modulePath(), GUID, Summary->importType());
1396 for (
auto &EI : FS->mutableCalls()) {
1397 if (!EI.first.getSummaryList().empty())
1399 auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());
1403 auto VI = Index.getValueInfo(GUID);
1405 VI.getSummaryList(),
1406 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1416 return SummaryPtr->getSummaryKind() ==
1417 GlobalValueSummary::GlobalVarKind;
1425 for (
const auto &Entry : Index) {
1426 for (
const auto &S : Entry.second.SummaryList) {
1437 assert(!Index.withGlobalValueDeadStripping());
1440 GUIDPreservedSymbols.
empty()) {
1445 unsigned LiveSymbols = 0;
1447 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1448 for (
auto GUID : GUIDPreservedSymbols) {
1449 ValueInfo VI = Index.getValueInfo(GUID);
1452 for (
const auto &S : VI.getSummaryList())
1457 for (
const auto &Entry : Index) {
1458 auto VI = Index.getValueInfo(Entry);
1459 for (
const auto &S : Entry.second.SummaryList) {
1483 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1494 bool KeepAliveLinkage =
false;
1495 bool Interposable =
false;
1496 for (
const auto &S : VI.getSummaryList()) {
1500 KeepAliveLinkage =
true;
1502 Interposable =
true;
1506 if (!KeepAliveLinkage)
1511 "Interposable and available_externally/linkonce_odr/weak_odr "
1516 for (
const auto &S : VI.getSummaryList())
1522 while (!Worklist.
empty()) {
1524 for (
const auto &Summary : VI.getSummaryList()) {
1529 visit(AS->getAliaseeVI(),
true);
1532 for (
auto Ref : Summary->refs())
1535 for (
auto Call : FS->calls())
1539 Index.setWithGlobalValueDeadStripping();
1541 unsigned DeadSymbols = Index.size() - LiveSymbols;
1542 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1543 <<
" symbols Dead \n");
1544 NumDeadSymbols += DeadSymbols;
1545 NumLiveSymbols += LiveSymbols;
1553 bool ImportEnabled) {
1558 Index.propagateAttributes(GUIDPreservedSymbols);
1570 ModuleToSummariesForIndex[std::string(ModulePath)] =
1571 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1580 auto It = Map.find(
Key);
1581 if (It == Map.end())
1582 std::tie(It, std::ignore) =
1588 for (
const auto &[FromModule, GUID, ImportType] : ImportList) {
1589 auto &SummariesForIndex =
1590 LookupOrCreate(ModuleToSummariesForIndex, FromModule);
1592 const auto &DefinedGVSummaries = ModuleToDefinedGVSummaries.
at(FromModule);
1593 const auto &DS = DefinedGVSummaries.
find(GUID);
1594 assert(DS != DefinedGVSummaries.
end() &&
1595 "Expected a defined summary for imported global value");
1597 DecSummaries.insert(DS->second);
1599 SummariesForIndex[GUID] = DS->second;
1613 [&](
StringRef M) { ImportsOS << M <<
"\n"; });
1623 for (
const auto &ILI : ModuleToSummariesForIndex)
1627 if (ILI.first != ModulePath)
1637 F->setComdat(
nullptr);
1639 V->setInitializer(
nullptr);
1642 V->setComdat(
nullptr);
1671 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1673 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1674 if (GS == DefinedGlobals.
end())
1681 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1682 F->setDoesNotAccessMemory();
1684 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1685 F->setOnlyReadsMemory();
1687 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1688 F->setDoesNotRecurse();
1690 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1691 F->setDoesNotThrow();
1695 auto NewLinkage = GS->second->linkage();
1734 GS->second->canAutoHide()) {
1740 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1748 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1749 if (GO->getComdat()->getName() == GO->getName())
1750 NonPrevailingComdats.
insert(GO->getComdat());
1751 GO->setComdat(
nullptr);
1756 for (
auto &GV : TheModule)
1758 for (
auto &GV : TheModule.
globals())
1759 FinalizeInModule(GV);
1760 for (
auto &GV : TheModule.
aliases())
1761 FinalizeInModule(GV);
1766 if (NonPrevailingComdats.
empty())
1769 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1770 GO.setComdat(
nullptr);
1781 for (
auto &GA : TheModule.
aliases()) {
1782 if (GA.hasAvailableExternallyLinkage())
1785 assert(Obj &&
"aliasee without an base object is unimplemented");
1800 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1810 auto GS = DefinedGlobals.
find(GV.getGUID());
1811 if (GS == DefinedGlobals.
end()) {
1822 GS = DefinedGlobals.
find(
1824 if (GS == DefinedGlobals.
end()) {
1831 GS = DefinedGlobals.
find(
1862 for (
auto &GV : M.globals())
1865 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1877 unsigned ImportedCount = 0, ImportedGVCount = 0;
1884 for (
auto &
F : DestModule)
1885 if (!
F.isDeclaration() && MoveSymbolGUIDSet.
contains(
F.getGUID()))
1895 if (!SrcModuleOrErr)
1897 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1899 "Context mismatch");
1903 if (
Error Err = SrcModule->materializeMetadata())
1904 return std::move(Err);
1913 auto GUID =
F.getGUID();
1914 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1915 bool ImportDefinition =
1919 <<
" importing function"
1920 << (ImportDefinition
1922 : (MaybeImportType ?
" declaration " :
" "))
1923 << GUID <<
" " <<
F.getName() <<
" from "
1924 << SrcModule->getSourceFileName() <<
"\n");
1925 if (ImportDefinition) {
1926 if (
Error Err =
F.materialize())
1927 return std::move(Err);
1934 "thinlto_src_module",
1936 {MDString::get(DestModule.getContext(),
1937 SrcModule->getModuleIdentifier())}));
1941 {MDString::get(DestModule.getContext(),
1942 SrcModule->getSourceFileName())}));
1953 auto GUID = GV.getGUID();
1954 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1955 bool ImportDefinition =
1959 <<
" importing global"
1960 << (ImportDefinition
1962 : (MaybeImportType ?
" declaration " :
" "))
1963 << GUID <<
" " << GV.getName() <<
" from "
1964 << SrcModule->getSourceFileName() <<
"\n");
1965 if (ImportDefinition) {
1966 if (
Error Err = GV.materialize())
1967 return std::move(Err);
1968 ImportedGVCount += GlobalsToImport.
insert(&GV);
1977 auto GUID = GA.getGUID();
1978 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1979 bool ImportDefinition =
1983 <<
" importing alias"
1984 << (ImportDefinition
1986 : (MaybeImportType ?
" declaration " :
" "))
1987 << GUID <<
" " << GA.getName() <<
" from "
1988 << SrcModule->getSourceFileName() <<
"\n");
1989 if (ImportDefinition) {
1990 if (
Error Err = GA.materialize())
1991 return std::move(Err);
1995 return std::move(Err);
1998 <<
" " << GO->
getName() <<
" from "
1999 << SrcModule->getSourceFileName() <<
"\n");
2004 "thinlto_src_module",
2006 {MDString::get(DestModule.getContext(),
2007 SrcModule->getModuleIdentifier())}));
2011 {MDString::get(DestModule.getContext(),
2012 SrcModule->getSourceFileName())}));
2014 GlobalsToImport.
insert(Fn);
2027 SrcModule->setPartialSampleProfileRatio(Index);
2034 for (
const auto *GV : GlobalsToImport)
2036 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
2039 if (
Error Err = Mover.
move(std::move(SrcModule),
2043 Twine(
"Function Import: link error: ") +
2046 ImportedCount += GlobalsToImport.
size();
2047 NumImportedModules++;
2052 NumImportedFunctions += (ImportedCount - ImportedGVCount);
2053 NumImportedGlobalVars += ImportedGVCount;
2056 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
2057 <<
" functions for Module "
2060 <<
" global variables for Module "
2062 return ImportedCount;
2072 if (!IndexPtrOrErr) {
2077 std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
2087 *Index, ImportList);
2090 isPrevailing, *Index, ImportList);
2096 for (
auto &
I : *Index) {
2097 for (
auto &S :
I.second.SummaryList) {
2109 auto ModuleLoader = [&M](
StringRef Identifier) {
2110 return loadFile(std::string(Identifier), M.getContext());
2119 "Error importing module: ");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
static auto qualifyCalleeCandidates(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, StringRef CallerModulePath)
Given a list of possible callee implementation for a call site, qualify the legality of importing eac...
static cl::opt< bool > EnableImportMetadata("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'"))
static cl::opt< float > ImportColdMultiplier("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"))
static DenseMap< StringRef, ImportStatistics > collectImportStatistics(const ModuleSummaryIndex &Index, const FunctionImporter::ImportMapTy &ImportList)
static cl::opt< float > ImportHotMultiplier("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"))
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, FunctionImporter::ExportSetTy &ExportSet)
static bool checkVariableImport(const ModuleSummaryIndex &Index, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
static bool doImportingForModuleForTest(Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
static cl::opt< float > ImportHotInstrFactor("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static cl::opt< float > ImportCriticalMultiplier("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for critical callsites"))
static cl::opt< int > ImportCutoff("import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)"))
cl::opt< std::string > UseCtxProfile
static cl::opt< bool > CtxprofMoveRootsToOwnModule("thinlto-move-ctxprof-trees", cl::desc("Move contextual profiling roots and the graphs under them in " "their own module."), cl::Hidden, cl::init(false))
static const char * getFailureName(FunctionImporter::ImportFailureReason Reason)
static cl::opt< float > ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
cl::list< GlobalValue::GUID > MoveSymbolGUID
static void internalizeGVsAfterImport(Module &M)
static cl::opt< bool > PrintImports("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions"))
void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, FunctionSummary *FS)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
cl::opt< bool > ForceImportAll("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute"))
static bool shouldSkipLocalInAnotherModule(const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
static cl::opt< unsigned > ImportInstrLimit("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
static cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy ...
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
static cl::opt< std::string > SummaryFile("summary-file", cl::desc("The summary file to use for function importing."))
Summary file to use for function importing when using -function-import from the command line.
static cl::opt< bool > ImportAllIndex("import-all-index", cl::desc("Import all external functions in index."))
Used when testing importing from distributed indexes via opt.
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void dumpImportListForModule(const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleFromIndexForTest(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold fo...
static void ComputeCrossModuleImportForModuleForTest(StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
cl::opt< bool > ForceImportAll
block placement Basic Block Placement Stats
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
Reader for contextual iFDO profile, which comes in bitstream format.
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Import globals referenced by a function or other globals that are being imported, if importing such g...
void onImportingSummary(const GlobalValueSummary &Summary)
GlobalsImporter(const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
virtual bool canImport(ValueInfo VI)
DenseMap< StringRef, FunctionImporter::ExportSetTy > *const ExportLists
virtual ~ModuleImportsManager()=default
static std::unique_ptr< ModuleImportsManager > create(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing
ModuleImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
const ModuleSummaryIndex & Index
virtual void computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName, FunctionImporter::ImportMapTy &ImportList)
Given the list of globals defined in a module, compute the list of imports as well as the list of "ex...
WorkloadImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
The map maintains the list of imports.
LLVM_ABI AddDefinitionStatus addDefinition(StringRef FromModule, GlobalValue::GUID GUID)
void addGUID(StringRef FromModule, GlobalValue::GUID GUID, GlobalValueSummary::ImportKind ImportKind)
LLVM_ABI SmallVector< StringRef, 0 > getSourceModules() const
LLVM_ABI std::optional< GlobalValueSummary::ImportKind > getImportType(StringRef FromModule, GlobalValue::GUID GUID) const
LLVM_ABI void maybeAddDeclaration(StringRef FromModule, GlobalValue::GUID GUID)
The function importer is automatically importing function from other modules based on the provided su...
LLVM_ABI Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
DenseMap< GlobalValue::GUID, std::tuple< unsigned, const GlobalValueSummary *, std::unique_ptr< ImportFailureInfo > > > ImportThresholdsTy
Map of callee GUID considered for import into a given module to a pair consisting of the largest thre...
ImportFailureReason
The different reasons selectCallee will chose not to import a candidate.
@ LocalLinkageNotInModule
DenseSet< ValueInfo > ExportSetTy
The set contains an entry for every global value that the module exports.
Function summary information to aid decisions and implementation of importing.
unsigned instCount() const
Get the instruction count recorded for this function.
FFlags fflags() const
Get function summary flags.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
LLVM_ABI const GlobalObject * getAliaseeObject() const
Function and variable summary information to aid decisions and implementation of importing.
StringRef modulePath() const
Get the path to the module containing this function.
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const GlobalObject * getAliaseeObject() const
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
LLVM_ABI Error materialize()
Make sure this GlobalValue is fully read.
LLVM_ABI bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
bool hasAvailableExternallyLinkage() const
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
LLVM_ABI Error move(std::unique_ptr< Module > Src, ArrayRef< GlobalValue * > ValuesToLink, LazyCallback AddLazyFor, bool IsPerformingImport)
Move in the provide values in ValuesToLink from Src.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static StringRef getOriginalNameBeforePromote(StringRef Name)
Helper to obtain the unpromoted name for a global value (or the original name if not promoted).
A Module instance is used to store all the information related to an LLVM module.
LLVMContext & getContext() const
Get the global data context.
const std::string & getSourceFileName() const
Get the module's original source file name.
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
iterator_range< global_object_iterator > global_objects()
LLVM_ABI Expected< PGOCtxProfile > loadProfiles()
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
A vector that has set insertion semantics.
ArrayRef< value_type > getArrayRef() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isFunctionTy() const
True if this is an instance of FunctionType.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
The root is the trivial Path to the root value.
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
bool fromJSON(const Value &E, std::string &Out, Path P)
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
std::error_code make_error_code(BitcodeError E)
const char * getHotnessName(CalleeInfo::HotnessType HT)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
LLVM_ABI 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...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto map_range(ContainerTy &&C, FuncTy F)
LLVM_ABI 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.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI void computeDeadSymbolsAndUpdateIndirectCalls(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing)
Compute all the symbols that are "dead": i.e these that can't be reached in the graph from any of the...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI void updateIndirectCalls(ModuleSummaryIndex &Index)
Update call edges for indirect calls to local functions added from SamplePGO when needed.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
LLVM_ABI std::unique_ptr< Module > getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given file holds a bitcode image, return a Module for it which does lazy deserialization of fu...
LLVM_ABI void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
LLVM_ABI 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::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
PrevailingType
PrevailingType enum used as a return type of callback passed to computeDeadSymbolsAndUpdateIndirectCa...
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
LLVM_ABI Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
LLVM_ABI 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.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
LLVM_ABI Expected< std::unique_ptr< ModuleSummaryIndex > > getModuleSummaryIndexForFile(StringRef Path, bool IgnoreEmptyThinLTOIndexFile=false)
Parse the module summary index out of an IR file and return the module summary index object if found,...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
Struct that holds a reference to a particular GUID in a global value summary.