57#include <system_error>
63#define DEBUG_TYPE "function-import"
66 "Number of functions thin link decided to import");
68 "Number of hot functions thin link decided to import");
70 "Number of critical functions thin link decided to import");
72 "Number of global variables thin link decided to import");
73STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
75 "Number of function declarations thin link decided to import because "
76 "the callee is required in the caller's module (e.g. for MemProf "
79 "Number of function declarations imported in backend");
81 "Number of global variables imported in backend");
82STATISTIC(NumImportedModules,
"Number of modules imported from");
83STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
84STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
91 cl::desc(
"Import functions with noinline attribute"));
96 cl::desc(
"Only import functions with less than N instructions"));
100 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
105 cl::desc(
"As we import functions, multiply the "
106 "`import-instr-limit` threshold by this factor "
107 "before processing newly imported functions"));
112 cl::desc(
"As we import functions called from hot callsite, multiply the "
113 "`import-instr-limit` threshold by this factor "
114 "before processing newly imported functions"));
118 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
124 "Multiply the `import-instr-limit` threshold for critical callsites"));
129 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
133 cl::desc(
"Print information for functions rejected for importing"));
146 cl::desc(
"If true, import function declaration as fallback if the function "
147 "definition is not imported."));
155 cl::desc(
"If true, import a declaration of the target of an indirect call "
156 "edge (and export it from its defining module) when its "
157 "definition is not imported."));
161 "import-declaration-for-indirect-calls-min-hotness",
163 cl::desc(
"Minimum hotness of an indirect call edge for "
164 "-import-declaration-for-indirect-calls to import a "
165 "declaration of its target."),
167 "Any edge, including ones without profile"),
169 "Cold or hotter edges"),
171 "Edges that are not cold"),
173 "Hot or critical edges"),
175 "Critical edges only")));
186 "thinlto-workload-def",
187 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
188 "dictionary. The keys are root functions, the values are lists of "
189 "functions to import in the module defining the root. It is "
190 "assumed -funique-internal-linkage-names was used, to ensure "
191 "local linkage functions have unique names. For example: \n"
193 " \"rootFunction_1\": [\"function_to_import_1\", "
194 "\"function_to_import_2\"], \n"
195 " \"rootFunction_2\": [\"function_to_import_3\", "
196 "\"function_to_import_4\"] \n"
203 "thinlto-move-ctxprof-trees",
204 cl::desc(
"Move contextual profiling roots and the graphs under them in "
205 "their own module."),
214static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
220 std::unique_ptr<Module> Result =
224 Err.print(
"function-import",
errs());
253 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
257 [&Index, CalleeSummaryList,
258 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
261 auto *GVSummary = SummaryPtr.get();
262 if (!Index.isGlobalValueLive(GVSummary))
299 if (Summary->notEligibleToImport())
324 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
325 unsigned Threshold,
StringRef CallerModulePath,
329 TooLargeOrNoInlineSummary =
nullptr;
330 auto QualifiedCandidates =
332 for (
auto QualifiedValue : QualifiedCandidates) {
333 Reason = QualifiedValue.first;
342 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
344 TooLargeOrNoInlineSummary = Summary;
351 TooLargeOrNoInlineSummary = Summary;
370 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
371 if (!Imports.insert(Def).second)
383 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
386 if (!Imports.contains(Def))
387 Imports.insert(Decl);
393 for (
const auto &[SrcMod, GUID, ImportType] : *
this)
400std::optional<GlobalValueSummary::ImportKind>
403 if (
auto IDPair = IDs.getImportIDs(FromModule, GUID)) {
404 auto [Def, Decl] = *IDPair;
405 if (Imports.contains(Def))
407 if (Imports.contains(Decl))
424 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
425 if (GVS == DefinedGVSummaries.end())
442 if (VI.getSummaryList().size() > 1 &&
444 !IsPrevailing(VI.getGUID(), GVS->second))
453 for (
const auto &VI : Summary.refs()) {
454 if (!shouldImportGlobal(VI, Summary.modulePath())) {
456 dbgs() <<
"Ref ignored! Target already in destination module.\n");
462 for (
const auto &RefSummary : VI.getSummaryList()) {
480 bool CanImportDecl =
false;
482 Summary.modulePath()) ||
483 !Index.canImportGlobalVar(GVS,
true,
486 ImportList.maybeAddDeclaration(RefSummary->modulePath(),
494 if (ImportList.addDefinition(RefSummary->modulePath(), VI.getGUID()) !=
500 NumImportedGlobalVarsThinLink++;
505 (*ExportLists)[RefSummary->modulePath()].insert(VI);
509 if (!Index.isWriteOnly(GVS))
523 : Index(Index), DefinedGVSummaries(DefinedGVSummaries),
524 IsPrevailing(IsPrevailing), ImportList(ImportList),
525 ExportLists(ExportLists) {}
529 onImportingSummaryImpl(Summary, Worklist);
530 while (!Worklist.
empty())
531 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
539 void computeImportForFunction(
584 void addRequiredDeclaration(
ValueInfo VI,
605 static std::unique_ptr<ModuleImportsManager>
639 if (SetIter == Workloads.end()) {
641 <<
" does not contain the root of any context.\n");
643 ModName, ImportList);
646 <<
" contains the root(s) of context(s).\n");
650 auto &ValueInfos = SetIter->second;
652 auto It = DefinedGVSummaries.
find(VI.getGUID());
653 if (It != DefinedGVSummaries.
end() &&
656 dbgs() <<
"[Workload] " << VI.name()
657 <<
" has the prevailing variant already in the module "
658 << ModName <<
". No need to import\n");
668 [&](
const auto &Candidate) {
670 <<
" from " << Candidate.second->modulePath()
671 <<
" ImportFailureReason: "
673 return Candidate.first ==
676 [](
const auto &Candidate) {
return Candidate.second; });
677 if (PotentialCandidates.empty()) {
679 <<
" because can't find eligible Callee. Guid is: "
680 << VI.getGUID() <<
"\n");
698 PotentialCandidates, [&](
const auto *Candidate) {
701 if (PrevailingCandidates.empty()) {
702 GVS = *PotentialCandidates.begin();
707 <<
"[Workload] Found multiple non-prevailing candidates for "
709 <<
". This is unexpected. Are module paths passed to the "
710 "compiler unique for the modules passed to the linker?");
719 GVS = *PrevailingCandidates.begin();
726 if (ExportingModule == ModName) {
728 <<
" because its defining module is the same as the "
732 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
733 << ExportingModule <<
" : " << VI.getGUID() <<
"\n");
737 (*ExportLists)[ExportingModule].insert(VI);
742 void loadFromJson() {
749 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
752 auto DbgReportIfAmbiguous = [&](
StringRef Name) {
754 dbgs() <<
"[Workload] Function name " << Name
755 <<
" present in the workload definition is ambiguous. Consider "
756 "compiling with -funique-internal-linkage-names.";
761 if (std::error_code EC = BufferOrErr.getError()) {
765 auto Buffer = std::move(BufferOrErr.get());
766 std::map<std::string, std::vector<std::string>> WorkloadDefs;
779 for (
const auto &Workload : WorkloadDefs) {
780 const auto &Root = Workload.first;
781 DbgReportIfAmbiguous(Root);
783 const auto &AllCallees = Workload.second;
784 auto RootIt = NameToValueInfo.
find(Root);
785 if (RootIt == NameToValueInfo.
end()) {
787 <<
" not found in this linkage unit.\n");
790 auto RootVI = RootIt->second;
791 if (RootVI.getSummaryList().size() != 1) {
793 <<
" should have exactly one summary, but has "
794 << RootVI.getSummaryList().size() <<
". Skipping.\n");
798 RootVI.getSummaryList().
front()->modulePath();
799 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
800 <<
" is : " << RootDefiningModule <<
"\n");
801 auto &Set = Workloads[RootDefiningModule];
802 for (
const auto &Callee : AllCallees) {
804 DbgReportIfAmbiguous(Callee);
805 auto ElemIt = NameToValueInfo.
find(Callee);
806 if (ElemIt == NameToValueInfo.
end()) {
810 Set.insert(ElemIt->second);
815 void loadFromCtxProf() {
818 if (std::error_code EC = BufferOrErr.getError()) {
822 auto Buffer = std::move(BufferOrErr.get());
830 const auto &CtxMap = Ctx->Contexts;
832 for (
const auto &[RootGuid, Root] : CtxMap) {
835 ContainedGUIDs.
clear();
837 auto RootVI =
Index.getValueInfo(RootGuid);
840 <<
" not found in this linkage unit.\n");
843 if (RootVI.getSummaryList().size() != 1) {
845 <<
" should have exactly one summary, but has "
846 << RootVI.getSummaryList().size() <<
". Skipping.\n");
849 std::string RootDefiningModule =
850 RootVI.getSummaryList().front()->modulePath().str();
852 RootDefiningModule = std::to_string(RootGuid);
854 dbgs() <<
"[Workload] Moving " << RootGuid
855 <<
" to a module with the filename without extension : "
856 << RootDefiningModule <<
"\n");
858 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << RootGuid
859 <<
" is : " << RootDefiningModule <<
"\n");
861 auto &Set = Workloads[RootDefiningModule];
862 Root.getContainedGuids(ContainedGUIDs);
863 Roots.insert(RootVI);
864 for (
auto Guid : ContainedGUIDs)
881 "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
889 for (
const auto &[Root, Set] : Workloads) {
890 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
891 <<
" distinct callees.\n";
892 for (
const auto &VI : Set) {
893 dbgs() <<
"[Workload] Root: " << Root
894 <<
" Would include: " << VI.getGUID() <<
"\n";
907 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
908 return std::unique_ptr<ModuleImportsManager>(
911 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
928 return "InterposableLinkage";
930 return "LocalLinkageNotInModule";
932 return "NotEligible";
942void ModuleImportsManager::computeImportForFunction(
943 const FunctionSummary &Summary,
const unsigned Threshold,
945 SmallVectorImpl<EdgeInfo> &Worklist, GlobalsImporter &GVImporter,
946 FunctionImporter::ImportMapTy &ImportList,
949 static int ImportCount = 0;
951 ValueInfo
VI =
Edge.first;
952 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
969 const bool RequiresDeclImport =
970 Edge.second.requiresDeclImport() ||
971 (
Edge.second.hasIndirectCall() &&
974 Edge.second.getHotness() >=
982 if (RequiresDeclImport && !DefinedGVSummaries.
count(
VI.getGUID()))
983 importRequiredDeclaration(VI,
Summary.modulePath(), ImportList);
987 if (DefinedGVSummaries.
count(
VI.getGUID())) {
991 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
995 if (!canImport(VI)) {
997 dbgs() <<
"Skipping over " <<
VI.getGUID()
998 <<
" because its import is handled in a different module.");
999 assert(
VI.getSummaryList().size() == 1 &&
1000 "The root was expected to be an external symbol");
1014 const auto NewThreshold =
1015 Threshold * GetBonusMultiplier(
Edge.second.getHotness());
1017 auto IT = ImportThresholds.insert(std::make_pair(
1018 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
1019 bool PreviouslyVisited = !
IT.second;
1020 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
1021 auto &CalleeSummary = std::get<1>(
IT.first->second);
1022 auto &FailureInfo = std::get<2>(
IT.first->second);
1024 bool IsHotCallsite =
1026 bool IsCriticalCallsite =
1029 const FunctionSummary *ResolvedCalleeSummary =
nullptr;
1030 if (CalleeSummary) {
1031 assert(PreviouslyVisited);
1036 if (NewThreshold <= ProcessedThreshold) {
1038 dbgs() <<
"ignored! Target was already imported with Threshold "
1039 << ProcessedThreshold <<
"\n");
1043 ProcessedThreshold = NewThreshold;
1048 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
1050 dbgs() <<
"ignored! Target was already rejected with Threshold "
1051 << ProcessedThreshold <<
"\n");
1054 "Expected FailureInfo for previously rejected candidate");
1055 FailureInfo->Attempts++;
1060 if (RequiresDeclImport)
1061 importRequiredDeclaration(VI,
Summary.modulePath(), ImportList);
1068 const GlobalValueSummary *SummaryForDeclImport =
nullptr;
1071 Summary.modulePath(), SummaryForDeclImport, Reason);
1072 if (!CalleeSummary) {
1075 if (SummaryForDeclImport) {
1076 if (RequiresDeclImport)
1078 addRequiredDeclaration(VI, SummaryForDeclImport, ImportList);
1087 if (PreviouslyVisited) {
1088 ProcessedThreshold = NewThreshold;
1091 "Expected FailureInfo for previously rejected candidate");
1092 FailureInfo->Reason = Reason;
1093 FailureInfo->Attempts++;
1094 FailureInfo->MaxHotness =
1095 std::max(FailureInfo->MaxHotness,
Edge.second.getHotness());
1099 "Expected no FailureInfo for newly rejected candidate");
1100 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
1101 VI,
Edge.second.getHotness(), Reason, 1);
1104 std::string
Msg = std::string(
"Failed to import function ") +
1105 VI.name().str() +
" due to " +
1110 "Error importing module: ");
1114 <<
"ignored! No qualifying callee with summary found.\n");
1120 CalleeSummary = CalleeSummary->getBaseObject();
1124 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
1125 "selectCallee() didn't honor the threshold");
1127 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
1133 NumImportedFunctionsThinLink++;
1135 NumImportedHotFunctionsThinLink++;
1136 if (IsCriticalCallsite)
1137 NumImportedCriticalFunctionsThinLink++;
1144 (*ExportLists)[ExportModulePath].insert(VI);
1147 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
1156 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
1161 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
1177 for (
const auto &GVSummary : DefinedGVSummaries) {
1181 auto VI =
Index.getValueInfo(GVSummary.first);
1183 if (!
Index.isGlobalValueLive(GVSummary.second)) {
1193 computeImportForFunction(*FuncSummary,
ImportInstrLimit, DefinedGVSummaries,
1194 Worklist, GVI, ImportList, ImportThresholds);
1198 while (!Worklist.
empty()) {
1200 auto *Summary = std::get<0>(GVInfo);
1201 auto Threshold = std::get<1>(GVInfo);
1203 computeImportForFunction(*Summary, Threshold, DefinedGVSummaries, Worklist,
1204 GVI, ImportList, ImportThresholds);
1210 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
1211 for (
auto &
I : ImportThresholds) {
1212 auto &ProcessedThreshold = std::get<0>(
I.second);
1213 auto &CalleeSummary = std::get<1>(
I.second);
1214 auto &FailureInfo = std::get<2>(
I.second);
1219 if (!FailureInfo->VI.getSummaryList().empty())
1221 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
1222 dbgs() << FailureInfo->VI
1224 <<
", Threshold = " << ProcessedThreshold
1225 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
1227 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1241 for (
auto [Reason, CandidateSummary] :
1245 "Expected only legality checks in qualifyCalleeCandidates");
1257 auto ExistingImportType = ImportList.
getImportType(SrcModule, VI.getGUID());
1262 if (!ExistingImportType) {
1264 NumRequiredDeclsThinLink++;
1277 auto SL = VI.getSummaryList();
1285 if (
const auto &VI = Index.getValueInfo(
G))
1294 unsigned NumGVS = 0;
1295 for (
auto &VI : ExportSet)
1313 for (
const auto &[FromModule, GUID,
Type] : ImportList) {
1332 for (
const auto &ImportPerModule : ImportLists)
1333 for (
const auto &[FromModule, GUID, ImportType] : ImportPerModule.second)
1334 FlattenedImports.
insert(GUID);
1342 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1345 Index.findSummaryInModule(VI, ModulePath));
1346 return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) &&
1352 for (
auto &ExportPerModule : ExportLists)
1353 for (
auto &VI : ExportPerModule.second)
1354 if (!FlattenedImports.
count(VI.getGUID()) &&
1355 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1372 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1373 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1375 << DefinedGVSummaries.first <<
"'\n");
1376 MIS->computeImportForModule(DefinedGVSummaries.second,
1377 DefinedGVSummaries.first, ImportList);
1385 for (
auto &ELI : ExportLists) {
1389 const auto &DefinedGVSummaries =
1390 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1391 for (
auto &EI : ELI.second) {
1398 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1402 auto *S = DS->getSecond();
1403 S = S->getBaseObject();
1409 if (!Index.isWriteOnly(GVS))
1422 [&](
ValueInfo VI) {
return !DefinedGVSummaries.
count(VI.getGUID()); });
1423 ELI.second.insert_range(NewExports);
1429 for (
auto &[ModPath, RequiredExports] : MIS->requiredDeclExports())
1436 for (
const auto &ModuleImports : ImportLists) {
1437 auto ModName = ModuleImports.first;
1438 auto &Exports = ExportLists[ModName];
1443 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1444 <<
" vars. Imports from " << Histogram.
size()
1446 for (
const auto &[SrcModName,
Stats] : Histogram) {
1448 <<
" function definitions and "
1450 <<
" function declarations imported from " << SrcModName
1453 <<
" global vars imported from " << SrcModName <<
"\n");
1465 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1466 << Histogram.
size() <<
" modules.\n");
1467 for (
const auto &[SrcModName,
Stats] : Histogram) {
1469 <<
" function definitions and "
1471 <<
" function declarations imported from " << SrcModName
1474 << SrcModName <<
"\n");
1496 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1499 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1501 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1516 for (
const auto &GlobalList : Index) {
1518 if (GlobalList.second.getSummaryList().empty())
1521 auto GUID = GlobalList.first;
1522 assert(GlobalList.second.getSummaryList().size() == 1 &&
1523 "Expected individual combined index to have one summary per GUID");
1524 auto &Summary = GlobalList.second.getSummaryList()[0];
1527 if (Summary->modulePath() == ModulePath)
1530 ImportList.
addGUID(Summary->modulePath(), GUID, Summary->importType());
1546 if (!CalleeVI || !CalleeVI.getSummaryList().empty())
1548 auto GUID = Index.getGUIDFromOriginalID(CalleeVI.getGUID());
1551 auto VI = Index.getValueInfo(GUID);
1553 VI.getSummaryList(),
1554 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1564 return SummaryPtr->getSummaryKind() ==
1565 GlobalValueSummary::GlobalVarKind;
1571 for (
auto &EI : FS->mutableCalls()) {
1573 if (
auto VI = GetUpdatedCallee(EI.first))
1584 if (FS->callsites().empty())
1586 for (
auto &CI : FS->mutableCallsites()) {
1587 if (
auto VI = GetUpdatedCallee(CI.Callee))
1593 for (
const auto &Entry : Index) {
1594 for (
const auto &S : Entry.second.getSummaryList()) {
1605 assert(!Index.withGlobalValueDeadStripping());
1608 GUIDPreservedSymbols.
empty()) {
1613 unsigned LiveSymbols = 0;
1615 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1616 for (
auto GUID : GUIDPreservedSymbols) {
1617 ValueInfo VI = Index.getValueInfo(GUID);
1620 for (
const auto &S : VI.getSummaryList())
1625 for (
const auto &Entry : Index) {
1626 auto VI = Index.getValueInfo(Entry);
1627 for (
const auto &S : Entry.second.getSummaryList()) {
1651 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1662 bool KeepAliveLinkage =
false;
1663 bool Interposable =
false;
1664 for (
const auto &S : VI.getSummaryList()) {
1668 KeepAliveLinkage =
true;
1670 Interposable =
true;
1674 if (!KeepAliveLinkage)
1679 "Interposable and available_externally/linkonce_odr/weak_odr "
1684 for (
const auto &S : VI.getSummaryList())
1690 while (!Worklist.
empty()) {
1692 for (
const auto &Summary : VI.getSummaryList()) {
1697 visit(AS->getAliaseeVI(),
true);
1700 for (
auto Ref : Summary->refs())
1703 for (
auto Call : FS->calls())
1707 Index.setWithGlobalValueDeadStripping();
1709 unsigned DeadSymbols = Index.size() - LiveSymbols;
1710 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1711 <<
" symbols Dead \n");
1712 NumDeadSymbols += DeadSymbols;
1713 NumLiveSymbols += LiveSymbols;
1721 bool ImportEnabled) {
1726 Index.propagateAttributes(GUIDPreservedSymbols);
1738 ModuleToSummariesForIndex[std::string(ModulePath)] =
1739 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1748 auto It = Map.find(
Key);
1749 if (It == Map.end())
1750 std::tie(It, std::ignore) =
1756 for (
const auto &[FromModule, GUID, ImportType] : ImportList) {
1757 auto &SummariesForIndex =
1758 LookupOrCreate(ModuleToSummariesForIndex, FromModule);
1760 const auto &DefinedGVSummaries = ModuleToDefinedGVSummaries.
at(FromModule);
1761 const auto &DS = DefinedGVSummaries.
find(GUID);
1762 assert(DS != DefinedGVSummaries.
end() &&
1763 "Expected a defined summary for imported global value");
1765 DecSummaries.
insert(DS->second);
1767 SummariesForIndex[GUID] = DS->second;
1783 for (
auto &[ModPath, SummariesForIndex] : ModuleToSummariesForIndex) {
1784 if (ModPath == ModulePath)
1786 auto It = ModuleToDefinedGVSummaries.
find(ModPath);
1787 if (It == ModuleToDefinedGVSummaries.
end())
1789 for (
const auto &[GUID, Summary] : It->second) {
1790 if (Summary->noRenameOnPromotion()) {
1791 DecSummaries.
insert(Summary);
1792 SummariesForIndex.try_emplace(GUID, Summary);
1809 [&](
StringRef M) { ImportsOS << M <<
"\n"; });
1819 for (
const auto &ILI : ModuleToSummariesForIndex)
1823 if (ILI.first != ModulePath)
1832 UniqueID = GO->getMetadata(LLVMContext::MD_guid);
1838 F->setMetadata(LLVMContext::MD_guid,
UniqueID);
1839 F->setComdat(
nullptr);
1841 V->setInitializer(
nullptr);
1845 V->setMetadata(LLVMContext::MD_guid,
UniqueID);
1846 V->setComdat(
nullptr);
1875 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1878 if (GS == DefinedGlobals.
end())
1885 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1886 F->setDoesNotAccessMemory();
1888 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1889 F->setOnlyReadsMemory();
1891 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1892 F->setDoesNotRecurse();
1894 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1895 F->setDoesNotThrow();
1899 auto NewLinkage = GS->second->linkage();
1938 GS->second->canAutoHide()) {
1944 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1952 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1953 if (GO->getComdat()->getName() == GO->getName())
1954 NonPrevailingComdats.
insert(GO->getComdat());
1955 GO->setComdat(
nullptr);
1960 for (
auto &GV : TheModule)
1962 for (
auto &GV : TheModule.
globals())
1963 FinalizeInModule(GV);
1964 for (
auto &GV : TheModule.
aliases())
1965 FinalizeInModule(GV);
1970 if (NonPrevailingComdats.
empty())
1973 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1974 GO.setComdat(
nullptr);
1985 for (
auto &GA : TheModule.
aliases()) {
1986 if (GA.hasAvailableExternallyLinkage())
1989 assert(Obj &&
"aliasee without an base object is unimplemented");
1990 if (Obj->hasAvailableExternallyLinkage()) {
2004 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
2014 auto GS = DefinedGlobals.
find(GV.getGUIDOrFallback());
2015 if (GS == DefinedGlobals.
end()) {
2026 GS = DefinedGlobals.
find(
2028 if (GS == DefinedGlobals.
end()) {
2035 GS = DefinedGlobals.
find(
2066 for (
auto &GV : M.globals())
2069 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
2083 if (!
F.hasAvailableExternallyLinkage() ||
2084 !
F.hasMetadata(LLVMContext::MD_implicit_ref))
2087 F.getMetadata(LLVMContext::MD_implicit_ref, MDs);
2089 auto *
Op = MD->getOperand(0).get();
2094 if (GV->hasAvailableExternallyLinkage() && Seen.
insert(GV).second)
2098 if (!ToProtect.
empty())
2109 unsigned ImportedCount = 0, ImportedGVCount = 0;
2116 for (
auto &
F : DestModule)
2117 if (!
F.isDeclaration() && MoveSymbolGUIDSet.
contains(
F.getGUIDOrFallback()))
2127 if (!SrcModuleOrErr)
2129 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
2131 "Context mismatch");
2135 if (
Error Err = SrcModule->materializeMetadata())
2136 return std::move(Err);
2148 auto GUID =
F.getGUIDOrFallback();
2149 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
2150 bool ImportDefinition =
2154 <<
" importing function"
2155 << (ImportDefinition
2157 : (MaybeImportType ?
" declaration " :
" "))
2158 << GUID <<
" " <<
F.getName() <<
" from "
2159 << SrcModule->getSourceFileName() <<
"\n");
2160 if (ImportDefinition) {
2161 if (
Error Err =
F.materialize())
2162 return std::move(Err);
2165 if (Opts.enable_import_metadata ||
2170 "thinlto_src_module",
2172 {MDString::get(DestModule.getContext(),
2173 SrcModule->getModuleIdentifier())}));
2177 {MDString::get(DestModule.getContext(),
2178 SrcModule->getSourceFileName())}));
2181 }
else if (MaybeImportType) {
2192 auto GUID = GV.getGUIDOrFallback();
2193 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
2194 bool ImportDefinition =
2198 <<
" importing global"
2199 << (ImportDefinition
2201 : (MaybeImportType ?
" declaration " :
" "))
2202 << GUID <<
" " << GV.getName() <<
" from "
2203 << SrcModule->getSourceFileName() <<
"\n");
2204 if (ImportDefinition) {
2205 if (
Error Err = GV.materialize())
2206 return std::move(Err);
2207 ImportedGVCount += GlobalsToImport.
insert(&GV);
2216 auto GUID = GA.getGUIDOrFallback();
2217 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
2218 bool ImportDefinition =
2222 <<
" importing alias"
2223 << (ImportDefinition
2225 : (MaybeImportType ?
" declaration " :
" "))
2226 << GUID <<
" " << GA.getName() <<
" from "
2227 << SrcModule->getSourceFileName() <<
"\n");
2228 if (ImportDefinition) {
2229 if (
Error Err = GA.materialize())
2230 return std::move(Err);
2234 return std::move(Err);
2240 <<
" " << GO->
getName() <<
" from "
2241 << SrcModule->getSourceFileName() <<
"\n");
2242 if (Opts.enable_import_metadata ||
2249 "thinlto_src_module",
2251 Ctx, SrcModule->getModuleIdentifier())}));
2255 Ctx, {
MDString::get(Ctx, SrcModule->getSourceFileName())}));
2257 "thinlto_alias_guid",
2261 GlobalsToImport.
insert(Fn);
2262 }
else if (MaybeImportType) {
2278 SrcModule->setPartialSampleProfileRatio(Index);
2298 for (
auto [GV, GUID] : DeclsToImport) {
2299 assert(!GV->hasLocalLinkage() &&
2300 "Expected imported declaration to be promoted");
2307 DeclInfos.
push_back({GV->getName().str(),
F->getFunctionType(),
2308 F->getAddressSpace(),
F->getCallingConv(),
2309 F->getAttributes(), GV->getVisibility(),
2310 GV->isDSOLocal(), GUID});
2313 if (Opts.print_imports) {
2314 for (
const auto *GV : GlobalsToImport)
2316 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
2319 if (
Error Err = Mover.
move(std::move(SrcModule),
2323 Twine(
"Function Import: link error: ") +
2326 ImportedCount += GlobalsToImport.
size();
2327 NumImportedModules++;
2341 for (
auto &DI : DeclInfos) {
2347 LLVMContext::MD_guid,
2350 {ConstantAsMetadata::get(ConstantInt::get(
2351 Type::getInt64Ty(DestModule.getContext()), DI.GUID))}));
2362 ExistingF && ExistingF->isDeclaration() &&
2363 !ExistingF->getMetadata(LLVMContext::MD_guid))
2368 DI.AddrSpace, DI.Name, &DestModule);
2369 F->setCallingConv(DI.CC);
2370 F->setAttributes(DI.Attrs);
2373 F->setVisibility(DI.Visibility);
2374 F->setDSOLocal(DI.DSOLocal);
2376 NumImportedFunctionDecls++;
2384 if (ImportedGVCount > 0)
2387 NumImportedFunctions += (ImportedCount - ImportedGVCount);
2388 NumImportedGlobalVars += ImportedGVCount;
2391 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
2392 <<
" functions for Module "
2395 <<
" global variables for Module "
2397 return ImportedCount;
2404 if (Opts.summary_file.empty())
2408 if (!IndexPtrOrErr) {
2410 "Error loading file '" + Opts.summary_file +
"': ");
2413 std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
2421 if (Opts.import_all_index)
2423 *Index, ImportList);
2426 isPrevailing, *Index, ImportList);
2432 for (
auto &
I : *Index) {
2433 for (
auto &S :
I.second.getSummaryList()) {
2435 S->setExternalLinkageForTest();
2445 auto ModuleLoader = [&M](
StringRef Identifier) {
2446 return loadFile(std::string(Identifier), M.getContext());
2455 "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")))
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
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 DenseMap< StringRef, ImportStatistics > collectImportStatistics(const ModuleSummaryIndex &Index, const FunctionImporter::ImportMapTy &ImportList)
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 const char * getFailureName(FunctionImporter::ImportFailureReason Reason)
static void internalizeGVsAfterImport(Module &M)
void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, FunctionSummary *FS)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
static bool shouldSkipLocalInAnotherModule(const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void protectImplicitRefGlobals(Module &M)
When a function carrying !implicit.ref is imported via ThinLTO, the referenced global arrives as avai...
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.
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...
static constexpr StringLiteral Filename
Reader for contextual iFDO profile, which comes in bitstream format.
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> 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)
void importRequiredDeclaration(ValueInfo VI, StringRef CallerModulePath, FunctionImporter::ImportMapTy &ImportList)
Import a declaration of the callee VI of a call edge requiring a declaration import (see RequiresDecl...
DenseMap< StringRef, FunctionImporter::ExportSetTy > *const ExportLists
void addRequiredDeclaration(ValueInfo VI, const GlobalValueSummary *DeclSummary, FunctionImporter::ImportMapTy &ImportList)
Import a declaration of the callee VI from the module containing DeclSummary, which must be a candida...
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
DenseMap< StringRef, FunctionImporter::ExportSetTy > RequiredDeclExports
DenseMap< StringRef, FunctionImporter::ExportSetTy > & requiredDeclExports()
Values that must be exported from their defining modules because declarations of them are required in...
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)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
void insert_range(Range &&R)
Inserts a range of 'std::pair<KeyT, ValueT>' values into the map.
ValueT & at(const_arg_type_t< KeyT > Val)
Return the entry for the specified key, or abort if no such entry exists.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value 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.
Class to represent function types.
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.
LLVM_ABI GUID getGUIDOrFallback() const
Return the GUID for this value if it has been assigned, otherwise fall back to computing it based on ...
ThreadLocalMode getThreadLocalMode() const
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
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.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ 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.
@ 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 LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
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()
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
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.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
char front() const
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.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
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)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void insert_range(Range &&R)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
bool remove_if(Predicate Pred)
Remove all elements for which Pred returns true.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
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.
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 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))
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
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"))
std::error_code make_error_code(BitcodeError E)
cl::list< GlobalValue::GUID > MoveSymbolGUID
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.
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 ...
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
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.
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.
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.
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"))
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
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)
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"))
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
const IPOOptions & getIPOOptions(const LLVMContext &C)
static cl::opt< CalleeInfo::HotnessType > ImportDeclarationForIndirectCallsMinHotness("import-declaration-for-indirect-calls-min-hotness", cl::init(CalleeInfo::HotnessType::Hot), cl::Hidden, cl::desc("Minimum hotness of an indirect call edge for " "-import-declaration-for-indirect-calls to import a " "declaration of its target."), cl::values(clEnumValN(CalleeInfo::HotnessType::Unknown, "unknown", "Any edge, including ones without profile"), clEnumValN(CalleeInfo::HotnessType::Cold, "cold", "Cold or hotter edges"), clEnumValN(CalleeInfo::HotnessType::None, "none", "Edges that are not cold"), clEnumValN(CalleeInfo::HotnessType::Hot, "hot", "Hot or critical edges"), clEnumValN(CalleeInfo::HotnessType::Critical, "critical", "Critical edges only")))
void sort(IteratorTy Start, IteratorTy End)
cl::opt< bool > AlwaysRenamePromotedLocals("always-rename-promoted-locals", cl::init(true), cl::Hidden, cl::desc("Always rename promoted locals."))
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...
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)"))
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.
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 void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
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 ...
cl::opt< bool > ForceImportAll
static cl::opt< bool > ImportDeclarationForIndirectCalls("import-declaration-for-indirect-calls", cl::init(false), cl::Hidden, cl::desc("If true, import a declaration of the target of an indirect call " "edge (and export it from its defining module) when its " "definition is not imported."))
Narrower form of -import-declaration for indirect call promotion: when the definition of a profiled i...
DWARFExpression::Operation Op
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.
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"))
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.
SmallPtrSet< GlobalValueSummary *, 0 > GVSummaryPtrSet
A set of global value summary pointers.
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.
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
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.