51#include <system_error>
57#define DEBUG_TYPE "function-import"
60 "Number of functions thin link decided to import");
62 "Number of hot functions thin link decided to import");
64 "Number of critical functions thin link decided to import");
66 "Number of global variables thin link decided to import");
67STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
69 "Number of global variables imported in backend");
70STATISTIC(NumImportedModules,
"Number of modules imported from");
71STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
72STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
77 cl::desc(
"Only import functions with less than N instructions"));
81 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
85 cl::desc(
"Import functions with noinline attribute"));
90 cl::desc(
"As we import functions, multiply the "
91 "`import-instr-limit` threshold by this factor "
92 "before processing newly imported functions"));
97 cl::desc(
"As we import functions called from hot callsite, multiply the "
98 "`import-instr-limit` threshold by this factor "
99 "before processing newly imported functions"));
103 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
109 "Multiply the `import-instr-limit` threshold for critical callsites"));
114 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
117 cl::desc(
"Print imported functions"));
121 cl::desc(
"Print information for functions rejected for importing"));
128 cl::desc(
"Enable import metadata like 'thinlto_src_module' and "
129 "'thinlto_src_file'"));
135 cl::desc(
"The summary file to use for function importing."));
141 cl::desc(
"Import all external functions in index."));
151 cl::desc(
"If true, import function declaration as fallback if the function "
152 "definition is not imported."));
163 "thinlto-workload-def",
164 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
165 "dictionary. The keys are root functions, the values are lists of "
166 "functions to import in the module defining the root. It is "
167 "assumed -funique-internal-linkage-names was used, to ensure "
168 "local linkage functions have unique names. For example: \n"
170 " \"rootFunction_1\": [\"function_to_import_1\", "
171 "\"function_to_import_2\"], \n"
172 " \"rootFunction_2\": [\"function_to_import_3\", "
173 "\"function_to_import_4\"] \n"
184static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
190 std::unique_ptr<Module> Result =
194 Err.print(
"function-import",
errs());
223 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
227 [&
Index, CalleeSummaryList,
228 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
231 auto *GVSummary = SummaryPtr.get();
232 if (!
Index.isGlobalValueLive(GVSummary))
233 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
236 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
239 auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());
247 return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};
264 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
269 if (Summary->notEligibleToImport())
270 return {FunctionImporter::ImportFailureReason::NotEligible,
273 return {FunctionImporter::ImportFailureReason::None, GVSummary};
294 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
295 unsigned Threshold,
StringRef CallerModulePath,
299 TooLargeOrNoInlineSummary =
nullptr;
300 auto QualifiedCandidates =
302 for (
auto QualifiedValue : QualifiedCandidates) {
303 Reason = QualifiedValue.first;
305 if (Reason != FunctionImporter::ImportFailureReason::None)
308 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
312 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
314 TooLargeOrNoInlineSummary = Summary;
315 Reason = FunctionImporter::ImportFailureReason::TooLarge;
321 TooLargeOrNoInlineSummary = Summary;
322 Reason = FunctionImporter::ImportFailureReason::NoInline;
347 bool shouldImportGlobal(
const ValueInfo &VI) {
348 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
349 if (GVS == DefinedGVSummaries.
end())
361 if (VI.getSummaryList().size() > 1 &&
363 !IsPrevailing(VI.getGUID(), GVS->second))
372 for (
const auto &VI : Summary.refs()) {
373 if (!shouldImportGlobal(VI)) {
375 dbgs() <<
"Ref ignored! Target already in destination module.\n");
381 for (
const auto &RefSummary : VI.getSummaryList()) {
382 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
388 if (!GVS || !
Index.canImportGlobalVar(GVS,
true) ||
390 Summary.modulePath()))
395 auto [Iter, Inserted] =
406 NumImportedGlobalVarsThinLink++;
411 (*ExportLists)[RefSummary->modulePath()].insert(VI);
415 if (!
Index.isWriteOnly(GVS))
429 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
430 IsPrevailing(IsPrevailing), ImportList(ImportList),
431 ExportLists(ExportLists) {}
435 onImportingSummaryImpl(Summary, Worklist);
436 while (!Worklist.
empty())
437 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
469 static std::unique_ptr<ModuleImportsManager>
490 auto SetIter = Workloads.
find(ModName);
491 if (SetIter == Workloads.
end()) {
493 <<
" does not contain the root of any context.\n");
495 ModName, ImportList);
498 <<
" contains the root(s) of context(s).\n");
502 auto &ValueInfos = SetIter->second;
505 auto It = DefinedGVSummaries.
find(VI.getGUID());
506 if (It != DefinedGVSummaries.
end() &&
509 dbgs() <<
"[Workload] " << VI.name()
510 <<
" has the prevailing variant already in the module "
511 << ModName <<
". No need to import\n");
521 [&](
const auto &Candidate) {
523 <<
" from " << Candidate.second->modulePath()
524 <<
" ImportFailureReason: "
526 return Candidate.first ==
527 FunctionImporter::ImportFailureReason::None;
529 [](
const auto &Candidate) {
return Candidate.second; });
530 if (PotentialCandidates.empty()) {
532 <<
" because can't find eligible Callee. Guid is: "
533 << Function::getGUID(VI.name()) <<
"\n");
551 PotentialCandidates, [&](
const auto *Candidate) {
554 if (PrevailingCandidates.empty()) {
555 GVS = *PotentialCandidates.begin();
560 <<
"[Workload] Found multiple non-prevailing candidates for "
562 <<
". This is unexpected. Are module paths passed to the "
563 "compiler unique for the modules passed to the linker?");
572 GVS = *PrevailingCandidates.begin();
579 if (ExportingModule == ModName) {
581 <<
" because its defining module is the same as the "
585 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
586 << ExportingModule <<
" : "
587 << Function::getGUID(VI.name()) <<
"\n");
588 ImportList[ExportingModule][VI.getGUID()] =
592 (*ExportLists)[ExportingModule].insert(VI);
597 void loadFromJson() {
604 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
609 dbgs() <<
"[Workload] Function name " << Name
610 <<
" present in the workload definition is ambiguous. Consider "
611 "compiling with -funique-internal-linkage-names.";
616 if (std::error_code EC = BufferOrErr.getError()) {
620 auto Buffer = std::move(BufferOrErr.get());
621 std::map<std::string, std::vector<std::string>> WorkloadDefs;
634 for (
const auto &Workload : WorkloadDefs) {
635 const auto &Root = Workload.first;
636 DbgReportIfAmbiguous(Root);
638 const auto &AllCallees = Workload.second;
639 auto RootIt = NameToValueInfo.
find(Root);
640 if (RootIt == NameToValueInfo.
end()) {
642 <<
" not found in this linkage unit.\n");
645 auto RootVI = RootIt->second;
646 if (RootVI.getSummaryList().size() != 1) {
648 <<
" should have exactly one summary, but has "
649 << RootVI.getSummaryList().size() <<
". Skipping.\n");
653 RootVI.getSummaryList().
front()->modulePath();
654 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
655 <<
" is : " << RootDefiningModule <<
"\n");
656 auto &Set = Workloads[RootDefiningModule];
657 for (
const auto &Callee : AllCallees) {
659 DbgReportIfAmbiguous(Callee);
660 auto ElemIt = NameToValueInfo.
find(Callee);
661 if (ElemIt == NameToValueInfo.
end()) {
665 Set.insert(ElemIt->second);
670 void loadFromCtxProf() {
673 if (std::error_code EC = BufferOrErr.getError()) {
677 auto Buffer = std::move(BufferOrErr.get());
685 const auto &CtxMap = *Ctx;
687 for (
const auto &[RootGuid, Root] : CtxMap) {
690 ContainedGUIDs.
clear();
692 auto RootVI =
Index.getValueInfo(RootGuid);
695 <<
" not found in this linkage unit.\n");
698 if (RootVI.getSummaryList().size() != 1) {
700 <<
" should have exactly one summary, but has "
701 << RootVI.getSummaryList().size() <<
". Skipping.\n");
705 RootVI.getSummaryList().
front()->modulePath();
706 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << RootGuid
707 <<
" is : " << RootDefiningModule <<
"\n");
708 auto &Set = Workloads[RootDefiningModule];
709 Root.getContainedGuids(ContainedGUIDs);
710 for (
auto Guid : ContainedGUIDs)
725 "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
733 for (
const auto &[Root, Set] : Workloads) {
734 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
735 <<
" distinct callees.\n";
736 for (
const auto &VI : Set) {
737 dbgs() <<
"[Workload] Root: " << Root
738 <<
" Would include: " << VI.getGUID() <<
"\n";
751 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
752 return std::unique_ptr<ModuleImportsManager>(
755 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
763 case FunctionImporter::ImportFailureReason::None:
765 case FunctionImporter::ImportFailureReason::GlobalVar:
767 case FunctionImporter::ImportFailureReason::NotLive:
769 case FunctionImporter::ImportFailureReason::TooLarge:
771 case FunctionImporter::ImportFailureReason::InterposableLinkage:
772 return "InterposableLinkage";
773 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
774 return "LocalLinkageNotInModule";
775 case FunctionImporter::ImportFailureReason::NotEligible:
776 return "NotEligible";
777 case FunctionImporter::ImportFailureReason::NoInline:
788 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
796 static int ImportCount = 0;
797 for (
const auto &Edge : Summary.calls()) {
799 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
808 if (DefinedGVSummaries.
count(VI.getGUID())) {
812 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
817 if (Hotness == CalleeInfo::HotnessType::Hot)
819 if (Hotness == CalleeInfo::HotnessType::Cold)
821 if (Hotness == CalleeInfo::HotnessType::Critical)
826 const auto NewThreshold =
827 Threshold * GetBonusMultiplier(Edge.second.getHotness());
829 auto IT = ImportThresholds.
insert(std::make_pair(
830 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
831 bool PreviouslyVisited = !
IT.second;
832 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
833 auto &CalleeSummary = std::get<1>(
IT.first->second);
834 auto &FailureInfo = std::get<2>(
IT.first->second);
837 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
838 bool IsCriticalCallsite =
839 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
843 assert(PreviouslyVisited);
848 if (NewThreshold <= ProcessedThreshold) {
850 dbgs() <<
"ignored! Target was already imported with Threshold "
851 << ProcessedThreshold <<
"\n");
855 ProcessedThreshold = NewThreshold;
856 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
860 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
862 dbgs() <<
"ignored! Target was already rejected with Threshold "
863 << ProcessedThreshold <<
"\n");
866 "Expected FailureInfo for previously rejected candidate");
867 FailureInfo->Attempts++;
878 Summary.modulePath(), SummaryForDeclImport, Reason);
879 if (!CalleeSummary) {
896 if (PreviouslyVisited) {
897 ProcessedThreshold = NewThreshold;
900 "Expected FailureInfo for previously rejected candidate");
901 FailureInfo->Reason = Reason;
902 FailureInfo->Attempts++;
903 FailureInfo->MaxHotness =
904 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
908 "Expected no FailureInfo for newly rejected candidate");
909 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
910 VI, Edge.second.getHotness(), Reason, 1);
913 std::string Msg = std::string(
"Failed to import function ") +
914 VI.name().str() +
" due to " +
916 auto Error = make_error<StringError>(
919 "Error importing module: ");
923 <<
"ignored! No qualifying callee with summary found.\n");
929 CalleeSummary = CalleeSummary->getBaseObject();
930 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
933 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
934 "selectCallee() didn't honor the threshold");
936 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
940 auto [Iter, Inserted] = ImportList[ExportModulePath].
try_emplace(
946 NumImportedFunctionsThinLink++;
948 NumImportedHotFunctionsThinLink++;
949 if (IsCriticalCallsite)
950 NumImportedCriticalFunctionsThinLink++;
960 (*ExportLists)[ExportModulePath].insert(VI);
963 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
972 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
977 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
993 for (
const auto &GVSummary : DefinedGVSummaries) {
997 auto VI =
Index.getValueInfo(GVSummary.first);
999 if (!
Index.isGlobalValueLive(GVSummary.second)) {
1004 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
1015 while (!Worklist.
empty()) {
1017 auto *Summary = std::get<0>(GVInfo);
1018 auto Threshold = std::get<1>(GVInfo);
1020 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
1029 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
1030 for (
auto &
I : ImportThresholds) {
1031 auto &ProcessedThreshold = std::get<0>(
I.second);
1032 auto &CalleeSummary = std::get<1>(
I.second);
1033 auto &FailureInfo = std::get<2>(
I.second);
1038 if (!FailureInfo->VI.getSummaryList().empty())
1039 FS = dyn_cast<FunctionSummary>(
1040 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
1041 dbgs() << FailureInfo->VI
1043 <<
", Threshold = " << ProcessedThreshold
1044 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
1046 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1053 auto SL = VI.getSummaryList();
1061 if (
const auto &VI =
Index.getValueInfo(
G))
1070 unsigned NumGVS = 0;
1071 for (
auto &VI : ExportSet)
1082 unsigned &DefinedFS) {
1083 unsigned NumGVS = 0;
1085 for (
auto &[GUID,
Type] : ImportMap) {
1102 for (
auto &ImportPerModule : ImportLists)
1103 for (
auto &ExportPerModule : ImportPerModule.second)
1104 for (
auto &[GUID,
Type] : ExportPerModule.second)
1105 FlattenedImports.
insert(GUID);
1113 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1115 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
1116 Index.findSummaryInModule(VI, ModulePath));
1117 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
1123 for (
auto &ExportPerModule : ExportLists)
1124 for (
auto &VI : ExportPerModule.second)
1125 if (!FlattenedImports.
count(VI.getGUID()) &&
1126 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1143 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1144 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1146 << DefinedGVSummaries.first <<
"'\n");
1147 MIS->computeImportForModule(DefinedGVSummaries.second,
1148 DefinedGVSummaries.first, ImportList);
1156 for (
auto &ELI : ExportLists) {
1160 const auto &DefinedGVSummaries =
1161 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1162 for (
auto &EI : ELI.second) {
1169 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1173 auto *S = DS->getSecond();
1174 S = S->getBaseObject();
1175 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1180 if (!
Index.isWriteOnly(GVS))
1181 for (
const auto &VI : GVS->refs())
1184 auto *FS = cast<FunctionSummary>(S);
1185 for (
const auto &Edge : FS->calls())
1186 NewExports.
insert(Edge.first);
1187 for (
const auto &
Ref : FS->refs())
1195 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1196 if (!DefinedGVSummaries.
count(EI->getGUID()))
1197 NewExports.
erase(EI++);
1201 ELI.second.insert(NewExports.
begin(), NewExports.
end());
1208 for (
auto &ModuleImports : ImportLists) {
1209 auto ModName = ModuleImports.first;
1210 auto &Exports = ExportLists[ModName];
1213 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1214 <<
" vars. Imports from " << ModuleImports.second.size()
1216 for (
auto &Src : ModuleImports.second) {
1217 auto SrcModName = Src.first;
1218 unsigned DefinedFS = 0;
1219 unsigned NumGVSPerMod =
1221 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1222 << Src.second.size() - NumGVSPerMod - DefinedFS
1223 <<
" function declarations imported from " << SrcModName
1226 <<
" global vars imported from " << SrcModName <<
"\n");
1236 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1237 << ImportList.
size() <<
" modules.\n");
1238 for (
auto &Src : ImportList) {
1239 auto SrcModName = Src.first;
1240 unsigned DefinedFS = 0;
1242 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1243 << Src.second.size() - DefinedFS - NumGVSPerMod
1244 <<
" function declarations imported from " << SrcModName
1246 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
1247 << SrcModName <<
"\n");
1269 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1272 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1274 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1289 for (
const auto &GlobalList :
Index) {
1291 if (GlobalList.second.SummaryList.empty())
1294 auto GUID = GlobalList.first;
1295 assert(GlobalList.second.SummaryList.size() == 1 &&
1296 "Expected individual combined index to have one summary per GUID");
1297 auto &Summary = GlobalList.second.SummaryList[0];
1300 if (Summary->modulePath() == ModulePath)
1303 auto [Iter, Inserted] = ImportList[Summary->modulePath()].
try_emplace(
1304 GUID, Summary->importType());
1308 Iter->second = std::min(Iter->second, Summary->importType());
1322 for (
auto &EI : FS->mutableCalls()) {
1323 if (!EI.first.getSummaryList().empty())
1325 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
1329 auto VI =
Index.getValueInfo(GUID);
1331 VI.getSummaryList(),
1332 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1342 return SummaryPtr->getSummaryKind() ==
1343 GlobalValueSummary::GlobalVarKind;
1351 for (
const auto &Entry :
Index) {
1352 for (
const auto &S : Entry.second.SummaryList) {
1353 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1366 GUIDPreservedSymbols.
empty()) {
1371 unsigned LiveSymbols = 0;
1373 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1374 for (
auto GUID : GUIDPreservedSymbols) {
1378 for (
const auto &S : VI.getSummaryList())
1383 for (
const auto &Entry :
Index) {
1384 auto VI =
Index.getValueInfo(Entry);
1385 for (
const auto &S : Entry.second.SummaryList) {
1386 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1398 auto visit = [&](
ValueInfo VI,
bool IsAliasee) {
1409 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1419 if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
1420 bool KeepAliveLinkage =
false;
1421 bool Interposable =
false;
1422 for (
const auto &S : VI.getSummaryList()) {
1426 KeepAliveLinkage =
true;
1428 Interposable =
true;
1432 if (!KeepAliveLinkage)
1437 "Interposable and available_externally/linkonce_odr/weak_odr "
1442 for (
const auto &S : VI.getSummaryList())
1448 while (!Worklist.
empty()) {
1450 for (
const auto &Summary : VI.getSummaryList()) {
1451 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1455 visit(AS->getAliaseeVI(),
true);
1458 for (
auto Ref : Summary->refs())
1460 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1461 for (
auto Call : FS->calls())
1462 visit(Call.first,
false);
1465 Index.setWithGlobalValueDeadStripping();
1467 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1468 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1469 <<
" symbols Dead \n");
1470 NumDeadSymbols += DeadSymbols;
1471 NumLiveSymbols += LiveSymbols;
1479 bool ImportEnabled) {
1483 Index.propagateAttributes(GUIDPreservedSymbols);
1492 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
1495 ModuleToSummariesForIndex[std::string(ModulePath)] =
1496 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1498 for (
const auto &ILI : ImportList) {
1499 auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];
1501 const auto &DefinedGVSummaries =
1502 ModuleToDefinedGVSummaries.
lookup(ILI.first);
1503 for (
const auto &[GUID,
Type] : ILI.second) {
1504 const auto &DS = DefinedGVSummaries.
find(GUID);
1505 assert(DS != DefinedGVSummaries.
end() &&
1506 "Expected a defined summary for imported global value");
1508 DecSummaries.insert(DS->second);
1510 SummariesForIndex[GUID] = DS->second;
1518 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1523 for (
const auto &ILI : ModuleToSummariesForIndex)
1527 if (ILI.first != ModulePath)
1528 ImportsOS << ILI.first <<
"\n";
1529 return std::error_code();
1535 if (
Function *
F = dyn_cast<Function>(&GV)) {
1538 F->setComdat(
nullptr);
1540 V->setInitializer(
nullptr);
1543 V->setComdat(
nullptr);
1571 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1573 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1574 if (GS == DefinedGlobals.
end())
1579 if (
Function *
F = dyn_cast<Function>(&GV)) {
1581 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1582 F->setDoesNotAccessMemory();
1584 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1585 F->setOnlyReadsMemory();
1587 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1588 F->setDoesNotRecurse();
1590 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1591 F->setDoesNotThrow();
1595 auto NewLinkage = GS->second->linkage();
1634 GS->second->canAutoHide()) {
1640 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1647 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1648 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1649 if (GO->getComdat()->getName() == GO->getName())
1650 NonPrevailingComdats.
insert(GO->getComdat());
1651 GO->setComdat(
nullptr);
1656 for (
auto &GV : TheModule)
1658 for (
auto &GV : TheModule.
globals())
1659 FinalizeInModule(GV);
1660 for (
auto &GV : TheModule.
aliases())
1661 FinalizeInModule(GV);
1666 if (NonPrevailingComdats.
empty())
1669 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1670 GO.setComdat(
nullptr);
1681 for (
auto &GA : TheModule.
aliases()) {
1682 if (GA.hasAvailableExternallyLinkage())
1685 assert(Obj &&
"aliasee without an base object is unimplemented");
1699 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1703 if (isa<GlobalIFunc>(&GV) ||
1704 (isa<GlobalAlias>(&GV) &&
1705 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1709 auto GS = DefinedGlobals.
find(GV.getGUID());
1710 if (GS == DefinedGlobals.
end()) {
1722 if (GS == DefinedGlobals.
end()) {
1759 for (
auto &GV : M.globals())
1762 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1774 unsigned ImportedCount = 0, ImportedGVCount = 0;
1778 std::set<StringRef> ModuleNameOrderedList;
1779 for (
const auto &FunctionsToImportPerModule : ImportList) {
1780 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);
1785 -> std::optional<GlobalValueSummary::ImportKind> {
1786 auto Iter = GUIDToImportType.find(GUID);
1787 if (Iter == GUIDToImportType.end())
1788 return std::nullopt;
1789 return Iter->second;
1792 for (
const auto &
Name : ModuleNameOrderedList) {
1794 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1795 assert(FunctionsToImportPerModule != ImportList.
end());
1797 if (!SrcModuleOrErr)
1799 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1801 "Context mismatch");
1805 if (
Error Err = SrcModule->materializeMetadata())
1806 return std::move(Err);
1808 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1815 auto GUID =
F.getGUID();
1816 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1818 bool ImportDefinition =
1823 <<
" importing function"
1824 << (ImportDefinition
1826 : (MaybeImportType ?
" declaration " :
" "))
1827 << GUID <<
" " <<
F.getName() <<
" from "
1828 << SrcModule->getSourceFileName() <<
"\n");
1829 if (ImportDefinition) {
1830 if (
Error Err =
F.materialize())
1831 return std::move(Err);
1838 "thinlto_src_module",
1840 {MDString::get(DestModule.getContext(),
1841 SrcModule->getModuleIdentifier())}));
1845 {MDString::get(DestModule.getContext(),
1846 SrcModule->getSourceFileName())}));
1854 auto GUID = GV.getGUID();
1855 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1857 bool ImportDefinition =
1862 <<
" importing global"
1863 << (ImportDefinition
1865 : (MaybeImportType ?
" declaration " :
" "))
1866 << GUID <<
" " << GV.getName() <<
" from "
1867 << SrcModule->getSourceFileName() <<
"\n");
1868 if (ImportDefinition) {
1869 if (
Error Err = GV.materialize())
1870 return std::move(Err);
1871 ImportedGVCount += GlobalsToImport.
insert(&GV);
1875 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1877 auto GUID = GA.getGUID();
1878 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1880 bool ImportDefinition =
1885 <<
" importing alias"
1886 << (ImportDefinition
1888 : (MaybeImportType ?
" declaration " :
" "))
1889 << GUID <<
" " << GA.getName() <<
" from "
1890 << SrcModule->getSourceFileName() <<
"\n");
1891 if (ImportDefinition) {
1892 if (
Error Err = GA.materialize())
1893 return std::move(Err);
1897 return std::move(Err);
1901 << SrcModule->getSourceFileName() <<
"\n");
1906 "thinlto_src_module",
1908 {MDString::get(DestModule.getContext(),
1909 SrcModule->getModuleIdentifier())}));
1913 {MDString::get(DestModule.getContext(),
1914 SrcModule->getSourceFileName())}));
1916 GlobalsToImport.
insert(Fn);
1928 SrcModule->setPartialSampleProfileRatio(
Index);
1936 for (
const auto *GV : GlobalsToImport)
1938 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1941 if (
Error Err = Mover.
move(std::move(SrcModule),
1945 Twine(
"Function Import: link error: ") +
1948 ImportedCount += GlobalsToImport.
size();
1949 NumImportedModules++;
1954 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1955 NumImportedGlobalVars += ImportedGVCount;
1958 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1959 <<
" functions for Module "
1962 <<
" global variables for Module "
1964 return ImportedCount;
1974 if (!IndexPtrOrErr) {
1979 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1988 *
Index, ImportList);
1991 isPrevailing, *
Index, ImportList);
1998 for (
auto &S :
I.second.SummaryList) {
2008 errs() <<
"Error renaming module\n";
2013 auto ModuleLoader = [&M](
StringRef Identifier) {
2014 return loadFile(std::string(Identifier), M.getContext());
2023 "Error importing module: ");
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 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 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, DenseMap< StringRef, FunctionImporter::ImportMapTy > &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 void computeImportForFunction(const FunctionSummary &Summary, const ModuleSummaryIndex &Index, const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, SmallVectorImpl< EdgeInfo > &Worklist, GlobalsImporter &GVImporter, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists, FunctionImporter::ImportThresholdsTy &ImportThresholds)
Compute the list of functions to import for a given caller.
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 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"))
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)
static 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.
This file supports working with JSON data.
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...
Module.h This file contains the declarations for the Module class.
Reader for contextual iFDO profile, which comes in bitstream format.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Determine the list of imports and exports for each module.
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...
A ModuleImportsManager that operates based on a workload definition (see -thinlto-workload-def).
WorkloadImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
A container for analyses that lazily runs them and caches their results.
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)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
The function importer is automatically importing function from other modules based on the provided su...
Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
std::unordered_map< GlobalValue::GUID, GlobalValueSummary::ImportKind > FunctionsToImportTy
The functions to import from a source module and their import type.
ImportFailureReason
The different reasons selectCallee will chose not to import a candidate.
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)
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.
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
static bool isLocalLinkage(LinkageTypes Linkage)
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)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
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...
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.
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.
Error materialize()
Make sure this GlobalValue is fully read.
bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
bool hasAvailableExternallyLinkage() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
@ 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
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()
Expected< std::map< GlobalValue::GUID, PGOCtxProfContext > > loadContexts()
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.
bool insert(const value_type &X)
Insert a new element into the SetVector.
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.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
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)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
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)
This is an optimization pass for GlobalISel generic memory operations.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
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)
std::error_code EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
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...
bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto map_range(ContainerTy &&C, FuncTy F)
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
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 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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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...
void updateIndirectCalls(ModuleSummaryIndex &Index)
Update call edges for indirect calls to local functions added from SamplePGO when needed.
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.
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...
void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
PrevailingType
PrevailingType enum used as a return type of callback passed to computeDeadSymbolsAndUpdateIndirectCa...
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
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.
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,...
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.