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()][VI] =
408 if (!
Index.isWriteOnly(GVS))
422 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
423 IsPrevailing(IsPrevailing), ImportList(ImportList),
424 ExportLists(ExportLists) {}
428 onImportingSummaryImpl(Summary, Worklist);
429 while (!Worklist.
empty())
430 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
462 static std::unique_ptr<ModuleImportsManager>
483 auto SetIter = Workloads.
find(ModName);
484 if (SetIter == Workloads.
end()) {
486 <<
" does not contain the root of any context.\n");
488 ModName, ImportList);
491 <<
" contains the root(s) of context(s).\n");
495 auto &ValueInfos = SetIter->second;
498 auto It = DefinedGVSummaries.
find(VI.getGUID());
499 if (It != DefinedGVSummaries.
end() &&
502 dbgs() <<
"[Workload] " << VI.name()
503 <<
" has the prevailing variant already in the module "
504 << ModName <<
". No need to import\n");
514 [&](
const auto &Candidate) {
516 <<
" from " << Candidate.second->modulePath()
517 <<
" ImportFailureReason: "
519 return Candidate.first ==
520 FunctionImporter::ImportFailureReason::None;
522 [](
const auto &Candidate) {
return Candidate.second; });
523 if (PotentialCandidates.empty()) {
525 <<
" because can't find eligible Callee. Guid is: "
526 << Function::getGUID(VI.name()) <<
"\n");
544 PotentialCandidates, [&](
const auto *Candidate) {
547 if (PrevailingCandidates.empty()) {
548 GVS = *PotentialCandidates.begin();
553 <<
"[Workload] Found multiple non-prevailing candidates for "
555 <<
". This is unexpected. Are module paths passed to the "
556 "compiler unique for the modules passed to the linker?");
565 GVS = *PrevailingCandidates.begin();
572 if (ExportingModule == ModName) {
574 <<
" because its defining module is the same as the "
578 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
579 << ExportingModule <<
" : "
580 << Function::getGUID(VI.name()) <<
"\n");
581 ImportList[ExportingModule][VI.getGUID()] =
603 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
608 dbgs() <<
"[Workload] Function name " << Name
609 <<
" present in the workload definition is ambiguous. Consider "
610 "compiling with -funique-internal-linkage-names.";
615 if (std::error_code EC = BufferOrErr.getError()) {
619 auto Buffer = std::move(BufferOrErr.get());
620 std::map<std::string, std::vector<std::string>> WorkloadDefs;
633 for (
const auto &Workload : WorkloadDefs) {
634 const auto &Root = Workload.first;
635 DbgReportIfAmbiguous(Root);
637 const auto &AllCallees = Workload.second;
638 auto RootIt = NameToValueInfo.
find(Root);
639 if (RootIt == NameToValueInfo.
end()) {
641 <<
" not found in this linkage unit.\n");
644 auto RootVI = RootIt->second;
645 if (RootVI.getSummaryList().size() != 1) {
647 <<
" should have exactly one summary, but has "
648 << RootVI.getSummaryList().size() <<
". Skipping.\n");
652 RootVI.getSummaryList().
front()->modulePath();
653 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
654 <<
" is : " << RootDefiningModule <<
"\n");
655 auto &Set = Workloads[RootDefiningModule];
656 for (
const auto &Callee : AllCallees) {
658 DbgReportIfAmbiguous(Callee);
659 auto ElemIt = NameToValueInfo.
find(Callee);
660 if (ElemIt == NameToValueInfo.
end()) {
664 Set.insert(ElemIt->second);
667 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
668 <<
" distinct callees.\n";
669 for (
const auto &VI : Set) {
670 dbgs() <<
"[Workload] Root: " << Root
671 <<
" Would include: " << VI.getGUID() <<
"\n";
684 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
685 return std::unique_ptr<ModuleImportsManager>(
688 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
696 case FunctionImporter::ImportFailureReason::None:
698 case FunctionImporter::ImportFailureReason::GlobalVar:
700 case FunctionImporter::ImportFailureReason::NotLive:
702 case FunctionImporter::ImportFailureReason::TooLarge:
704 case FunctionImporter::ImportFailureReason::InterposableLinkage:
705 return "InterposableLinkage";
706 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
707 return "LocalLinkageNotInModule";
708 case FunctionImporter::ImportFailureReason::NotEligible:
709 return "NotEligible";
710 case FunctionImporter::ImportFailureReason::NoInline:
721 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
729 static int ImportCount = 0;
730 for (
const auto &Edge : Summary.calls()) {
732 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
741 if (DefinedGVSummaries.
count(VI.getGUID())) {
745 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
750 if (Hotness == CalleeInfo::HotnessType::Hot)
752 if (Hotness == CalleeInfo::HotnessType::Cold)
754 if (Hotness == CalleeInfo::HotnessType::Critical)
759 const auto NewThreshold =
760 Threshold * GetBonusMultiplier(Edge.second.getHotness());
762 auto IT = ImportThresholds.
insert(std::make_pair(
763 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
764 bool PreviouslyVisited = !
IT.second;
765 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
766 auto &CalleeSummary = std::get<1>(
IT.first->second);
767 auto &FailureInfo = std::get<2>(
IT.first->second);
770 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
771 bool IsCriticalCallsite =
772 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
776 assert(PreviouslyVisited);
781 if (NewThreshold <= ProcessedThreshold) {
783 dbgs() <<
"ignored! Target was already imported with Threshold "
784 << ProcessedThreshold <<
"\n");
788 ProcessedThreshold = NewThreshold;
789 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
793 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
795 dbgs() <<
"ignored! Target was already rejected with Threshold "
796 << ProcessedThreshold <<
"\n");
799 "Expected FailureInfo for previously rejected candidate");
800 FailureInfo->Attempts++;
811 Summary.modulePath(), SummaryForDeclImport, Reason);
812 if (!CalleeSummary) {
823 (*ExportLists)[DeclSourceModule].try_emplace(
831 if (PreviouslyVisited) {
832 ProcessedThreshold = NewThreshold;
835 "Expected FailureInfo for previously rejected candidate");
836 FailureInfo->Reason = Reason;
837 FailureInfo->Attempts++;
838 FailureInfo->MaxHotness =
839 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
843 "Expected no FailureInfo for newly rejected candidate");
844 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
845 VI, Edge.second.getHotness(), Reason, 1);
848 std::string Msg = std::string(
"Failed to import function ") +
849 VI.name().str() +
" due to " +
851 auto Error = make_error<StringError>(
854 "Error importing module: ");
858 <<
"ignored! No qualifying callee with summary found.\n");
864 CalleeSummary = CalleeSummary->getBaseObject();
865 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
868 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
869 "selectCallee() didn't honor the threshold");
871 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
875 auto [Iter, Inserted] = ImportList[ExportModulePath].
try_emplace(
881 NumImportedFunctionsThinLink++;
883 NumImportedHotFunctionsThinLink++;
884 if (IsCriticalCallsite)
885 NumImportedCriticalFunctionsThinLink++;
898 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
907 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
912 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
928 for (
const auto &GVSummary : DefinedGVSummaries) {
932 auto VI =
Index.getValueInfo(GVSummary.first);
934 if (!
Index.isGlobalValueLive(GVSummary.second)) {
939 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
950 while (!Worklist.
empty()) {
952 auto *Summary = std::get<0>(GVInfo);
953 auto Threshold = std::get<1>(GVInfo);
955 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
964 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
965 for (
auto &
I : ImportThresholds) {
966 auto &ProcessedThreshold = std::get<0>(
I.second);
967 auto &CalleeSummary = std::get<1>(
I.second);
968 auto &FailureInfo = std::get<2>(
I.second);
973 if (!FailureInfo->VI.getSummaryList().empty())
974 FS = dyn_cast<FunctionSummary>(
975 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
976 dbgs() << FailureInfo->VI
978 <<
", Threshold = " << ProcessedThreshold
979 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
981 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
988 auto SL = VI.getSummaryList();
996 if (
const auto &VI =
Index.getValueInfo(
G))
1003 unsigned &DefinedGVS,
1004 unsigned &DefinedFS) {
1005 unsigned NumGVS = 0;
1008 for (
auto &[GUID,
Type] : Cont) {
1027 for (
auto &ImportPerModule : ImportLists)
1028 for (
auto &ExportPerModule : ImportPerModule.second)
1029 for (
auto &[GUID,
Type] : ExportPerModule.second)
1030 FlattenedImports.
insert(GUID);
1038 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1040 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
1041 Index.findSummaryInModule(VI, ModulePath));
1042 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
1048 for (
auto &ExportPerModule : ExportLists)
1049 for (
auto &[VI, Unused] : ExportPerModule.second)
1050 if (!FlattenedImports.
count(VI.getGUID()) &&
1051 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1068 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1069 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1071 << DefinedGVSummaries.first <<
"'\n");
1072 MIS->computeImportForModule(DefinedGVSummaries.second,
1073 DefinedGVSummaries.first, ImportList);
1081 for (
auto &ELI : ExportLists) {
1083 const auto &DefinedGVSummaries =
1084 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1085 for (
auto &[EI,
Type] : ELI.second) {
1096 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1100 auto *S = DS->getSecond();
1101 S = S->getBaseObject();
1102 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1107 if (!
Index.isWriteOnly(GVS))
1108 for (
const auto &VI : GVS->refs()) {
1114 auto *FS = cast<FunctionSummary>(S);
1115 for (
const auto &Edge : FS->calls()) {
1120 for (
const auto &
Ref : FS->refs()) {
1131 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1132 if (!DefinedGVSummaries.
count(EI->first.getGUID()))
1133 NewExports.
erase(EI++);
1137 ELI.second.insert(NewExports.
begin(), NewExports.
end());
1144 for (
auto &ModuleImports : ImportLists) {
1145 auto ModName = ModuleImports.first;
1146 auto &Exports = ExportLists[ModName];
1147 unsigned DefinedGVS = 0, DefinedFS = 0;
1150 LLVM_DEBUG(
dbgs() <<
"* Module " << ModName <<
" exports " << DefinedFS
1151 <<
" function as definitions, "
1152 << Exports.
size() - NumGVS - DefinedFS
1153 <<
" functions as declarations, " << DefinedGVS
1154 <<
" var definitions and " << NumGVS - DefinedGVS
1155 <<
" var declarations. Imports from "
1156 << ModuleImports.second.size() <<
" modules.\n");
1157 for (
auto &Src : ModuleImports.second) {
1158 auto SrcModName = Src.first;
1159 unsigned DefinedGVS = 0, DefinedFS = 0;
1160 unsigned NumGVSPerMod =
1162 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1163 << Src.second.size() - NumGVSPerMod - DefinedFS
1164 <<
" function declarations imported from " << SrcModName
1166 LLVM_DEBUG(
dbgs() <<
" - " << DefinedGVS <<
" global vars definition and "
1167 << NumGVSPerMod - DefinedGVS
1168 <<
" global vars declaration imported from "
1169 << SrcModName <<
"\n");
1179 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1180 << ImportList.
size() <<
" modules.\n");
1181 for (
auto &Src : ImportList) {
1182 auto SrcModName = Src.first;
1183 unsigned DefinedGVS = 0, DefinedFS = 0;
1184 unsigned NumGVSPerMod =
1186 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1187 << Src.second.size() - DefinedFS - NumGVSPerMod
1188 <<
" function declarations imported from " << SrcModName
1190 LLVM_DEBUG(
dbgs() <<
" - " << DefinedGVS <<
" var definitions and "
1191 << NumGVSPerMod - DefinedGVS
1192 <<
" var declarations imported from " << SrcModName
1215 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1218 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1220 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1235 for (
const auto &GlobalList :
Index) {
1237 if (GlobalList.second.SummaryList.empty())
1240 auto GUID = GlobalList.first;
1241 assert(GlobalList.second.SummaryList.size() == 1 &&
1242 "Expected individual combined index to have one summary per GUID");
1243 auto &Summary = GlobalList.second.SummaryList[0];
1246 if (Summary->modulePath() == ModulePath)
1249 auto [Iter, Inserted] = ImportList[Summary->modulePath()].
try_emplace(
1250 GUID, Summary->importType());
1254 Iter->second = std::min(Iter->second, Summary->importType());
1268 for (
auto &EI : FS->mutableCalls()) {
1269 if (!EI.first.getSummaryList().empty())
1271 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
1275 auto VI =
Index.getValueInfo(GUID);
1277 VI.getSummaryList(),
1278 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1288 return SummaryPtr->getSummaryKind() ==
1289 GlobalValueSummary::GlobalVarKind;
1297 for (
const auto &Entry :
Index) {
1298 for (
const auto &S : Entry.second.SummaryList) {
1299 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1312 GUIDPreservedSymbols.
empty()) {
1317 unsigned LiveSymbols = 0;
1319 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1320 for (
auto GUID : GUIDPreservedSymbols) {
1324 for (
const auto &S : VI.getSummaryList())
1329 for (
const auto &Entry :
Index) {
1330 auto VI =
Index.getValueInfo(Entry);
1331 for (
const auto &S : Entry.second.SummaryList) {
1332 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1344 auto visit = [&](
ValueInfo VI,
bool IsAliasee) {
1355 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1365 if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
1366 bool KeepAliveLinkage =
false;
1367 bool Interposable =
false;
1368 for (
const auto &S : VI.getSummaryList()) {
1372 KeepAliveLinkage =
true;
1374 Interposable =
true;
1378 if (!KeepAliveLinkage)
1383 "Interposable and available_externally/linkonce_odr/weak_odr "
1388 for (
const auto &S : VI.getSummaryList())
1394 while (!Worklist.
empty()) {
1396 for (
const auto &Summary : VI.getSummaryList()) {
1397 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1401 visit(AS->getAliaseeVI(),
true);
1404 for (
auto Ref : Summary->refs())
1406 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1407 for (
auto Call : FS->calls())
1408 visit(Call.first,
false);
1411 Index.setWithGlobalValueDeadStripping();
1413 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1414 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1415 <<
" symbols Dead \n");
1416 NumDeadSymbols += DeadSymbols;
1417 NumLiveSymbols += LiveSymbols;
1425 bool ImportEnabled) {
1429 Index.propagateAttributes(GUIDPreservedSymbols);
1438 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1440 ModuleToSummariesForIndex[std::string(ModulePath)] =
1441 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1443 for (
const auto &ILI : ImportList) {
1444 auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];
1446 const auto &DefinedGVSummaries =
1447 ModuleToDefinedGVSummaries.
lookup(ILI.first);
1448 for (
const auto &[GUID,
Type] : ILI.second) {
1449 const auto &DS = DefinedGVSummaries.
find(GUID);
1450 assert(DS != DefinedGVSummaries.
end() &&
1451 "Expected a defined summary for imported global value");
1455 SummariesForIndex[GUID] = DS->second;
1463 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1468 for (
const auto &ILI : ModuleToSummariesForIndex)
1472 if (ILI.first != ModulePath)
1473 ImportsOS << ILI.first <<
"\n";
1474 return std::error_code();
1480 if (
Function *
F = dyn_cast<Function>(&GV)) {
1483 F->setComdat(
nullptr);
1485 V->setInitializer(
nullptr);
1488 V->setComdat(
nullptr);
1516 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1518 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1519 if (GS == DefinedGlobals.
end())
1524 if (
Function *
F = dyn_cast<Function>(&GV)) {
1526 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1527 F->setDoesNotAccessMemory();
1529 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1530 F->setOnlyReadsMemory();
1532 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1533 F->setDoesNotRecurse();
1535 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1536 F->setDoesNotThrow();
1540 auto NewLinkage = GS->second->linkage();
1579 GS->second->canAutoHide()) {
1585 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1592 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1593 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1594 if (GO->getComdat()->getName() == GO->getName())
1595 NonPrevailingComdats.
insert(GO->getComdat());
1596 GO->setComdat(
nullptr);
1601 for (
auto &GV : TheModule)
1603 for (
auto &GV : TheModule.
globals())
1604 FinalizeInModule(GV);
1605 for (
auto &GV : TheModule.
aliases())
1606 FinalizeInModule(GV);
1611 if (NonPrevailingComdats.
empty())
1614 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1615 GO.setComdat(
nullptr);
1626 for (
auto &GA : TheModule.
aliases()) {
1627 if (GA.hasAvailableExternallyLinkage())
1630 assert(Obj &&
"aliasee without an base object is unimplemented");
1644 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1648 if (isa<GlobalIFunc>(&GV) ||
1649 (isa<GlobalAlias>(&GV) &&
1650 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1654 auto GS = DefinedGlobals.
find(GV.getGUID());
1655 if (GS == DefinedGlobals.
end()) {
1667 if (GS == DefinedGlobals.
end()) {
1704 for (
auto &GV : M.globals())
1707 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1719 unsigned ImportedCount = 0, ImportedGVCount = 0;
1723 std::set<StringRef> ModuleNameOrderedList;
1724 for (
const auto &FunctionsToImportPerModule : ImportList) {
1725 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);
1730 -> std::optional<GlobalValueSummary::ImportKind> {
1731 auto Iter = GUIDToImportType.find(GUID);
1732 if (Iter == GUIDToImportType.end())
1733 return std::nullopt;
1734 return Iter->second;
1737 for (
const auto &
Name : ModuleNameOrderedList) {
1739 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1740 assert(FunctionsToImportPerModule != ImportList.
end());
1742 if (!SrcModuleOrErr)
1744 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1746 "Context mismatch");
1750 if (
Error Err = SrcModule->materializeMetadata())
1751 return std::move(Err);
1753 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1760 auto GUID =
F.getGUID();
1761 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1763 bool ImportDefinition =
1768 <<
" importing function"
1769 << (ImportDefinition
1771 : (MaybeImportType ?
" declaration " :
" "))
1772 << GUID <<
" " <<
F.getName() <<
" from "
1773 << SrcModule->getSourceFileName() <<
"\n");
1774 if (ImportDefinition) {
1775 if (
Error Err =
F.materialize())
1776 return std::move(Err);
1783 "thinlto_src_module",
1785 {MDString::get(DestModule.getContext(),
1786 SrcModule->getModuleIdentifier())}));
1790 {MDString::get(DestModule.getContext(),
1791 SrcModule->getSourceFileName())}));
1799 auto GUID = GV.getGUID();
1800 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1802 bool ImportDefinition =
1807 <<
" importing global"
1808 << (ImportDefinition
1810 : (MaybeImportType ?
" declaration " :
" "))
1811 << GUID <<
" " << GV.getName() <<
" from "
1812 << SrcModule->getSourceFileName() <<
"\n");
1813 if (ImportDefinition) {
1814 if (
Error Err = GV.materialize())
1815 return std::move(Err);
1816 ImportedGVCount += GlobalsToImport.
insert(&GV);
1820 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1822 auto GUID = GA.getGUID();
1823 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1825 bool ImportDefinition =
1830 <<
" importing alias"
1831 << (ImportDefinition
1833 : (MaybeImportType ?
" declaration " :
" "))
1834 << GUID <<
" " << GA.getName() <<
" from "
1835 << SrcModule->getSourceFileName() <<
"\n");
1836 if (ImportDefinition) {
1837 if (
Error Err = GA.materialize())
1838 return std::move(Err);
1842 return std::move(Err);
1846 << SrcModule->getSourceFileName() <<
"\n");
1851 "thinlto_src_module",
1853 {MDString::get(DestModule.getContext(),
1854 SrcModule->getModuleIdentifier())}));
1858 {MDString::get(DestModule.getContext(),
1859 SrcModule->getSourceFileName())}));
1861 GlobalsToImport.
insert(Fn);
1873 SrcModule->setPartialSampleProfileRatio(
Index);
1881 for (
const auto *GV : GlobalsToImport)
1883 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1886 if (
Error Err = Mover.
move(std::move(SrcModule),
1890 Twine(
"Function Import: link error: ") +
1893 ImportedCount += GlobalsToImport.
size();
1894 NumImportedModules++;
1899 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1900 NumImportedGlobalVars += ImportedGVCount;
1903 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1904 <<
" functions for Module "
1907 <<
" global variables for Module "
1909 return ImportedCount;
1919 if (!IndexPtrOrErr) {
1924 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1933 *
Index, ImportList);
1936 isPrevailing, *
Index, ImportList);
1943 for (
auto &S :
I.second.SummaryList) {
1953 errs() <<
"Error renaming module\n";
1958 auto ModuleLoader = [&M](
StringRef Identifier) {
1959 return loadFile(std::string(Identifier), M.getContext());
1968 "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 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.
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont, unsigned &DefinedGVS, unsigned &DefinedFS)
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)
bool erase(const KeyT &Val)
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)
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 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 gatherImportedSummariesForModule(StringRef ModulePath, const DenseMap< StringRef, GVSummaryMapTy > &ModuleToDefinedGVSummaries, const FunctionImporter::ImportMapTy &ImportList, std::map< std::string, GVSummaryMapTy > &ModuleToSummariesForIndex)
Compute the set of summaries needed for a ThinLTO backend compilation of ModulePath.
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 ...
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.