52#include <system_error>
58#define DEBUG_TYPE "function-import"
61 "Number of functions thin link decided to import");
63 "Number of hot functions thin link decided to import");
65 "Number of critical functions thin link decided to import");
67 "Number of global variables thin link decided to import");
68STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
70 "Number of global variables imported in backend");
71STATISTIC(NumImportedModules,
"Number of modules imported from");
72STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
73STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
80 cl::desc(
"Import functions with noinline attribute"));
85 cl::desc(
"Only import functions with less than N instructions"));
89 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
94 cl::desc(
"As we import functions, multiply the "
95 "`import-instr-limit` threshold by this factor "
96 "before processing newly imported functions"));
101 cl::desc(
"As we import functions called from hot callsite, multiply the "
102 "`import-instr-limit` threshold by this factor "
103 "before processing newly imported functions"));
107 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
113 "Multiply the `import-instr-limit` threshold for critical callsites"));
118 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
121 cl::desc(
"Print imported functions"));
125 cl::desc(
"Print information for functions rejected for importing"));
132 cl::desc(
"Enable import metadata like 'thinlto_src_module' and "
133 "'thinlto_src_file'"));
139 cl::desc(
"The summary file to use for function importing."));
145 cl::desc(
"Import all external functions in index."));
155 cl::desc(
"If true, import function declaration as fallback if the function "
156 "definition is not imported."));
167 "thinlto-workload-def",
168 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
169 "dictionary. The keys are root functions, the values are lists of "
170 "functions to import in the module defining the root. It is "
171 "assumed -funique-internal-linkage-names was used, to ensure "
172 "local linkage functions have unique names. For example: \n"
174 " \"rootFunction_1\": [\"function_to_import_1\", "
175 "\"function_to_import_2\"], \n"
176 " \"rootFunction_2\": [\"function_to_import_3\", "
177 "\"function_to_import_4\"] \n"
184 "thinlto-move-ctxprof-trees",
185 cl::desc(
"Move contextual profiling roots and the graphs under them in "
186 "their own module."),
195static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
201 std::unique_ptr<Module> Result =
205 Err.print(
"function-import",
errs());
234 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
238 [&Index, CalleeSummaryList,
239 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
242 auto *GVSummary = SummaryPtr.get();
243 if (!Index.isGlobalValueLive(GVSummary))
280 if (Summary->notEligibleToImport())
305 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
306 unsigned Threshold,
StringRef CallerModulePath,
310 TooLargeOrNoInlineSummary =
nullptr;
311 auto QualifiedCandidates =
313 for (
auto QualifiedValue : QualifiedCandidates) {
314 Reason = QualifiedValue.first;
323 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
325 TooLargeOrNoInlineSummary = Summary;
332 TooLargeOrNoInlineSummary = Summary;
351 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
352 if (!Imports.insert(Def).second)
364 auto [Def, Decl] = IDs.createImportIDs(FromModule, GUID);
367 if (!Imports.contains(Def))
368 Imports.insert(Decl);
374 for (
const auto &[SrcMod, GUID, ImportType] : *
this)
381std::optional<GlobalValueSummary::ImportKind>
384 if (
auto IDPair = IDs.getImportIDs(FromModule, GUID)) {
385 auto [Def, Decl] = *IDPair;
386 if (Imports.contains(Def))
388 if (Imports.contains(Decl))
404 bool shouldImportGlobal(
const ValueInfo &VI) {
405 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
406 if (GVS == DefinedGVSummaries.end())
418 if (VI.getSummaryList().size() > 1 &&
420 !IsPrevailing(VI.getGUID(), GVS->second))
429 for (
const auto &VI : Summary.refs()) {
430 if (!shouldImportGlobal(VI)) {
432 dbgs() <<
"Ref ignored! Target already in destination module.\n");
438 for (
const auto &RefSummary : VI.getSummaryList()) {
456 bool CanImportDecl =
false;
458 Summary.modulePath()) ||
459 !Index.canImportGlobalVar(GVS,
true,
462 ImportList.maybeAddDeclaration(RefSummary->modulePath(),
470 if (ImportList.addDefinition(RefSummary->modulePath(), VI.getGUID()) !=
476 NumImportedGlobalVarsThinLink++;
481 (*ExportLists)[RefSummary->modulePath()].insert(VI);
485 if (!Index.isWriteOnly(GVS))
499 : Index(Index), DefinedGVSummaries(DefinedGVSummaries),
500 IsPrevailing(IsPrevailing), ImportList(ImportList),
501 ExportLists(ExportLists) {}
505 onImportingSummaryImpl(Summary, Worklist);
506 while (!Worklist.
empty())
507 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
515 void computeImportForFunction(
547 static std::unique_ptr<ModuleImportsManager>
581 if (SetIter == Workloads.end()) {
583 <<
" does not contain the root of any context.\n");
585 ModName, ImportList);
588 <<
" contains the root(s) of context(s).\n");
592 auto &ValueInfos = SetIter->second;
594 auto It = DefinedGVSummaries.
find(VI.getGUID());
595 if (It != DefinedGVSummaries.
end() &&
598 dbgs() <<
"[Workload] " << VI.name()
599 <<
" has the prevailing variant already in the module "
600 << ModName <<
". No need to import\n");
610 [&](
const auto &Candidate) {
612 <<
" from " << Candidate.second->modulePath()
613 <<
" ImportFailureReason: "
615 return Candidate.first ==
618 [](
const auto &Candidate) {
return Candidate.second; });
619 if (PotentialCandidates.empty()) {
621 <<
" because can't find eligible Callee. Guid is: "
622 << VI.getGUID() <<
"\n");
640 PotentialCandidates, [&](
const auto *Candidate) {
643 if (PrevailingCandidates.empty()) {
644 GVS = *PotentialCandidates.begin();
649 <<
"[Workload] Found multiple non-prevailing candidates for "
651 <<
". This is unexpected. Are module paths passed to the "
652 "compiler unique for the modules passed to the linker?");
661 GVS = *PrevailingCandidates.begin();
668 if (ExportingModule == ModName) {
670 <<
" because its defining module is the same as the "
674 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
675 << ExportingModule <<
" : " << VI.getGUID() <<
"\n");
679 (*ExportLists)[ExportingModule].insert(VI);
684 void loadFromJson() {
691 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
694 auto DbgReportIfAmbiguous = [&](
StringRef Name) {
696 dbgs() <<
"[Workload] Function name " << Name
697 <<
" present in the workload definition is ambiguous. Consider "
698 "compiling with -funique-internal-linkage-names.";
703 if (std::error_code EC = BufferOrErr.getError()) {
707 auto Buffer = std::move(BufferOrErr.get());
708 std::map<std::string, std::vector<std::string>> WorkloadDefs;
721 for (
const auto &Workload : WorkloadDefs) {
722 const auto &Root = Workload.first;
723 DbgReportIfAmbiguous(Root);
725 const auto &AllCallees = Workload.second;
726 auto RootIt = NameToValueInfo.
find(Root);
727 if (RootIt == NameToValueInfo.
end()) {
729 <<
" not found in this linkage unit.\n");
732 auto RootVI = RootIt->second;
733 if (RootVI.getSummaryList().size() != 1) {
735 <<
" should have exactly one summary, but has "
736 << RootVI.getSummaryList().size() <<
". Skipping.\n");
740 RootVI.getSummaryList().
front()->modulePath();
741 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
742 <<
" is : " << RootDefiningModule <<
"\n");
743 auto &Set = Workloads[RootDefiningModule];
744 for (
const auto &Callee : AllCallees) {
746 DbgReportIfAmbiguous(Callee);
747 auto ElemIt = NameToValueInfo.
find(Callee);
748 if (ElemIt == NameToValueInfo.
end()) {
752 Set.insert(ElemIt->second);
757 void loadFromCtxProf() {
760 if (std::error_code EC = BufferOrErr.getError()) {
764 auto Buffer = std::move(BufferOrErr.get());
772 const auto &CtxMap = Ctx->Contexts;
774 for (
const auto &[RootGuid, Root] : CtxMap) {
777 ContainedGUIDs.
clear();
779 auto RootVI =
Index.getValueInfo(RootGuid);
782 <<
" not found in this linkage unit.\n");
785 if (RootVI.getSummaryList().size() != 1) {
787 <<
" should have exactly one summary, but has "
788 << RootVI.getSummaryList().size() <<
". Skipping.\n");
791 std::string RootDefiningModule =
792 RootVI.getSummaryList().front()->modulePath().str();
794 RootDefiningModule = std::to_string(RootGuid);
796 dbgs() <<
"[Workload] Moving " << RootGuid
797 <<
" to a module with the filename without extension : "
798 << RootDefiningModule <<
"\n");
800 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << RootGuid
801 <<
" is : " << RootDefiningModule <<
"\n");
803 auto &Set = Workloads[RootDefiningModule];
804 Root.getContainedGuids(ContainedGUIDs);
805 Roots.insert(RootVI);
806 for (
auto Guid : ContainedGUIDs)
823 "Pass only one of: -thinlto-pgo-ctx-prof or -thinlto-workload-def");
831 for (
const auto &[Root, Set] : Workloads) {
832 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
833 <<
" distinct callees.\n";
834 for (
const auto &VI : Set) {
835 dbgs() <<
"[Workload] Root: " << Root
836 <<
" Would include: " << VI.getGUID() <<
"\n";
849 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
850 return std::unique_ptr<ModuleImportsManager>(
853 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
870 return "InterposableLinkage";
872 return "LocalLinkageNotInModule";
874 return "NotEligible";
884void ModuleImportsManager::computeImportForFunction(
885 const FunctionSummary &Summary,
const unsigned Threshold,
887 SmallVectorImpl<EdgeInfo> &Worklist, GlobalsImporter &GVImporter,
888 FunctionImporter::ImportMapTy &ImportList,
891 static int ImportCount = 0;
893 ValueInfo
VI =
Edge.first;
894 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
903 if (DefinedGVSummaries.
count(
VI.getGUID())) {
907 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
911 if (!canImport(VI)) {
913 dbgs() <<
"Skipping over " <<
VI.getGUID()
914 <<
" because its import is handled in a different module.");
915 assert(
VI.getSummaryList().size() == 1 &&
916 "The root was expected to be an external symbol");
930 const auto NewThreshold =
931 Threshold * GetBonusMultiplier(
Edge.second.getHotness());
933 auto IT = ImportThresholds.insert(std::make_pair(
934 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
935 bool PreviouslyVisited = !
IT.second;
936 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
937 auto &CalleeSummary = std::get<1>(
IT.first->second);
938 auto &FailureInfo = std::get<2>(
IT.first->second);
942 bool IsCriticalCallsite =
945 const FunctionSummary *ResolvedCalleeSummary =
nullptr;
947 assert(PreviouslyVisited);
952 if (NewThreshold <= ProcessedThreshold) {
954 dbgs() <<
"ignored! Target was already imported with Threshold "
955 << ProcessedThreshold <<
"\n");
959 ProcessedThreshold = NewThreshold;
964 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
966 dbgs() <<
"ignored! Target was already rejected with Threshold "
967 << ProcessedThreshold <<
"\n");
970 "Expected FailureInfo for previously rejected candidate");
971 FailureInfo->Attempts++;
979 const GlobalValueSummary *SummaryForDeclImport =
nullptr;
982 Summary.modulePath(), SummaryForDeclImport, Reason);
983 if (!CalleeSummary) {
987 StringRef DeclSourceModule = SummaryForDeclImport->
modulePath();
996 if (PreviouslyVisited) {
997 ProcessedThreshold = NewThreshold;
1000 "Expected FailureInfo for previously rejected candidate");
1001 FailureInfo->Reason = Reason;
1002 FailureInfo->Attempts++;
1003 FailureInfo->MaxHotness =
1004 std::max(FailureInfo->MaxHotness,
Edge.second.getHotness());
1008 "Expected no FailureInfo for newly rejected candidate");
1009 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
1010 VI,
Edge.second.getHotness(), Reason, 1);
1013 std::string Msg = std::string(
"Failed to import function ") +
1014 VI.name().str() +
" due to " +
1019 "Error importing module: ");
1023 <<
"ignored! No qualifying callee with summary found.\n");
1029 CalleeSummary = CalleeSummary->getBaseObject();
1033 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
1034 "selectCallee() didn't honor the threshold");
1036 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
1042 NumImportedFunctionsThinLink++;
1044 NumImportedHotFunctionsThinLink++;
1045 if (IsCriticalCallsite)
1046 NumImportedCriticalFunctionsThinLink++;
1053 (*ExportLists)[ExportModulePath].insert(VI);
1056 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
1065 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
1070 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
1086 for (
const auto &GVSummary : DefinedGVSummaries) {
1090 auto VI =
Index.getValueInfo(GVSummary.first);
1092 if (!
Index.isGlobalValueLive(GVSummary.second)) {
1102 computeImportForFunction(*FuncSummary,
ImportInstrLimit, DefinedGVSummaries,
1103 Worklist, GVI, ImportList, ImportThresholds);
1107 while (!Worklist.
empty()) {
1109 auto *Summary = std::get<0>(GVInfo);
1110 auto Threshold = std::get<1>(GVInfo);
1112 computeImportForFunction(*Summary, Threshold, DefinedGVSummaries, Worklist,
1113 GVI, ImportList, ImportThresholds);
1119 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
1120 for (
auto &
I : ImportThresholds) {
1121 auto &ProcessedThreshold = std::get<0>(
I.second);
1122 auto &CalleeSummary = std::get<1>(
I.second);
1123 auto &FailureInfo = std::get<2>(
I.second);
1128 if (!FailureInfo->VI.getSummaryList().empty())
1130 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
1131 dbgs() << FailureInfo->VI
1133 <<
", Threshold = " << ProcessedThreshold
1134 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
1136 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1143 auto SL = VI.getSummaryList();
1151 if (
const auto &VI = Index.getValueInfo(
G))
1160 unsigned NumGVS = 0;
1161 for (
auto &VI : ExportSet)
1179 for (
const auto &[FromModule, GUID,
Type] : ImportList) {
1198 for (
const auto &ImportPerModule : ImportLists)
1199 for (
const auto &[FromModule, GUID, ImportType] : ImportPerModule.second)
1200 FlattenedImports.
insert(GUID);
1208 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1211 Index.findSummaryInModule(VI, ModulePath));
1212 return GVS && (Index.isReadOnly(GVS) || Index.isWriteOnly(GVS)) &&
1218 for (
auto &ExportPerModule : ExportLists)
1219 for (
auto &VI : ExportPerModule.second)
1220 if (!FlattenedImports.
count(VI.getGUID()) &&
1221 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1238 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1239 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1241 << DefinedGVSummaries.first <<
"'\n");
1242 MIS->computeImportForModule(DefinedGVSummaries.second,
1243 DefinedGVSummaries.first, ImportList);
1251 for (
auto &ELI : ExportLists) {
1255 const auto &DefinedGVSummaries =
1256 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1257 for (
auto &EI : ELI.second) {
1264 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1268 auto *S = DS->getSecond();
1269 S = S->getBaseObject();
1275 if (!Index.isWriteOnly(GVS))
1287 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1288 if (!DefinedGVSummaries.
count(EI->getGUID()))
1289 NewExports.
erase(EI++);
1293 ELI.second.insert_range(NewExports);
1300 for (
const auto &ModuleImports : ImportLists) {
1301 auto ModName = ModuleImports.first;
1302 auto &Exports = ExportLists[ModName];
1307 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1308 <<
" vars. Imports from " << Histogram.
size()
1310 for (
const auto &[SrcModName,
Stats] : Histogram) {
1312 <<
" function definitions and "
1314 <<
" function declarations imported from " << SrcModName
1317 <<
" global vars imported from " << SrcModName <<
"\n");
1329 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1330 << Histogram.
size() <<
" modules.\n");
1331 for (
const auto &[SrcModName,
Stats] : Histogram) {
1333 <<
" function definitions and "
1335 <<
" function declarations imported from " << SrcModName
1338 << SrcModName <<
"\n");
1360 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1363 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1365 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1380 for (
const auto &GlobalList : Index) {
1382 if (GlobalList.second.getSummaryList().empty())
1385 auto GUID = GlobalList.first;
1386 assert(GlobalList.second.getSummaryList().size() == 1 &&
1387 "Expected individual combined index to have one summary per GUID");
1388 auto &Summary = GlobalList.second.getSummaryList()[0];
1391 if (Summary->modulePath() == ModulePath)
1394 ImportList.
addGUID(Summary->modulePath(), GUID, Summary->importType());
1407 for (
auto &EI : FS->mutableCalls()) {
1408 if (!EI.first.getSummaryList().empty())
1410 auto GUID = Index.getGUIDFromOriginalID(EI.first.getGUID());
1414 auto VI = Index.getValueInfo(GUID);
1416 VI.getSummaryList(),
1417 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1427 return SummaryPtr->getSummaryKind() ==
1428 GlobalValueSummary::GlobalVarKind;
1436 for (
const auto &Entry : Index) {
1437 for (
const auto &S : Entry.second.getSummaryList()) {
1448 assert(!Index.withGlobalValueDeadStripping());
1451 GUIDPreservedSymbols.
empty()) {
1456 unsigned LiveSymbols = 0;
1458 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1459 for (
auto GUID : GUIDPreservedSymbols) {
1460 ValueInfo VI = Index.getValueInfo(GUID);
1463 for (
const auto &S : VI.getSummaryList())
1468 for (
const auto &Entry : Index) {
1469 auto VI = Index.getValueInfo(Entry);
1470 for (
const auto &S : Entry.second.getSummaryList()) {
1494 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1505 bool KeepAliveLinkage =
false;
1506 bool Interposable =
false;
1507 for (
const auto &S : VI.getSummaryList()) {
1511 KeepAliveLinkage =
true;
1513 Interposable =
true;
1517 if (!KeepAliveLinkage)
1522 "Interposable and available_externally/linkonce_odr/weak_odr "
1527 for (
const auto &S : VI.getSummaryList())
1533 while (!Worklist.
empty()) {
1535 for (
const auto &Summary : VI.getSummaryList()) {
1540 visit(AS->getAliaseeVI(),
true);
1543 for (
auto Ref : Summary->refs())
1546 for (
auto Call : FS->calls())
1550 Index.setWithGlobalValueDeadStripping();
1552 unsigned DeadSymbols = Index.size() - LiveSymbols;
1553 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1554 <<
" symbols Dead \n");
1555 NumDeadSymbols += DeadSymbols;
1556 NumLiveSymbols += LiveSymbols;
1564 bool ImportEnabled) {
1569 Index.propagateAttributes(GUIDPreservedSymbols);
1581 ModuleToSummariesForIndex[std::string(ModulePath)] =
1582 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1591 auto It = Map.find(
Key);
1592 if (It == Map.end())
1593 std::tie(It, std::ignore) =
1599 for (
const auto &[FromModule, GUID, ImportType] : ImportList) {
1600 auto &SummariesForIndex =
1601 LookupOrCreate(ModuleToSummariesForIndex, FromModule);
1603 const auto &DefinedGVSummaries = ModuleToDefinedGVSummaries.
at(FromModule);
1604 const auto &DS = DefinedGVSummaries.
find(GUID);
1605 assert(DS != DefinedGVSummaries.
end() &&
1606 "Expected a defined summary for imported global value");
1608 DecSummaries.insert(DS->second);
1610 SummariesForIndex[GUID] = DS->second;
1626 for (
auto &[ModPath, SummariesForIndex] : ModuleToSummariesForIndex) {
1627 if (ModPath == ModulePath)
1629 auto It = ModuleToDefinedGVSummaries.
find(ModPath);
1630 if (It == ModuleToDefinedGVSummaries.
end())
1632 for (
const auto &[GUID, Summary] : It->second) {
1633 if (Summary->noRenameOnPromotion()) {
1634 DecSummaries.insert(Summary);
1635 SummariesForIndex.try_emplace(GUID, Summary);
1652 [&](
StringRef M) { ImportsOS << M <<
"\n"; });
1662 for (
const auto &ILI : ModuleToSummariesForIndex)
1666 if (ILI.first != ModulePath)
1676 F->setComdat(
nullptr);
1678 V->setInitializer(
nullptr);
1681 V->setComdat(
nullptr);
1710 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1712 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1713 if (GS == DefinedGlobals.
end())
1720 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1721 F->setDoesNotAccessMemory();
1723 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1724 F->setOnlyReadsMemory();
1726 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1727 F->setDoesNotRecurse();
1729 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1730 F->setDoesNotThrow();
1734 auto NewLinkage = GS->second->linkage();
1773 GS->second->canAutoHide()) {
1779 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1787 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1788 if (GO->getComdat()->getName() == GO->getName())
1789 NonPrevailingComdats.
insert(GO->getComdat());
1790 GO->setComdat(
nullptr);
1795 for (
auto &GV : TheModule)
1797 for (
auto &GV : TheModule.
globals())
1798 FinalizeInModule(GV);
1799 for (
auto &GV : TheModule.
aliases())
1800 FinalizeInModule(GV);
1805 if (NonPrevailingComdats.
empty())
1808 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1809 GO.setComdat(
nullptr);
1820 for (
auto &GA : TheModule.
aliases()) {
1821 if (GA.hasAvailableExternallyLinkage())
1824 assert(Obj &&
"aliasee without an base object is unimplemented");
1825 if (Obj->hasAvailableExternallyLinkage()) {
1839 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1849 auto GS = DefinedGlobals.
find(GV.getGUID());
1850 if (GS == DefinedGlobals.
end()) {
1861 GS = DefinedGlobals.
find(
1863 if (GS == DefinedGlobals.
end()) {
1870 GS = DefinedGlobals.
find(
1901 for (
auto &GV : M.globals())
1904 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1916 unsigned ImportedCount = 0, ImportedGVCount = 0;
1923 for (
auto &
F : DestModule)
1924 if (!
F.isDeclaration() && MoveSymbolGUIDSet.
contains(
F.getGUID()))
1934 if (!SrcModuleOrErr)
1936 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1938 "Context mismatch");
1942 if (
Error Err = SrcModule->materializeMetadata())
1943 return std::move(Err);
1952 auto GUID =
F.getGUID();
1953 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1954 bool ImportDefinition =
1958 <<
" importing function"
1959 << (ImportDefinition
1961 : (MaybeImportType ?
" declaration " :
" "))
1962 << GUID <<
" " <<
F.getName() <<
" from "
1963 << SrcModule->getSourceFileName() <<
"\n");
1964 if (ImportDefinition) {
1965 if (
Error Err =
F.materialize())
1966 return std::move(Err);
1973 "thinlto_src_module",
1975 {MDString::get(DestModule.getContext(),
1976 SrcModule->getModuleIdentifier())}));
1980 {MDString::get(DestModule.getContext(),
1981 SrcModule->getSourceFileName())}));
1992 auto GUID = GV.getGUID();
1993 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
1994 bool ImportDefinition =
1998 <<
" importing global"
1999 << (ImportDefinition
2001 : (MaybeImportType ?
" declaration " :
" "))
2002 << GUID <<
" " << GV.getName() <<
" from "
2003 << SrcModule->getSourceFileName() <<
"\n");
2004 if (ImportDefinition) {
2005 if (
Error Err = GV.materialize())
2006 return std::move(Err);
2007 ImportedGVCount += GlobalsToImport.
insert(&GV);
2016 auto GUID = GA.getGUID();
2017 auto MaybeImportType = ImportList.
getImportType(ModName, GUID);
2018 bool ImportDefinition =
2022 <<
" importing alias"
2023 << (ImportDefinition
2025 : (MaybeImportType ?
" declaration " :
" "))
2026 << GUID <<
" " << GA.getName() <<
" from "
2027 << SrcModule->getSourceFileName() <<
"\n");
2028 if (ImportDefinition) {
2029 if (
Error Err = GA.materialize())
2030 return std::move(Err);
2034 return std::move(Err);
2037 <<
" " << GO->
getName() <<
" from "
2038 << SrcModule->getSourceFileName() <<
"\n");
2043 "thinlto_src_module",
2045 {MDString::get(DestModule.getContext(),
2046 SrcModule->getModuleIdentifier())}));
2050 {MDString::get(DestModule.getContext(),
2051 SrcModule->getSourceFileName())}));
2053 GlobalsToImport.
insert(Fn);
2066 SrcModule->setPartialSampleProfileRatio(Index);
2073 for (
const auto *GV : GlobalsToImport)
2075 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
2078 if (
Error Err = Mover.
move(std::move(SrcModule),
2082 Twine(
"Function Import: link error: ") +
2085 ImportedCount += GlobalsToImport.
size();
2086 NumImportedModules++;
2091 NumImportedFunctions += (ImportedCount - ImportedGVCount);
2092 NumImportedGlobalVars += ImportedGVCount;
2095 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
2096 <<
" functions for Module "
2099 <<
" global variables for Module "
2101 return ImportedCount;
2111 if (!IndexPtrOrErr) {
2116 std::unique_ptr<ModuleSummaryIndex> Index = std::move(*IndexPtrOrErr);
2126 *Index, ImportList);
2129 isPrevailing, *Index, ImportList);
2135 for (
auto &
I : *Index) {
2136 for (
auto &S :
I.second.getSummaryList()) {
2138 S->setExternalLinkageForTest();
2148 auto ModuleLoader = [&M](
StringRef Identifier) {
2149 return loadFile(std::string(Identifier), M.getContext());
2158 "Error importing module: ");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static auto qualifyCalleeCandidates(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, StringRef CallerModulePath)
Given a list of possible callee implementation for a call site, qualify the legality of importing eac...
static DenseMap< StringRef, ImportStatistics > collectImportStatistics(const ModuleSummaryIndex &Index, const FunctionImporter::ImportMapTy &ImportList)
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, FunctionImporter::ExportSetTy &ExportSet)
static bool checkVariableImport(const ModuleSummaryIndex &Index, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
static bool doImportingForModuleForTest(Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
static const char * getFailureName(FunctionImporter::ImportFailureReason Reason)
static void internalizeGVsAfterImport(Module &M)
void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, FunctionSummary *FS)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
static bool shouldSkipLocalInAnotherModule(const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void dumpImportListForModule(const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleFromIndexForTest(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold fo...
static void ComputeCrossModuleImportForModuleForTest(StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
block placement Basic Block Placement Stats
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
static constexpr StringLiteral Filename
Reader for contextual iFDO profile, which comes in bitstream format.
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Import globals referenced by a function or other globals that are being imported, if importing such g...
void onImportingSummary(const GlobalValueSummary &Summary)
GlobalsImporter(const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
virtual bool canImport(ValueInfo VI)
DenseMap< StringRef, FunctionImporter::ExportSetTy > *const ExportLists
virtual ~ModuleImportsManager()=default
static std::unique_ptr< ModuleImportsManager > create(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing
ModuleImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
const ModuleSummaryIndex & Index
virtual void computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName, FunctionImporter::ImportMapTy &ImportList)
Given the list of globals defined in a module, compute the list of imports as well as the list of "ex...
WorkloadImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ValueT & at(const_arg_type_t< KeyT > Val)
at - Return the entry for the specified key, or abort if no such entry exists.
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.
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
The map maintains the list of imports.
LLVM_ABI AddDefinitionStatus addDefinition(StringRef FromModule, GlobalValue::GUID GUID)
void addGUID(StringRef FromModule, GlobalValue::GUID GUID, GlobalValueSummary::ImportKind ImportKind)
LLVM_ABI SmallVector< StringRef, 0 > getSourceModules() const
LLVM_ABI std::optional< GlobalValueSummary::ImportKind > getImportType(StringRef FromModule, GlobalValue::GUID GUID) const
LLVM_ABI void maybeAddDeclaration(StringRef FromModule, GlobalValue::GUID GUID)
The function importer is automatically importing function from other modules based on the provided su...
LLVM_ABI Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
DenseMap< GlobalValue::GUID, std::tuple< unsigned, const GlobalValueSummary *, std::unique_ptr< ImportFailureInfo > > > ImportThresholdsTy
Map of callee GUID considered for import into a given module to a pair consisting of the largest thre...
ImportFailureReason
The different reasons selectCallee will chose not to import a candidate.
@ LocalLinkageNotInModule
DenseSet< ValueInfo > ExportSetTy
The set contains an entry for every global value that the module exports.
Function summary information to aid decisions and implementation of importing.
unsigned instCount() const
Get the instruction count recorded for this function.
FFlags fflags() const
Get function summary flags.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
LLVM_ABI const GlobalObject * getAliaseeObject() const
Function and variable summary information to aid decisions and implementation of importing.
StringRef modulePath() const
Get the path to the module containing this function.
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const GlobalObject * getAliaseeObject() const
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
static LLVM_ABI std::string getGlobalIdentifier(StringRef Name, GlobalValue::LinkageTypes Linkage, StringRef FileName)
Return the modified name for a global value suitable to be used as the key for a global lookup (e....
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
LLVM_ABI Error materialize()
Make sure this GlobalValue is fully read.
LLVM_ABI bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
@ 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.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isFunctionTy() const
True if this is an instance of FunctionType.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
The root is the trivial Path to the root value.
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
bool fromJSON(const Value &E, std::string &Out, Path P)
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
static cl::opt< float > ImportHotMultiplier("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"))
static cl::opt< bool > CtxprofMoveRootsToOwnModule("thinlto-move-ctxprof-trees", cl::desc("Move contextual profiling roots and the graphs under them in " "their own module."), cl::Hidden, cl::init(false))
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
static cl::opt< float > ImportColdMultiplier("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"))
std::error_code make_error_code(BitcodeError E)
cl::list< GlobalValue::GUID > MoveSymbolGUID
const char * getHotnessName(CalleeInfo::HotnessType HT)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
static cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy ...
DenseMap< GlobalValue::GUID, GlobalValueSummary * > GVSummaryMapTy
Map of global value GUID to its summary, used to identify values defined in a particular module,...
cl::opt< std::string > UseCtxProfile("use-ctx-profile", cl::init(""), cl::Hidden, cl::desc("Use the specified contextual profile file"))
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
static cl::opt< unsigned > ImportInstrLimit("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
LLVM_ABI void renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
static cl::opt< float > ImportHotInstrFactor("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static cl::opt< bool > PrintImports("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions"))
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
LLVM_ABI void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
auto dyn_cast_or_null(const Y &Val)
static cl::opt< float > ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
cl::opt< bool > AlwaysRenamePromotedLocals("always-rename-promoted-locals", cl::init(true), cl::Hidden, cl::desc("Always rename promoted locals."))
LLVM_ABI void computeDeadSymbolsAndUpdateIndirectCalls(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing)
Compute all the symbols that are "dead": i.e these that can't be reached in the graph from any of the...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
std::map< std::string, GVSummaryMapTy, std::less<> > ModuleToSummariesForIndexTy
Map of a module name to the GUIDs and summaries we will import from that module.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
static cl::opt< 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< int > ImportCutoff("import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)"))
static cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI void updateIndirectCalls(ModuleSummaryIndex &Index)
Update call edges for indirect calls to local functions added from SamplePGO when needed.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
LLVM_ABI std::unique_ptr< Module > getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given file holds a bitcode image, return a Module for it which does lazy deserialization of fu...
LLVM_ABI void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
cl::opt< bool > ForceImportAll
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.
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.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI void processImportsFiles(StringRef ModulePath, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex, function_ref< void(const std::string &)> F)
Call F passing each of the files module ModulePath will import from.
static cl::opt< float > ImportCriticalMultiplier("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for critical callsites"))
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
PrevailingType
PrevailingType enum used as a return type of callback passed to computeDeadSymbolsAndUpdateIndirectCa...
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
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'"))
LLVM_ABI Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
LLVM_ABI void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
LLVM_ABI Expected< std::unique_ptr< ModuleSummaryIndex > > getModuleSummaryIndexForFile(StringRef Path, bool IgnoreEmptyThinLTOIndexFile=false)
Parse the module summary index out of an IR file and return the module summary index object if found,...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
Struct that holds a reference to a particular GUID in a global value summary.