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");
76 cl::desc(
"Import functions with noinline attribute"));
81 cl::desc(
"Only import functions with less than N instructions"));
85 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
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"
180 "thinlto-move-ctxprof-trees",
181 cl::desc(
"Move contextual profiling roots and the graphs under them in "
182 "their own module."),
192static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
198 std::unique_ptr<Module> Result =
202 Err.print(
"function-import",
errs());
231 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
235 [&Index, CalleeSummaryList,
236 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
239 auto *GVSummary = SummaryPtr.get();
240 if (!Index.isGlobalValueLive(GVSummary))
241 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
244 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
247 auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());
255 return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};
272 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
277 if (Summary->notEligibleToImport())
278 return {FunctionImporter::ImportFailureReason::NotEligible,
281 return {FunctionImporter::ImportFailureReason::None, GVSummary};
302 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
303 unsigned Threshold,
StringRef CallerModulePath,
307 TooLargeOrNoInlineSummary =
nullptr;
308 auto QualifiedCandidates =
310 for (
auto QualifiedValue : QualifiedCandidates) {
311 Reason = QualifiedValue.first;
313 if (Reason != FunctionImporter::ImportFailureReason::None)
316 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
320 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
322 TooLargeOrNoInlineSummary = Summary;
323 Reason = FunctionImporter::ImportFailureReason::TooLarge;
329 TooLargeOrNoInlineSummary = Summary;
330 Reason = FunctionImporter::ImportFailureReason::NoInline;
349 if (!Imports.insert(Def).second)
361 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
364 if (!Imports.contains(Def))
365 Imports.insert(Decl);
371 for (
const auto &[SrcMod, GUID, ImportType] : *
this)
378std::optional<GlobalValueSummary::ImportKind>
381 if (
auto IDPair = IDs.getImportIDs(FromModule, GUID)) {
382 auto [Def, Decl] = *IDPair;
383 if (Imports.contains(Def))
385 if (Imports.contains(Decl))
401 bool shouldImportGlobal(
const ValueInfo &VI) {
402 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
403 if (GVS == DefinedGVSummaries.
end())
415 if (VI.getSummaryList().size() > 1 &&
417 !IsPrevailing(VI.getGUID(), GVS->second))
426 for (
const auto &VI : Summary.refs()) {
427 if (!shouldImportGlobal(VI)) {
429 dbgs() <<
"Ref ignored! Target already in destination module.\n");
435 for (
const auto &RefSummary : VI.getSummaryList()) {
436 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
442 bool CanImportDecl =
false;
445 Summary.modulePath()) ||
446 !
Index.canImportGlobalVar(GVS,
true,
457 if (ImportList.
addDefinition(RefSummary->modulePath(), VI.getGUID()) !=
458 FunctionImporter::ImportMapTy::AddDefinitionStatus::Inserted)
463 NumImportedGlobalVarsThinLink++;
468 (*ExportLists)[RefSummary->modulePath()].insert(VI);
472 if (!
Index.isWriteOnly(GVS))
486 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
487 IsPrevailing(IsPrevailing), ImportList(ImportList),
488 ExportLists(ExportLists) {}
492 onImportingSummaryImpl(Summary, Worklist);
493 while (!Worklist.
empty())
494 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
502 void computeImportForFunction(
520 : IsPrevailing(IsPrevailing),
Index(
Index), ExportLists(ExportLists) {}
534 static std::unique_ptr<ModuleImportsManager>
564 Filename = Filename.substr(0, Filename.find_last_of(
'.'));
566 auto SetIter = Workloads.
find(Filename);
568 if (SetIter == Workloads.
end()) {
570 <<
" does not contain the root of any context.\n");
572 ModName, ImportList);
575 <<
" contains the root(s) of context(s).\n");
579 auto &ValueInfos = SetIter->second;
581 auto It = DefinedGVSummaries.
find(VI.getGUID());
582 if (It != DefinedGVSummaries.
end() &&
583 IsPrevailing(VI.getGUID(), It->second)) {
585 dbgs() <<
"[Workload] " << VI.name()
586 <<
" has the prevailing variant already in the module "
587 << ModName <<
". No need to import\n");
597 [&](
const auto &Candidate) {
599 <<
" from " << Candidate.second->modulePath()
600 <<
" ImportFailureReason: "
602 return Candidate.first ==
603 FunctionImporter::ImportFailureReason::None;
605 [](
const auto &Candidate) {
return Candidate.second; });
606 if (PotentialCandidates.empty()) {
608 <<
" because can't find eligible Callee. Guid is: "
609 << VI.getGUID() <<
"\n");
627 PotentialCandidates, [&](
const auto *Candidate) {
628 return IsPrevailing(VI.getGUID(), Candidate);
630 if (PrevailingCandidates.empty()) {
631 GVS = *PotentialCandidates.begin();
636 <<
"[Workload] Found multiple non-prevailing candidates for "
638 <<
". This is unexpected. Are module paths passed to the "
639 "compiler unique for the modules passed to the linker?");
648 GVS = *PrevailingCandidates.begin();
655 if (ExportingModule == ModName) {
657 <<
" because its defining module is the same as the "
661 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
662 << ExportingModule <<
" : " << VI.getGUID() <<
"\n");
666 (*ExportLists)[ExportingModule].insert(VI);
671 void loadFromJson() {
678 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
683 dbgs() <<
"[Workload] Function name " << Name
684 <<
" present in the workload definition is ambiguous. Consider "
685 "compiling with -funique-internal-linkage-names.";
690 if (std::error_code EC = BufferOrErr.getError()) {
694 auto Buffer = std::move(BufferOrErr.get());
695 std::map<std::string, std::vector<std::string>> WorkloadDefs;
708 for (
const auto &Workload : WorkloadDefs) {
709 const auto &Root = Workload.first;
710 DbgReportIfAmbiguous(Root);
712 const auto &AllCallees = Workload.second;
713 auto RootIt = NameToValueInfo.
find(Root);
714 if (RootIt == NameToValueInfo.
end()) {
716 <<
" not found in this linkage unit.\n");
719 auto RootVI = RootIt->second;
720 if (RootVI.getSummaryList().size() != 1) {
722 <<
" should have exactly one summary, but has "
723 << RootVI.getSummaryList().size() <<
". Skipping.\n");
727 RootVI.getSummaryList().
front()->modulePath();
728 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
729 <<
" is : " << RootDefiningModule <<
"\n");
730 auto &Set = Workloads[RootDefiningModule];
731 for (
const auto &Callee : AllCallees) {
733 DbgReportIfAmbiguous(Callee);
734 auto ElemIt = NameToValueInfo.
find(Callee);
735 if (ElemIt == NameToValueInfo.
end()) {
739 Set.insert(ElemIt->second);
744 void loadFromCtxProf() {
747 if (std::error_code EC = BufferOrErr.getError()) {
751 auto Buffer = std::move(BufferOrErr.get());
759 const auto &CtxMap = Ctx->Contexts;
761 for (
const auto &[RootGuid, Root] : CtxMap) {
764 ContainedGUIDs.
clear();
766 auto RootVI =
Index.getValueInfo(RootGuid);
769 <<
" not found in this linkage unit.\n");
772 if (RootVI.getSummaryList().size() != 1) {
774 <<
" should have exactly one summary, but has "
775 << RootVI.getSummaryList().size() <<
". Skipping.\n");
778 std::string RootDefiningModule =
779 RootVI.getSummaryList().front()->modulePath().str();
781 RootDefiningModule = std::to_string(RootGuid);
783 dbgs() <<
"[Workload] Moving " << RootGuid
784 <<
" to a module with the filename without extension : "
785 << RootDefiningModule <<
"\n");
787 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << RootGuid
788 <<
" is : " << RootDefiningModule <<
"\n");
790 auto &Set = Workloads[RootDefiningModule];
791 Root.getContainedGuids(ContainedGUIDs);
793 for (
auto Guid : ContainedGUIDs)
810 "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
818 for (
const auto &[Root, Set] : Workloads) {
819 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
820 <<
" distinct callees.\n";
821 for (
const auto &VI : Set) {
822 dbgs() <<
"[Workload] Root: " << Root
823 <<
" Would include: " << VI.getGUID() <<
"\n";
836 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
837 return std::unique_ptr<ModuleImportsManager>(
840 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
841 return std::make_unique<WorkloadImportsManager>(IsPrevailing, Index,
857 return "InterposableLinkage";
859 return "LocalLinkageNotInModule";
861 return "NotEligible";
871void ModuleImportsManager::computeImportForFunction(
878 static int ImportCount = 0;
879 for (
const auto &Edge :
Summary.calls()) {
881 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
890 if (DefinedGVSummaries.
count(
VI.getGUID())) {
894 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
898 if (!canImport(VI)) {
900 dbgs() <<
"Skipping over " <<
VI.getGUID()
901 <<
" because its import is handled in a different module.");
902 assert(
VI.getSummaryList().size() == 1 &&
903 "The root was expected to be an external symbol");
917 const auto NewThreshold =
918 Threshold * GetBonusMultiplier(
Edge.second.getHotness());
920 auto IT = ImportThresholds.
insert(std::make_pair(
921 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
922 bool PreviouslyVisited = !
IT.second;
923 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
924 auto &CalleeSummary = std::get<1>(
IT.first->second);
925 auto &FailureInfo = std::get<2>(
IT.first->second);
929 bool IsCriticalCallsite =
934 assert(PreviouslyVisited);
939 if (NewThreshold <= ProcessedThreshold) {
941 dbgs() <<
"ignored! Target was already imported with Threshold "
942 << ProcessedThreshold <<
"\n");
946 ProcessedThreshold = NewThreshold;
947 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
951 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
953 dbgs() <<
"ignored! Target was already rejected with Threshold "
954 << ProcessedThreshold <<
"\n");
957 "Expected FailureInfo for previously rejected candidate");
958 FailureInfo->Attempts++;
969 Summary.modulePath(), SummaryForDeclImport, Reason);
970 if (!CalleeSummary) {
983 if (PreviouslyVisited) {
984 ProcessedThreshold = NewThreshold;
987 "Expected FailureInfo for previously rejected candidate");
988 FailureInfo->Reason = Reason;
989 FailureInfo->Attempts++;
990 FailureInfo->MaxHotness =
991 std::max(FailureInfo->MaxHotness,
Edge.second.getHotness());
995 "Expected no FailureInfo for newly rejected candidate");
996 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
997 VI,
Edge.second.getHotness(), Reason, 1);
1000 std::string Msg = std::string(
"Failed to import function ") +
1001 VI.name().str() +
" due to " +
1003 auto Error = make_error<StringError>(
1006 "Error importing module: ");
1010 <<
"ignored! No qualifying callee with summary found.\n");
1016 CalleeSummary = CalleeSummary->getBaseObject();
1017 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
1020 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
1021 "selectCallee() didn't honor the threshold");
1023 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
1029 NumImportedFunctionsThinLink++;
1031 NumImportedHotFunctionsThinLink++;
1032 if (IsCriticalCallsite)
1033 NumImportedCriticalFunctionsThinLink++;
1040 (*ExportLists)[ExportModulePath].insert(VI);
1043 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
1052 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
1057 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
1067 GlobalsImporter GVI(Index, DefinedGVSummaries, IsPrevailing, ImportList,
1073 for (
const auto &GVSummary : DefinedGVSummaries) {
1077 auto VI = Index.getValueInfo(GVSummary.first);
1079 if (!Index.isGlobalValueLive(GVSummary.second)) {
1084 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
1089 computeImportForFunction(*FuncSummary,
ImportInstrLimit, DefinedGVSummaries,
1090 Worklist, GVI, ImportList, ImportThresholds);
1094 while (!Worklist.
empty()) {
1096 auto *Summary = std::get<0>(GVInfo);
1097 auto Threshold = std::get<1>(GVInfo);
1099 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
1100 computeImportForFunction(*FS, Threshold, DefinedGVSummaries, Worklist,
1101 GVI, ImportList, ImportThresholds);
1107 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
1108 for (
auto &
I : ImportThresholds) {
1109 auto &ProcessedThreshold = std::get<0>(
I.second);
1110 auto &CalleeSummary = std::get<1>(
I.second);
1111 auto &FailureInfo = std::get<2>(
I.second);
1116 if (!FailureInfo->VI.getSummaryList().empty())
1117 FS = dyn_cast<FunctionSummary>(
1118 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
1119 dbgs() << FailureInfo->VI
1121 <<
", Threshold = " << ProcessedThreshold
1122 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
1124 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1131 auto SL = VI.getSummaryList();
1139 if (
const auto &VI = Index.getValueInfo(
G))
1148 unsigned NumGVS = 0;
1149 for (
auto &VI : ExportSet)
1156 unsigned NumGVS = 0;
1157 unsigned DefinedFS = 0;
1167 for (
const auto &[FromModule, GUID,
Type] : ImportList) {
1186 for (
const auto &ImportPerModule : ImportLists)
1187 for (
const auto &[FromModule, GUID, ImportType] : ImportPerModule.second)
1188 FlattenedImports.
insert(GUID);
1196 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1198 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
1199 Index.findSummaryInModule(VI, ModulePath));
1200 return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) &&
1206 for (
auto &ExportPerModule : ExportLists)
1207 for (
auto &VI : ExportPerModule.second)
1208 if (!FlattenedImports.
count(VI.getGUID()) &&
1209 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1226 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1227 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1229 << DefinedGVSummaries.first <<
"'\n");
1230 MIS->computeImportForModule(DefinedGVSummaries.second,
1231 DefinedGVSummaries.first, ImportList);
1239 for (
auto &ELI : ExportLists) {
1243 const auto &DefinedGVSummaries =
1244 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1245 for (
auto &EI : ELI.second) {
1252 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1256 auto *S = DS->getSecond();
1257 S = S->getBaseObject();
1258 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1263 if (!Index.isWriteOnly(GVS))
1266 auto *FS = cast<FunctionSummary>(S);
1275 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1276 if (!DefinedGVSummaries.
count(EI->getGUID()))
1277 NewExports.
erase(EI++);
1281 ELI.second.insert_range(NewExports);
1288 for (
const auto &ModuleImports : ImportLists) {
1289 auto ModName = ModuleImports.first;
1290 auto &Exports = ExportLists[ModName];
1295 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1296 <<
" vars. Imports from " << Histogram.
size()
1298 for (
const auto &[SrcModName,
Stats] : Histogram) {
1300 <<
" function definitions and "
1302 <<
" function declarations imported from " << SrcModName
1305 <<
" global vars imported from " << SrcModName <<
"\n");
1317 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1318 << Histogram.
size() <<
" modules.\n");
1319 for (
const auto &[SrcModName,
Stats] : Histogram) {
1321 <<
" function definitions and "
1323 <<
" function declarations imported from " << SrcModName
1326 << SrcModName <<
"\n");
1348 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1351 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1353 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1368 for (
const auto &GlobalList : Index) {
1370 if (GlobalList.second.SummaryList.empty())
1373 auto GUID = GlobalList.first;
1374 assert(GlobalList.second.SummaryList.size() == 1 &&
1375 "Expected individual combined index to have one summary per GUID");
1376 auto &Summary = GlobalList.second.SummaryList[0];
1379 if (Summary->modulePath() == ModulePath)
1382 ImportList.
addGUID(Summary->modulePath(), GUID, Summary->importType());
1395 for (
auto &EI : FS->mutableCalls()) {
1396 if (!EI.first.getSummaryList().empty())
1398 auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());
1402 auto VI = Index.getValueInfo(GUID);
1404 VI.getSummaryList(),
1405 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1415 return SummaryPtr->getSummaryKind() ==
1416 GlobalValueSummary::GlobalVarKind;
1424 for (
const auto &Entry : Index) {
1425 for (
const auto &S : Entry.second.SummaryList) {
1426 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1436 assert(!Index.withGlobalValueDeadStripping());
1439 GUIDPreservedSymbols.
empty()) {
1444 unsigned LiveSymbols = 0;
1446 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1447 for (
auto GUID : GUIDPreservedSymbols) {
1448 ValueInfo VI = Index.getValueInfo(GUID);
1451 for (
const auto &S : VI.getSummaryList())
1456 for (
const auto &Entry : Index) {
1457 auto VI = Index.getValueInfo(Entry);
1458 for (
const auto &S : Entry.second.SummaryList) {
1459 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1482 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1493 bool KeepAliveLinkage =
false;
1494 bool Interposable =
false;
1495 for (
const auto &S : VI.getSummaryList()) {
1499 KeepAliveLinkage =
true;
1501 Interposable =
true;
1505 if (!KeepAliveLinkage)
1510 "Interposable and available_externally/linkonce_odr/weak_odr "
1515 for (
const auto &S : VI.getSummaryList())
1521 while (!Worklist.
empty()) {
1523 for (
const auto &Summary : VI.getSummaryList()) {
1524 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1528 visit(AS->getAliaseeVI(),
true);
1531 for (
auto Ref : Summary->refs())
1533 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1534 for (
auto Call : FS->calls())
1535 visit(Call.first,
false);
1538 Index.setWithGlobalValueDeadStripping();
1540 unsigned DeadSymbols = Index.size() - LiveSymbols;
1541 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1542 <<
" symbols Dead \n");
1543 NumDeadSymbols += DeadSymbols;
1544 NumLiveSymbols += LiveSymbols;
1552 bool ImportEnabled) {
1556 Index.propagateAttributes(GUIDPreservedSymbols);
1568 ModuleToSummariesForIndex[std::string(ModulePath)] =
1569 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1578 auto It = Map.find(Key);
1579 if (It == Map.end())
1580 std::tie(It, std::ignore) =
1586 for (
const auto &[FromModule, GUID, ImportType] : ImportList) {
1587 auto &SummariesForIndex =
1588 LookupOrCreate(ModuleToSummariesForIndex, FromModule);
1590 const auto &DefinedGVSummaries = ModuleToDefinedGVSummaries.
at(FromModule);
1591 const auto &DS = DefinedGVSummaries.
find(GUID);
1592 assert(DS != DefinedGVSummaries.
end() &&
1593 "Expected a defined summary for imported global value");
1595 DecSummaries.insert(DS->second);
1597 SummariesForIndex[GUID] = DS->second;
1611 [&](
StringRef M) { ImportsOS << M <<
"\n"; });
1621 for (
const auto &ILI : ModuleToSummariesForIndex)
1625 if (ILI.first != ModulePath)
1632 if (
Function *
F = dyn_cast<Function>(&GV)) {
1635 F->setComdat(
nullptr);
1637 V->setInitializer(
nullptr);
1640 V->setComdat(
nullptr);
1668 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1670 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1671 if (GS == DefinedGlobals.
end())
1676 if (
Function *
F = dyn_cast<Function>(&GV)) {
1678 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1679 F->setDoesNotAccessMemory();
1681 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1682 F->setOnlyReadsMemory();
1684 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1685 F->setDoesNotRecurse();
1687 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1688 F->setDoesNotThrow();
1692 auto NewLinkage = GS->second->linkage();
1731 GS->second->canAutoHide()) {
1737 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1744 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1745 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1746 if (GO->getComdat()->getName() == GO->getName())
1747 NonPrevailingComdats.
insert(GO->getComdat());
1748 GO->setComdat(
nullptr);
1753 for (
auto &GV : TheModule)
1755 for (
auto &GV : TheModule.
globals())
1756 FinalizeInModule(GV);
1757 for (
auto &GV : TheModule.
aliases())
1758 FinalizeInModule(GV);
1763 if (NonPrevailingComdats.
empty())
1766 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1767 GO.setComdat(
nullptr);
1778 for (
auto &GA : TheModule.
aliases()) {
1779 if (GA.hasAvailableExternallyLinkage())
1782 assert(Obj &&
"aliasee without an base object is unimplemented");
1796 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1800 if (isa<GlobalIFunc>(&GV) ||
1801 (isa<GlobalAlias>(&GV) &&
1802 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1806 auto GS = DefinedGlobals.
find(GV.getGUID());
1807 if (GS == DefinedGlobals.
end()) {
1815 std::string OrigId = GlobalValue::getGlobalIdentifier(
1818 GS = DefinedGlobals.
find(
1820 if (GS == DefinedGlobals.
end()) {
1827 GS = DefinedGlobals.
find(
1858 for (
auto &GV : M.globals())
1861 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1873 unsigned ImportedCount = 0, ImportedGVCount = 0;
1880 for (
auto &
F : DestModule)
1881 if (!
F.isDeclaration() && MoveSymbolGUIDSet.
contains(
F.getGUID()))
1890 if (!SrcModuleOrErr)
1892 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1894 "Context mismatch");
1898 if (
Error Err = SrcModule->materializeMetadata())
1899 return std::move(Err);
1906 auto GUID =
F.getGUID();
1907 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1911 <<
" importing function"
1912 << (ImportDefinition
1914 : (MaybeImportType ?
" declaration " :
" "))
1915 << GUID <<
" " <<
F.getName() <<
" from "
1916 << SrcModule->getSourceFileName() <<
"\n");
1917 if (ImportDefinition) {
1918 if (
Error Err =
F.materialize())
1919 return std::move(Err);
1926 "thinlto_src_module",
1928 {MDString::get(DestModule.getContext(),
1929 SrcModule->getModuleIdentifier())}));
1933 {MDString::get(DestModule.getContext(),
1934 SrcModule->getSourceFileName())}));
1942 auto GUID = GV.getGUID();
1943 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1947 <<
" importing global"
1948 << (ImportDefinition
1950 : (MaybeImportType ?
" declaration " :
" "))
1951 << GUID <<
" " << GV.getName() <<
" from "
1952 << SrcModule->getSourceFileName() <<
"\n");
1953 if (ImportDefinition) {
1954 if (
Error Err = GV.materialize())
1955 return std::move(Err);
1956 ImportedGVCount += GlobalsToImport.
insert(&GV);
1960 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1962 auto GUID = GA.getGUID();
1963 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1967 <<
" importing alias"
1968 << (ImportDefinition
1970 : (MaybeImportType ?
" declaration " :
" "))
1971 << GUID <<
" " << GA.getName() <<
" from "
1972 << SrcModule->getSourceFileName() <<
"\n");
1973 if (ImportDefinition) {
1974 if (
Error Err = GA.materialize())
1975 return std::move(Err);
1979 return std::move(Err);
1983 << SrcModule->getSourceFileName() <<
"\n");
1988 "thinlto_src_module",
1990 {MDString::get(DestModule.getContext(),
1991 SrcModule->getModuleIdentifier())}));
1995 {MDString::get(DestModule.getContext(),
1996 SrcModule->getSourceFileName())}));
1998 GlobalsToImport.
insert(Fn);
2010 SrcModule->setPartialSampleProfileRatio(Index);
2017 for (
const auto *GV : GlobalsToImport)
2019 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
2022 if (
Error Err = Mover.
move(std::move(SrcModule),
2026 Twine(
"Function Import: link error: ") +
2029 ImportedCount += GlobalsToImport.
size();
2030 NumImportedModules++;
2035 NumImportedFunctions += (ImportedCount - ImportedGVCount);
2036 NumImportedGlobalVars += ImportedGVCount;
2039 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
2040 <<
" functions for Module "
2043 <<
" global variables for Module "
2045 return ImportedCount;
2055 if (!IndexPtrOrErr) {
2060 std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
2070 *Index, ImportList);
2073 isPrevailing, *Index, ImportList);
2079 for (
auto &
I : *Index) {
2080 for (
auto &S :
I.second.SummaryList) {
2092 auto ModuleLoader = [&M](
StringRef Identifier) {
2093 return loadFile(std::string(Identifier), M.getContext());
2102 "Error importing module: ");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
static auto qualifyCalleeCandidates(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, StringRef CallerModulePath)
Given a list of possible callee implementation for a call site, qualify the legality of importing eac...
static cl::opt< bool > EnableImportMetadata("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'"))
static cl::opt< float > ImportColdMultiplier("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"))
static DenseMap< StringRef, ImportStatistics > collectImportStatistics(const ModuleSummaryIndex &Index, const FunctionImporter::ImportMapTy &ImportList)
static cl::opt< float > ImportHotMultiplier("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"))
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, FunctionImporter::ExportSetTy &ExportSet)
static bool checkVariableImport(const ModuleSummaryIndex &Index, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
static bool doImportingForModuleForTest(Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
static cl::opt< float > ImportHotInstrFactor("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static cl::opt< float > ImportCriticalMultiplier("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for critical callsites"))
static cl::opt< int > ImportCutoff("import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)"))
cl::opt< std::string > UseCtxProfile
static cl::opt< bool > CtxprofMoveRootsToOwnModule("thinlto-move-ctxprof-trees", cl::desc("Move contextual profiling roots and the graphs under them in " "their own module."), cl::Hidden, cl::init(false))
static const char * getFailureName(FunctionImporter::ImportFailureReason Reason)
static cl::opt< float > ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
cl::list< GlobalValue::GUID > MoveSymbolGUID
static void internalizeGVsAfterImport(Module &M)
static cl::opt< bool > PrintImports("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions"))
void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, FunctionSummary *FS)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
cl::opt< bool > ForceImportAll("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute"))
static bool shouldSkipLocalInAnotherModule(const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
static cl::opt< unsigned > ImportInstrLimit("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
static cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy ...
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
static cl::opt< std::string > SummaryFile("summary-file", cl::desc("The summary file to use for function importing."))
Summary file to use for function importing when using -function-import from the command line.
static cl::opt< bool > ImportAllIndex("import-all-index", cl::desc("Import all external functions in index."))
Used when testing importing from distributed indexes via opt.
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void dumpImportListForModule(const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleFromIndexForTest(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold fo...
static void ComputeCrossModuleImportForModuleForTest(StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
cl::opt< bool > ForceImportAll
block placement Basic Block Placement Stats
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
Reader for contextual iFDO profile, which comes in bitstream format.
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Import globals referenced by a function or other globals that are being imported, if importing such g...
void onImportingSummary(const GlobalValueSummary &Summary)
GlobalsImporter(const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
Determine the list of imports and exports for each module.
virtual bool canImport(ValueInfo VI)
DenseMap< StringRef, FunctionImporter::ExportSetTy > *const ExportLists
virtual ~ModuleImportsManager()=default
static std::unique_ptr< ModuleImportsManager > create(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing
ModuleImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
const ModuleSummaryIndex & Index
virtual void computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName, FunctionImporter::ImportMapTy &ImportList)
Given the list of globals defined in a module, compute the list of imports as well as the list of "ex...
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)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
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.
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)
std::pair< ImportIDTy, ImportIDTy > createImportIDs(StringRef FromModule, GlobalValue::GUID GUID)
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.
ImportFailureReason
The different reasons selectCallee will chose not to import a candidate.
@ LocalLinkageNotInModule
Function summary information to aid decisions and implementation of importing.
unsigned instCount() const
Get the instruction count recorded for this function.
FFlags fflags() const
Get function summary flags.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
LLVM_ABI const GlobalObject * getAliaseeObject() const
Function and variable summary information to aid decisions and implementation of importing.
StringRef modulePath() const
Get the path to the module containing this function.
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const GlobalObject * getAliaseeObject() const
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
LLVM_ABI Error materialize()
Make sure this GlobalValue is fully read.
LLVM_ABI bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
bool hasAvailableExternallyLinkage() const
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
LLVM_ABI Error move(std::unique_ptr< Module > Src, ArrayRef< GlobalValue * > ValuesToLink, LazyCallback AddLazyFor, bool IsPerformingImport)
Move in the provide values in ValuesToLink from Src.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static StringRef getOriginalNameBeforePromote(StringRef Name)
Helper to obtain the unpromoted name for a global value (or the original name if not promoted).
A Module instance is used to store all the information related to an LLVM module.
LLVMContext & getContext() const
Get the global data context.
const std::string & getSourceFileName() const
Get the module's original source file name.
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
iterator_range< global_object_iterator > global_objects()
LLVM_ABI Expected< PGOCtxProfile > loadProfiles()
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
A vector that has set insertion semantics.
ArrayRef< value_type > getArrayRef() const
size_type size() const
Determine the number of elements in the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
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.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
The root is the trivial Path to the root value.
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
bool fromJSON(const Value &E, std::string &Out, Path P)
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
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)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
LLVM_ABI void renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto map_range(ContainerTy &&C, FuncTy F)
LLVM_ABI void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI void computeDeadSymbolsAndUpdateIndirectCalls(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing)
Compute all the symbols that are "dead": i.e these that can't be reached in the graph from any of the...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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...
LLVM_ABI void updateIndirectCalls(ModuleSummaryIndex &Index)
Update call edges for indirect calls to local functions added from SamplePGO when needed.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
LLVM_ABI std::unique_ptr< Module > getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given file holds a bitcode image, return a Module for it which does lazy deserialization of fu...
LLVM_ABI void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
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::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
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.
PrevailingType
PrevailingType enum used as a return type of callback passed to computeDeadSymbolsAndUpdateIndirectCa...
const char * toString(DWARFSectionKind Kind)
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
LLVM_ABI Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
LLVM_ABI void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
LLVM_ABI Expected< std::unique_ptr< ModuleSummaryIndex > > getModuleSummaryIndexForFile(StringRef Path, bool IgnoreEmptyThinLTOIndexFile=false)
Parse the module summary index out of an IR file and return the module summary index object if found,...
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
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.