51#include <system_error>
57#define DEBUG_TYPE "function-import"
60 "Number of functions thin link decided to import");
62 "Number of hot functions thin link decided to import");
64 "Number of critical functions thin link decided to import");
66 "Number of global variables thin link decided to import");
67STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
69 "Number of global variables imported in backend");
70STATISTIC(NumImportedModules,
"Number of modules imported from");
71STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
72STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
77 cl::desc(
"Only import functions with less than N instructions"));
81 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
85 cl::desc(
"Import functions with noinline attribute"));
90 cl::desc(
"As we import functions, multiply the "
91 "`import-instr-limit` threshold by this factor "
92 "before processing newly imported functions"));
97 cl::desc(
"As we import functions called from hot callsite, multiply the "
98 "`import-instr-limit` threshold by this factor "
99 "before processing newly imported functions"));
103 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
109 "Multiply the `import-instr-limit` threshold for critical callsites"));
114 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
117 cl::desc(
"Print imported functions"));
121 cl::desc(
"Print information for functions rejected for importing"));
128 cl::desc(
"Enable import metadata like 'thinlto_src_module' and "
129 "'thinlto_src_file'"));
135 cl::desc(
"The summary file to use for function importing."));
141 cl::desc(
"Import all external functions in index."));
151 cl::desc(
"If true, import function declaration as fallback if the function "
152 "definition is not imported."));
163 "thinlto-workload-def",
164 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
165 "dictionary. The keys are root functions, the values are lists of "
166 "functions to import in the module defining the root. It is "
167 "assumed -funique-internal-linkage-names was used, to ensure "
168 "local linkage functions have unique names. For example: \n"
170 " \"rootFunction_1\": [\"function_to_import_1\", "
171 "\"function_to_import_2\"], \n"
172 " \"rootFunction_2\": [\"function_to_import_3\", "
173 "\"function_to_import_4\"] \n"
182static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
188 std::unique_ptr<Module> Result =
192 Err.print(
"function-import",
errs());
205 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
209 [&
Index, CalleeSummaryList,
210 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
213 auto *GVSummary = SummaryPtr.get();
214 if (!
Index.isGlobalValueLive(GVSummary))
215 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
218 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
221 auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());
229 return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};
242 CalleeSummaryList.size() > 1 &&
243 Summary->modulePath() != CallerModulePath)
245 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
250 if (Summary->notEligibleToImport())
251 return {FunctionImporter::ImportFailureReason::NotEligible,
254 return {FunctionImporter::ImportFailureReason::None, GVSummary};
275 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
276 unsigned Threshold,
StringRef CallerModulePath,
280 TooLargeOrNoInlineSummary =
nullptr;
281 auto QualifiedCandidates =
283 for (
auto QualifiedValue : QualifiedCandidates) {
284 Reason = QualifiedValue.first;
286 if (Reason != FunctionImporter::ImportFailureReason::None)
289 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
293 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
295 TooLargeOrNoInlineSummary = Summary;
296 Reason = FunctionImporter::ImportFailureReason::TooLarge;
302 TooLargeOrNoInlineSummary = Summary;
303 Reason = FunctionImporter::ImportFailureReason::NoInline;
328 bool shouldImportGlobal(
const ValueInfo &VI) {
329 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
330 if (GVS == DefinedGVSummaries.
end())
342 if (VI.getSummaryList().size() > 1 &&
344 !IsPrevailing(VI.getGUID(), GVS->second))
353 for (
const auto &VI : Summary.refs()) {
354 if (!shouldImportGlobal(VI)) {
356 dbgs() <<
"Ref ignored! Target already in destination module.\n");
368 auto LocalNotInModule =
371 RefSummary->modulePath() != Summary.modulePath();
374 for (
const auto &RefSummary : VI.getSummaryList()) {
375 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
381 if (!GVS || !
Index.canImportGlobalVar(GVS,
true) ||
382 LocalNotInModule(GVS))
387 auto [Iter, Inserted] =
398 NumImportedGlobalVarsThinLink++;
403 (*ExportLists)[RefSummary->modulePath()].insert(VI);
407 if (!
Index.isWriteOnly(GVS))
421 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
422 IsPrevailing(IsPrevailing), ImportList(ImportList),
423 ExportLists(ExportLists) {}
427 onImportingSummaryImpl(Summary, Worklist);
428 while (!Worklist.
empty())
429 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
461 static std::unique_ptr<ModuleImportsManager>
482 auto SetIter = Workloads.
find(ModName);
483 if (SetIter == Workloads.
end()) {
485 <<
" does not contain the root of any context.\n");
487 ModName, ImportList);
490 <<
" contains the root(s) of context(s).\n");
494 auto &ValueInfos = SetIter->second;
497 auto It = DefinedGVSummaries.
find(VI.getGUID());
498 if (It != DefinedGVSummaries.
end() &&
501 dbgs() <<
"[Workload] " << VI.name()
502 <<
" has the prevailing variant already in the module "
503 << ModName <<
". No need to import\n");
513 [&](
const auto &Candidate) {
515 <<
" from " << Candidate.second->modulePath()
516 <<
" ImportFailureReason: "
518 return Candidate.first ==
519 FunctionImporter::ImportFailureReason::None;
521 [](
const auto &Candidate) {
return Candidate.second; });
522 if (PotentialCandidates.empty()) {
524 <<
" because can't find eligible Callee. Guid is: "
525 << Function::getGUID(VI.name()) <<
"\n");
543 PotentialCandidates, [&](
const auto *Candidate) {
546 if (PrevailingCandidates.empty()) {
547 GVS = *PotentialCandidates.begin();
552 <<
"[Workload] Found multiple non-prevailing candidates for "
554 <<
". This is unexpected. Are module paths passed to the "
555 "compiler unique for the modules passed to the linker?");
564 GVS = *PrevailingCandidates.begin();
571 if (ExportingModule == ModName) {
573 <<
" because its defining module is the same as the "
577 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
578 << ExportingModule <<
" : "
579 << Function::getGUID(VI.name()) <<
"\n");
580 ImportList[ExportingModule][VI.getGUID()] =
584 (*ExportLists)[ExportingModule].insert(VI);
602 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
607 dbgs() <<
"[Workload] Function name " << Name
608 <<
" present in the workload definition is ambiguous. Consider "
609 "compiling with -funique-internal-linkage-names.";
614 if (std::error_code EC = BufferOrErr.getError()) {
618 auto Buffer = std::move(BufferOrErr.get());
619 std::map<std::string, std::vector<std::string>> WorkloadDefs;
632 for (
const auto &Workload : WorkloadDefs) {
633 const auto &Root = Workload.first;
634 DbgReportIfAmbiguous(Root);
636 const auto &AllCallees = Workload.second;
637 auto RootIt = NameToValueInfo.
find(Root);
638 if (RootIt == NameToValueInfo.
end()) {
640 <<
" not found in this linkage unit.\n");
643 auto RootVI = RootIt->second;
644 if (RootVI.getSummaryList().size() != 1) {
646 <<
" should have exactly one summary, but has "
647 << RootVI.getSummaryList().size() <<
". Skipping.\n");
651 RootVI.getSummaryList().
front()->modulePath();
652 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
653 <<
" is : " << RootDefiningModule <<
"\n");
654 auto &Set = Workloads[RootDefiningModule];
655 for (
const auto &Callee : AllCallees) {
657 DbgReportIfAmbiguous(Callee);
658 auto ElemIt = NameToValueInfo.
find(Callee);
659 if (ElemIt == NameToValueInfo.
end()) {
663 Set.insert(ElemIt->second);
666 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
667 <<
" distinct callees.\n";
668 for (
const auto &VI : Set) {
669 dbgs() <<
"[Workload] Root: " << Root
670 <<
" Would include: " << VI.getGUID() <<
"\n";
683 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
684 return std::unique_ptr<ModuleImportsManager>(
687 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
695 case FunctionImporter::ImportFailureReason::None:
697 case FunctionImporter::ImportFailureReason::GlobalVar:
699 case FunctionImporter::ImportFailureReason::NotLive:
701 case FunctionImporter::ImportFailureReason::TooLarge:
703 case FunctionImporter::ImportFailureReason::InterposableLinkage:
704 return "InterposableLinkage";
705 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
706 return "LocalLinkageNotInModule";
707 case FunctionImporter::ImportFailureReason::NotEligible:
708 return "NotEligible";
709 case FunctionImporter::ImportFailureReason::NoInline:
720 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
728 static int ImportCount = 0;
729 for (
const auto &Edge : Summary.calls()) {
731 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
740 if (DefinedGVSummaries.
count(VI.getGUID())) {
744 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
749 if (Hotness == CalleeInfo::HotnessType::Hot)
751 if (Hotness == CalleeInfo::HotnessType::Cold)
753 if (Hotness == CalleeInfo::HotnessType::Critical)
758 const auto NewThreshold =
759 Threshold * GetBonusMultiplier(Edge.second.getHotness());
761 auto IT = ImportThresholds.
insert(std::make_pair(
762 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
763 bool PreviouslyVisited = !
IT.second;
764 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
765 auto &CalleeSummary = std::get<1>(
IT.first->second);
766 auto &FailureInfo = std::get<2>(
IT.first->second);
769 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
770 bool IsCriticalCallsite =
771 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
775 assert(PreviouslyVisited);
780 if (NewThreshold <= ProcessedThreshold) {
782 dbgs() <<
"ignored! Target was already imported with Threshold "
783 << ProcessedThreshold <<
"\n");
787 ProcessedThreshold = NewThreshold;
788 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
792 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
794 dbgs() <<
"ignored! Target was already rejected with Threshold "
795 << ProcessedThreshold <<
"\n");
798 "Expected FailureInfo for previously rejected candidate");
799 FailureInfo->Attempts++;
810 Summary.modulePath(), SummaryForDeclImport, Reason);
811 if (!CalleeSummary) {
828 if (PreviouslyVisited) {
829 ProcessedThreshold = NewThreshold;
832 "Expected FailureInfo for previously rejected candidate");
833 FailureInfo->Reason = Reason;
834 FailureInfo->Attempts++;
835 FailureInfo->MaxHotness =
836 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
840 "Expected no FailureInfo for newly rejected candidate");
841 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
842 VI, Edge.second.getHotness(), Reason, 1);
845 std::string Msg = std::string(
"Failed to import function ") +
846 VI.name().str() +
" due to " +
848 auto Error = make_error<StringError>(
851 "Error importing module: ");
855 <<
"ignored! No qualifying callee with summary found.\n");
861 CalleeSummary = CalleeSummary->getBaseObject();
862 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
865 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
866 "selectCallee() didn't honor the threshold");
868 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
872 auto [Iter, Inserted] = ImportList[ExportModulePath].
try_emplace(
878 NumImportedFunctionsThinLink++;
880 NumImportedHotFunctionsThinLink++;
881 if (IsCriticalCallsite)
882 NumImportedCriticalFunctionsThinLink++;
892 (*ExportLists)[ExportModulePath].insert(VI);
895 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
904 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
909 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
925 for (
const auto &GVSummary : DefinedGVSummaries) {
929 auto VI =
Index.getValueInfo(GVSummary.first);
931 if (!
Index.isGlobalValueLive(GVSummary.second)) {
936 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
947 while (!Worklist.
empty()) {
949 auto *Summary = std::get<0>(GVInfo);
950 auto Threshold = std::get<1>(GVInfo);
952 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
961 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
962 for (
auto &
I : ImportThresholds) {
963 auto &ProcessedThreshold = std::get<0>(
I.second);
964 auto &CalleeSummary = std::get<1>(
I.second);
965 auto &FailureInfo = std::get<2>(
I.second);
970 if (!FailureInfo->VI.getSummaryList().empty())
971 FS = dyn_cast<FunctionSummary>(
972 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
973 dbgs() << FailureInfo->VI
975 <<
", Threshold = " << ProcessedThreshold
976 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
978 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
985 auto SL = VI.getSummaryList();
993 if (
const auto &VI =
Index.getValueInfo(
G))
1002 unsigned NumGVS = 0;
1003 for (
auto &VI : ExportSet)
1014 unsigned &DefinedFS) {
1015 unsigned NumGVS = 0;
1017 for (
auto &[GUID,
Type] : ImportMap) {
1034 for (
auto &ImportPerModule : ImportLists)
1035 for (
auto &ExportPerModule : ImportPerModule.second)
1036 for (
auto &[GUID,
Type] : ExportPerModule.second)
1037 FlattenedImports.
insert(GUID);
1045 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1047 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
1048 Index.findSummaryInModule(VI, ModulePath));
1049 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
1055 for (
auto &ExportPerModule : ExportLists)
1056 for (
auto &VI : ExportPerModule.second)
1057 if (!FlattenedImports.
count(VI.getGUID()) &&
1058 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1075 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1076 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1078 << DefinedGVSummaries.first <<
"'\n");
1079 MIS->computeImportForModule(DefinedGVSummaries.second,
1080 DefinedGVSummaries.first, ImportList);
1088 for (
auto &ELI : ExportLists) {
1092 const auto &DefinedGVSummaries =
1093 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1094 for (
auto &EI : ELI.second) {
1101 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1105 auto *S = DS->getSecond();
1106 S = S->getBaseObject();
1107 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1112 if (!
Index.isWriteOnly(GVS))
1113 for (
const auto &VI : GVS->refs())
1116 auto *FS = cast<FunctionSummary>(S);
1117 for (
const auto &Edge : FS->calls())
1118 NewExports.
insert(Edge.first);
1119 for (
const auto &
Ref : FS->refs())
1127 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1128 if (!DefinedGVSummaries.
count(EI->getGUID()))
1129 NewExports.
erase(EI++);
1133 ELI.second.insert(NewExports.
begin(), NewExports.
end());
1140 for (
auto &ModuleImports : ImportLists) {
1141 auto ModName = ModuleImports.first;
1142 auto &Exports = ExportLists[ModName];
1145 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1146 <<
" vars. Imports from " << ModuleImports.second.size()
1148 for (
auto &Src : ModuleImports.second) {
1149 auto SrcModName = Src.first;
1150 unsigned DefinedFS = 0;
1151 unsigned NumGVSPerMod =
1153 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1154 << Src.second.size() - NumGVSPerMod - DefinedFS
1155 <<
" function declarations imported from " << SrcModName
1158 <<
" global vars imported from " << SrcModName <<
"\n");
1168 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1169 << ImportList.
size() <<
" modules.\n");
1170 for (
auto &Src : ImportList) {
1171 auto SrcModName = Src.first;
1172 unsigned DefinedFS = 0;
1174 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1175 << Src.second.size() - DefinedFS - NumGVSPerMod
1176 <<
" function declarations imported from " << SrcModName
1178 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
1179 << SrcModName <<
"\n");
1201 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1204 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1206 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1221 for (
const auto &GlobalList :
Index) {
1223 if (GlobalList.second.SummaryList.empty())
1226 auto GUID = GlobalList.first;
1227 assert(GlobalList.second.SummaryList.size() == 1 &&
1228 "Expected individual combined index to have one summary per GUID");
1229 auto &Summary = GlobalList.second.SummaryList[0];
1232 if (Summary->modulePath() == ModulePath)
1235 auto [Iter, Inserted] = ImportList[Summary->modulePath()].
try_emplace(
1236 GUID, Summary->importType());
1240 Iter->second = std::min(Iter->second, Summary->importType());
1254 for (
auto &EI : FS->mutableCalls()) {
1255 if (!EI.first.getSummaryList().empty())
1257 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
1261 auto VI =
Index.getValueInfo(GUID);
1263 VI.getSummaryList(),
1264 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1274 return SummaryPtr->getSummaryKind() ==
1275 GlobalValueSummary::GlobalVarKind;
1283 for (
const auto &Entry :
Index) {
1284 for (
const auto &S : Entry.second.SummaryList) {
1285 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1298 GUIDPreservedSymbols.
empty()) {
1303 unsigned LiveSymbols = 0;
1305 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1306 for (
auto GUID : GUIDPreservedSymbols) {
1310 for (
const auto &S : VI.getSummaryList())
1315 for (
const auto &Entry :
Index) {
1316 auto VI =
Index.getValueInfo(Entry);
1317 for (
const auto &S : Entry.second.SummaryList) {
1318 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1330 auto visit = [&](
ValueInfo VI,
bool IsAliasee) {
1341 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1351 if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
1352 bool KeepAliveLinkage =
false;
1353 bool Interposable =
false;
1354 for (
const auto &S : VI.getSummaryList()) {
1358 KeepAliveLinkage =
true;
1360 Interposable =
true;
1364 if (!KeepAliveLinkage)
1369 "Interposable and available_externally/linkonce_odr/weak_odr "
1374 for (
const auto &S : VI.getSummaryList())
1380 while (!Worklist.
empty()) {
1382 for (
const auto &Summary : VI.getSummaryList()) {
1383 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1387 visit(AS->getAliaseeVI(),
true);
1390 for (
auto Ref : Summary->refs())
1392 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1393 for (
auto Call : FS->calls())
1394 visit(Call.first,
false);
1397 Index.setWithGlobalValueDeadStripping();
1399 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1400 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1401 <<
" symbols Dead \n");
1402 NumDeadSymbols += DeadSymbols;
1403 NumLiveSymbols += LiveSymbols;
1411 bool ImportEnabled) {
1415 Index.propagateAttributes(GUIDPreservedSymbols);
1424 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
1427 ModuleToSummariesForIndex[std::string(ModulePath)] =
1428 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1430 for (
const auto &ILI : ImportList) {
1431 auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];
1433 const auto &DefinedGVSummaries =
1434 ModuleToDefinedGVSummaries.
lookup(ILI.first);
1435 for (
const auto &[GUID,
Type] : ILI.second) {
1436 const auto &DS = DefinedGVSummaries.
find(GUID);
1437 assert(DS != DefinedGVSummaries.
end() &&
1438 "Expected a defined summary for imported global value");
1440 DecSummaries.insert(DS->second);
1442 SummariesForIndex[GUID] = DS->second;
1450 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1455 for (
const auto &ILI : ModuleToSummariesForIndex)
1459 if (ILI.first != ModulePath)
1460 ImportsOS << ILI.first <<
"\n";
1461 return std::error_code();
1467 if (
Function *
F = dyn_cast<Function>(&GV)) {
1470 F->setComdat(
nullptr);
1472 V->setInitializer(
nullptr);
1475 V->setComdat(
nullptr);
1503 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1505 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1506 if (GS == DefinedGlobals.
end())
1511 if (
Function *
F = dyn_cast<Function>(&GV)) {
1513 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1514 F->setDoesNotAccessMemory();
1516 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1517 F->setOnlyReadsMemory();
1519 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1520 F->setDoesNotRecurse();
1522 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1523 F->setDoesNotThrow();
1527 auto NewLinkage = GS->second->linkage();
1566 GS->second->canAutoHide()) {
1572 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1579 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1580 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1581 if (GO->getComdat()->getName() == GO->getName())
1582 NonPrevailingComdats.
insert(GO->getComdat());
1583 GO->setComdat(
nullptr);
1588 for (
auto &GV : TheModule)
1590 for (
auto &GV : TheModule.
globals())
1591 FinalizeInModule(GV);
1592 for (
auto &GV : TheModule.
aliases())
1593 FinalizeInModule(GV);
1598 if (NonPrevailingComdats.
empty())
1601 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1602 GO.setComdat(
nullptr);
1613 for (
auto &GA : TheModule.
aliases()) {
1614 if (GA.hasAvailableExternallyLinkage())
1617 assert(Obj &&
"aliasee without an base object is unimplemented");
1631 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1635 if (isa<GlobalIFunc>(&GV) ||
1636 (isa<GlobalAlias>(&GV) &&
1637 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1641 auto GS = DefinedGlobals.
find(GV.getGUID());
1642 if (GS == DefinedGlobals.
end()) {
1654 if (GS == DefinedGlobals.
end()) {
1691 for (
auto &GV : M.globals())
1694 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1706 unsigned ImportedCount = 0, ImportedGVCount = 0;
1710 std::set<StringRef> ModuleNameOrderedList;
1711 for (
const auto &FunctionsToImportPerModule : ImportList) {
1712 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);
1717 -> std::optional<GlobalValueSummary::ImportKind> {
1718 auto Iter = GUIDToImportType.find(GUID);
1719 if (Iter == GUIDToImportType.end())
1720 return std::nullopt;
1721 return Iter->second;
1724 for (
const auto &
Name : ModuleNameOrderedList) {
1726 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1727 assert(FunctionsToImportPerModule != ImportList.
end());
1729 if (!SrcModuleOrErr)
1731 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1733 "Context mismatch");
1737 if (
Error Err = SrcModule->materializeMetadata())
1738 return std::move(Err);
1740 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1747 auto GUID =
F.getGUID();
1748 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1750 bool ImportDefinition =
1755 <<
" importing function"
1756 << (ImportDefinition
1758 : (MaybeImportType ?
" declaration " :
" "))
1759 << GUID <<
" " <<
F.getName() <<
" from "
1760 << SrcModule->getSourceFileName() <<
"\n");
1761 if (ImportDefinition) {
1762 if (
Error Err =
F.materialize())
1763 return std::move(Err);
1770 "thinlto_src_module",
1772 {MDString::get(DestModule.getContext(),
1773 SrcModule->getModuleIdentifier())}));
1777 {MDString::get(DestModule.getContext(),
1778 SrcModule->getSourceFileName())}));
1786 auto GUID = GV.getGUID();
1787 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1789 bool ImportDefinition =
1794 <<
" importing global"
1795 << (ImportDefinition
1797 : (MaybeImportType ?
" declaration " :
" "))
1798 << GUID <<
" " << GV.getName() <<
" from "
1799 << SrcModule->getSourceFileName() <<
"\n");
1800 if (ImportDefinition) {
1801 if (
Error Err = GV.materialize())
1802 return std::move(Err);
1803 ImportedGVCount += GlobalsToImport.
insert(&GV);
1807 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1809 auto GUID = GA.getGUID();
1810 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1812 bool ImportDefinition =
1817 <<
" importing alias"
1818 << (ImportDefinition
1820 : (MaybeImportType ?
" declaration " :
" "))
1821 << GUID <<
" " << GA.getName() <<
" from "
1822 << SrcModule->getSourceFileName() <<
"\n");
1823 if (ImportDefinition) {
1824 if (
Error Err = GA.materialize())
1825 return std::move(Err);
1829 return std::move(Err);
1833 << SrcModule->getSourceFileName() <<
"\n");
1838 "thinlto_src_module",
1840 {MDString::get(DestModule.getContext(),
1841 SrcModule->getModuleIdentifier())}));
1845 {MDString::get(DestModule.getContext(),
1846 SrcModule->getSourceFileName())}));
1848 GlobalsToImport.
insert(Fn);
1860 SrcModule->setPartialSampleProfileRatio(
Index);
1868 for (
const auto *GV : GlobalsToImport)
1870 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1873 if (
Error Err = Mover.
move(std::move(SrcModule),
1877 Twine(
"Function Import: link error: ") +
1880 ImportedCount += GlobalsToImport.
size();
1881 NumImportedModules++;
1886 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1887 NumImportedGlobalVars += ImportedGVCount;
1890 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1891 <<
" functions for Module "
1894 <<
" global variables for Module "
1896 return ImportedCount;
1906 if (!IndexPtrOrErr) {
1911 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1920 *
Index, ImportList);
1923 isPrevailing, *
Index, ImportList);
1930 for (
auto &S :
I.second.SummaryList) {
1940 errs() <<
"Error renaming module\n";
1945 auto ModuleLoader = [&M](
StringRef Identifier) {
1946 return loadFile(std::string(Identifier), M.getContext());
1955 "Error importing module: ");
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static auto qualifyCalleeCandidates(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, StringRef CallerModulePath)
Given a list of possible callee implementation for a call site, qualify the legality of importing eac...
static cl::opt< bool > EnableImportMetadata("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'"))
static cl::opt< float > ImportColdMultiplier("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"))
static cl::opt< float > ImportHotMultiplier("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"))
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, FunctionImporter::ExportSetTy &ExportSet)
static bool checkVariableImport(const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
static bool doImportingForModuleForTest(Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
static cl::opt< float > ImportHotInstrFactor("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static void computeImportForFunction(const FunctionSummary &Summary, const ModuleSummaryIndex &Index, const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, SmallVectorImpl< EdgeInfo > &Worklist, GlobalsImporter &GVImporter, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists, FunctionImporter::ImportThresholdsTy &ImportThresholds)
Compute the list of functions to import for a given caller.
static cl::opt< float > ImportCriticalMultiplier("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for critical callsites"))
static cl::opt< int > ImportCutoff("import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)"))
static const char * getFailureName(FunctionImporter::ImportFailureReason Reason)
static cl::opt< float > ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static void internalizeGVsAfterImport(Module &M)
static cl::opt< bool > PrintImports("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions"))
void updateValueInfoForIndirectCalls(ModuleSummaryIndex &Index, FunctionSummary *FS)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
static cl::opt< bool > ForceImportAll("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute"))
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
static cl::opt< unsigned > ImportInstrLimit("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
static cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy ...
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
static cl::opt< std::string > SummaryFile("summary-file", cl::desc("The summary file to use for function importing."))
Summary file to use for function importing when using -function-import from the command line.
static cl::opt< bool > ImportAllIndex("import-all-index", cl::desc("Import all external functions in index."))
Used when testing importing from distributed indexes via opt.
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void dumpImportListForModule(const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleFromIndexForTest(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold fo...
static void ComputeCrossModuleImportForModuleForTest(StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
This file supports working with JSON data.
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Import globals referenced by a function or other globals that are being imported, if importing such g...
void onImportingSummary(const GlobalValueSummary &Summary)
GlobalsImporter(const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
Determine the list of imports and exports for each module.
DenseMap< StringRef, FunctionImporter::ExportSetTy > *const ExportLists
virtual ~ModuleImportsManager()=default
static std::unique_ptr< ModuleImportsManager > create(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing
ModuleImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists=nullptr)
const ModuleSummaryIndex & Index
virtual void computeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, StringRef ModName, FunctionImporter::ImportMapTy &ImportList)
Given the list of globals defined in a module, compute the list of imports as well as the list of "ex...
A ModuleImportsManager that operates based on a workload definition (see -thinlto-workload-def).
WorkloadImportsManager(function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing, const ModuleSummaryIndex &Index, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists)
A container for analyses that lazily runs them and caches their results.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
The function importer is automatically importing function from other modules based on the provided su...
Expected< bool > importFunctions(Module &M, const ImportMapTy &ImportList)
Import functions in Module M based on the supplied import list.
std::unordered_map< GlobalValue::GUID, GlobalValueSummary::ImportKind > FunctionsToImportTy
The functions to import from a source module and their import type.
ImportFailureReason
The different reasons selectCallee will chose not to import a candidate.
Function summary information to aid decisions and implementation of importing.
unsigned instCount() const
Get the instruction count recorded for this function.
FFlags fflags() const
Get function summary flags.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const GlobalObject * getAliaseeObject() const
Function and variable summary information to aid decisions and implementation of importing.
StringRef modulePath() const
Get the path to the module containing this function.
GlobalValue::LinkageTypes linkage() const
Return linkage type recorded for this global value.
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
static bool isLocalLinkage(LinkageTypes Linkage)
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
void setLinkage(LinkageTypes LT)
unsigned getAddressSpace() const
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Module * getParent()
Get the module that this global value is contained inside of...
const GlobalObject * getAliaseeObject() const
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
Error materialize()
Make sure this GlobalValue is fully read.
bool canBeOmittedFromSymbolTable() const
True if GV can be left out of the object symbol table.
bool hasAvailableExternallyLinkage() const
std::string getGlobalIdentifier() const
Return the modified name for this global value suitable to be used as the key for a global lookup (e....
@ InternalLinkage
Rename collisions when linking (static functions).
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
Error move(std::unique_ptr< Module > Src, ArrayRef< GlobalValue * > ValuesToLink, LazyCallback AddLazyFor, bool IsPerformingImport)
Move in the provide values in ValuesToLink from Src.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Class to hold module path string table and global value map, and encapsulate methods for operating on...
static StringRef getOriginalNameBeforePromote(StringRef Name)
Helper to obtain the unpromoted name for a global value (or the original name if not promoted).
A Module instance is used to store all the information related to an LLVM module.
LLVMContext & getContext() const
Get the global data context.
const std::string & getSourceFileName() const
Get the module's original source file name.
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
iterator_range< global_object_iterator > global_objects()
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
A vector that has set insertion semantics.
ArrayRef< value_type > getArrayRef() const
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isFunctionTy() const
True if this is an instance of FunctionType.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
The root is the trivial Path to the root value.
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
bool fromJSON(const Value &E, std::string &Out, Path P)
This is an optimization pass for GlobalISel generic memory operations.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
void gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex, GVSummaryPtrSet &DecSummaries)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, DenseMap< StringRef, FunctionImporter::ImportMapTy > &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
bool internalizeModule(Module &TheModule, std::function< bool(const GlobalValue &)> MustPreserveGV)
Helper function to internalize functions and variables in a Module.
std::error_code make_error_code(BitcodeError E)
const char * getHotnessName(CalleeInfo::HotnessType HT)
std::error_code EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
auto map_range(ContainerTy &&C, FuncTy F)
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void computeDeadSymbolsAndUpdateIndirectCalls(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing)
Compute all the symbols that are "dead": i.e these that can't be reached in the graph from any of the...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
void updateIndirectCalls(ModuleSummaryIndex &Index)
Update call edges for indirect calls to local functions added from SamplePGO when needed.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
cl::opt< bool > EnableMemProfContextDisambiguation
Enable MemProf context disambiguation for thin link.
std::unique_ptr< Module > getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, bool ShouldLazyLoadMetadata=false)
If the given file holds a bitcode image, return a Module for it which does lazy deserialization of fu...
void thinLTOInternalizeModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals)
Internalize TheModule based on the information recorded in the summaries during global summary-based ...
std::unordered_set< GlobalValueSummary * > GVSummaryPtrSet
A set of global value summary pointers.
PrevailingType
PrevailingType enum used as a return type of callback passed to computeDeadSymbolsAndUpdateIndirectCa...
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
void computeDeadSymbolsWithConstProp(ModuleSummaryIndex &Index, const DenseSet< GlobalValue::GUID > &GUIDPreservedSymbols, function_ref< PrevailingType(GlobalValue::GUID)> isPrevailing, bool ImportEnabled)
Compute dead symbols and run constant propagation in combined index after that.
Expected< std::unique_ptr< ModuleSummaryIndex > > getModuleSummaryIndexForFile(StringRef Path, bool IgnoreEmptyThinLTOIndexFile=false)
Parse the module summary index out of an IR file and return the module summary index object if found,...
void thinLTOFinalizeInModule(Module &TheModule, const GVSummaryMapTy &DefinedGlobals, bool PropagateAttrs)
Based on the information recorded in the summaries during global summary-based analysis:
Struct that holds a reference to a particular GUID in a global value summary.