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"
178 "import-assume-unique-local",
cl::init(
false),
180 "By default, a local-linkage global variable won't be imported in the "
181 "edge mod1:func -> mod2:local-var (from value profiles) since compiler "
182 "cannot assume mod2 is compiled with full path which gives local-var a "
183 "program-wide unique GUID. Set this option to true will help cross "
184 "module import of such variables. This is only safe if the compiler "
185 "user specify the full module path."),
193static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
199 std::unique_ptr<Module> Result =
203 Err.print(
"function-import",
errs());
233 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
237 [&
Index, CalleeSummaryList,
238 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
241 auto *GVSummary = SummaryPtr.get();
242 if (!
Index.isGlobalValueLive(GVSummary))
243 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
246 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
249 auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());
257 return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};
274 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
279 if (Summary->notEligibleToImport())
280 return {FunctionImporter::ImportFailureReason::NotEligible,
283 return {FunctionImporter::ImportFailureReason::None, GVSummary};
304 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
305 unsigned Threshold,
StringRef CallerModulePath,
309 TooLargeOrNoInlineSummary =
nullptr;
310 auto QualifiedCandidates =
312 for (
auto QualifiedValue : QualifiedCandidates) {
313 Reason = QualifiedValue.first;
315 if (Reason != FunctionImporter::ImportFailureReason::None)
318 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
322 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
324 TooLargeOrNoInlineSummary = Summary;
325 Reason = FunctionImporter::ImportFailureReason::TooLarge;
331 TooLargeOrNoInlineSummary = Summary;
332 Reason = FunctionImporter::ImportFailureReason::NoInline;
357 bool shouldImportGlobal(
const ValueInfo &VI) {
358 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
359 if (GVS == DefinedGVSummaries.
end())
371 if (VI.getSummaryList().size() > 1 &&
373 !IsPrevailing(VI.getGUID(), GVS->second))
382 for (
const auto &VI : Summary.refs()) {
383 if (!shouldImportGlobal(VI)) {
385 dbgs() <<
"Ref ignored! Target already in destination module.\n");
391 for (
const auto &RefSummary : VI.getSummaryList()) {
392 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
398 if (!GVS || !
Index.canImportGlobalVar(GVS,
true) ||
400 Summary.modulePath()))
405 auto [Iter, Inserted] =
416 NumImportedGlobalVarsThinLink++;
421 (*ExportLists)[RefSummary->modulePath()].insert(VI);
425 if (!
Index.isWriteOnly(GVS))
439 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
440 IsPrevailing(IsPrevailing), ImportList(ImportList),
441 ExportLists(ExportLists) {}
445 onImportingSummaryImpl(Summary, Worklist);
446 while (!Worklist.
empty())
447 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
479 static std::unique_ptr<ModuleImportsManager>
500 auto SetIter = Workloads.
find(ModName);
501 if (SetIter == Workloads.
end()) {
503 <<
" does not contain the root of any context.\n");
505 ModName, ImportList);
508 <<
" contains the root(s) of context(s).\n");
512 auto &ValueInfos = SetIter->second;
515 auto It = DefinedGVSummaries.
find(VI.getGUID());
516 if (It != DefinedGVSummaries.
end() &&
519 dbgs() <<
"[Workload] " << VI.name()
520 <<
" has the prevailing variant already in the module "
521 << ModName <<
". No need to import\n");
531 [&](
const auto &Candidate) {
533 <<
" from " << Candidate.second->modulePath()
534 <<
" ImportFailureReason: "
536 return Candidate.first ==
537 FunctionImporter::ImportFailureReason::None;
539 [](
const auto &Candidate) {
return Candidate.second; });
540 if (PotentialCandidates.empty()) {
542 <<
" because can't find eligible Callee. Guid is: "
543 << Function::getGUID(VI.name()) <<
"\n");
561 PotentialCandidates, [&](
const auto *Candidate) {
564 if (PrevailingCandidates.empty()) {
565 GVS = *PotentialCandidates.begin();
570 <<
"[Workload] Found multiple non-prevailing candidates for "
572 <<
". This is unexpected. Are module paths passed to the "
573 "compiler unique for the modules passed to the linker?");
582 GVS = *PrevailingCandidates.begin();
589 if (ExportingModule == ModName) {
591 <<
" because its defining module is the same as the "
595 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
596 << ExportingModule <<
" : "
597 << Function::getGUID(VI.name()) <<
"\n");
598 ImportList[ExportingModule][VI.getGUID()] =
602 (*ExportLists)[ExportingModule].insert(VI);
620 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
625 dbgs() <<
"[Workload] Function name " << Name
626 <<
" present in the workload definition is ambiguous. Consider "
627 "compiling with -funique-internal-linkage-names.";
632 if (std::error_code EC = BufferOrErr.getError()) {
636 auto Buffer = std::move(BufferOrErr.get());
637 std::map<std::string, std::vector<std::string>> WorkloadDefs;
650 for (
const auto &Workload : WorkloadDefs) {
651 const auto &Root = Workload.first;
652 DbgReportIfAmbiguous(Root);
654 const auto &AllCallees = Workload.second;
655 auto RootIt = NameToValueInfo.
find(Root);
656 if (RootIt == NameToValueInfo.
end()) {
658 <<
" not found in this linkage unit.\n");
661 auto RootVI = RootIt->second;
662 if (RootVI.getSummaryList().size() != 1) {
664 <<
" should have exactly one summary, but has "
665 << RootVI.getSummaryList().size() <<
". Skipping.\n");
669 RootVI.getSummaryList().
front()->modulePath();
670 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
671 <<
" is : " << RootDefiningModule <<
"\n");
672 auto &Set = Workloads[RootDefiningModule];
673 for (
const auto &Callee : AllCallees) {
675 DbgReportIfAmbiguous(Callee);
676 auto ElemIt = NameToValueInfo.
find(Callee);
677 if (ElemIt == NameToValueInfo.
end()) {
681 Set.insert(ElemIt->second);
684 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
685 <<
" distinct callees.\n";
686 for (
const auto &VI : Set) {
687 dbgs() <<
"[Workload] Root: " << Root
688 <<
" Would include: " << VI.getGUID() <<
"\n";
701 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
702 return std::unique_ptr<ModuleImportsManager>(
705 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
713 case FunctionImporter::ImportFailureReason::None:
715 case FunctionImporter::ImportFailureReason::GlobalVar:
717 case FunctionImporter::ImportFailureReason::NotLive:
719 case FunctionImporter::ImportFailureReason::TooLarge:
721 case FunctionImporter::ImportFailureReason::InterposableLinkage:
722 return "InterposableLinkage";
723 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
724 return "LocalLinkageNotInModule";
725 case FunctionImporter::ImportFailureReason::NotEligible:
726 return "NotEligible";
727 case FunctionImporter::ImportFailureReason::NoInline:
738 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
746 static int ImportCount = 0;
747 for (
const auto &Edge : Summary.calls()) {
749 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
758 if (DefinedGVSummaries.
count(VI.getGUID())) {
762 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
767 if (Hotness == CalleeInfo::HotnessType::Hot)
769 if (Hotness == CalleeInfo::HotnessType::Cold)
771 if (Hotness == CalleeInfo::HotnessType::Critical)
776 const auto NewThreshold =
777 Threshold * GetBonusMultiplier(Edge.second.getHotness());
779 auto IT = ImportThresholds.
insert(std::make_pair(
780 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
781 bool PreviouslyVisited = !
IT.second;
782 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
783 auto &CalleeSummary = std::get<1>(
IT.first->second);
784 auto &FailureInfo = std::get<2>(
IT.first->second);
787 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
788 bool IsCriticalCallsite =
789 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
793 assert(PreviouslyVisited);
798 if (NewThreshold <= ProcessedThreshold) {
800 dbgs() <<
"ignored! Target was already imported with Threshold "
801 << ProcessedThreshold <<
"\n");
805 ProcessedThreshold = NewThreshold;
806 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
810 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
812 dbgs() <<
"ignored! Target was already rejected with Threshold "
813 << ProcessedThreshold <<
"\n");
816 "Expected FailureInfo for previously rejected candidate");
817 FailureInfo->Attempts++;
828 Summary.modulePath(), SummaryForDeclImport, Reason);
829 if (!CalleeSummary) {
846 if (PreviouslyVisited) {
847 ProcessedThreshold = NewThreshold;
850 "Expected FailureInfo for previously rejected candidate");
851 FailureInfo->Reason = Reason;
852 FailureInfo->Attempts++;
853 FailureInfo->MaxHotness =
854 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
858 "Expected no FailureInfo for newly rejected candidate");
859 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
860 VI, Edge.second.getHotness(), Reason, 1);
863 std::string Msg = std::string(
"Failed to import function ") +
864 VI.name().str() +
" due to " +
866 auto Error = make_error<StringError>(
869 "Error importing module: ");
873 <<
"ignored! No qualifying callee with summary found.\n");
879 CalleeSummary = CalleeSummary->getBaseObject();
880 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
883 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
884 "selectCallee() didn't honor the threshold");
886 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
890 auto [Iter, Inserted] = ImportList[ExportModulePath].
try_emplace(
896 NumImportedFunctionsThinLink++;
898 NumImportedHotFunctionsThinLink++;
899 if (IsCriticalCallsite)
900 NumImportedCriticalFunctionsThinLink++;
910 (*ExportLists)[ExportModulePath].insert(VI);
913 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
922 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
927 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
943 for (
const auto &GVSummary : DefinedGVSummaries) {
947 auto VI =
Index.getValueInfo(GVSummary.first);
949 if (!
Index.isGlobalValueLive(GVSummary.second)) {
954 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
965 while (!Worklist.
empty()) {
967 auto *Summary = std::get<0>(GVInfo);
968 auto Threshold = std::get<1>(GVInfo);
970 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
979 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
980 for (
auto &
I : ImportThresholds) {
981 auto &ProcessedThreshold = std::get<0>(
I.second);
982 auto &CalleeSummary = std::get<1>(
I.second);
983 auto &FailureInfo = std::get<2>(
I.second);
988 if (!FailureInfo->VI.getSummaryList().empty())
989 FS = dyn_cast<FunctionSummary>(
990 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
991 dbgs() << FailureInfo->VI
993 <<
", Threshold = " << ProcessedThreshold
994 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
996 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
1003 auto SL = VI.getSummaryList();
1011 if (
const auto &VI =
Index.getValueInfo(
G))
1020 unsigned NumGVS = 0;
1021 for (
auto &VI : ExportSet)
1032 unsigned &DefinedFS) {
1033 unsigned NumGVS = 0;
1035 for (
auto &[GUID,
Type] : ImportMap) {
1052 for (
auto &ImportPerModule : ImportLists)
1053 for (
auto &ExportPerModule : ImportPerModule.second)
1054 for (
auto &[GUID,
Type] : ExportPerModule.second)
1055 FlattenedImports.
insert(GUID);
1063 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
1065 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
1066 Index.findSummaryInModule(VI, ModulePath));
1067 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
1073 for (
auto &ExportPerModule : ExportLists)
1074 for (
auto &VI : ExportPerModule.second)
1075 if (!FlattenedImports.
count(VI.getGUID()) &&
1076 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1093 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1094 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1096 << DefinedGVSummaries.first <<
"'\n");
1097 MIS->computeImportForModule(DefinedGVSummaries.second,
1098 DefinedGVSummaries.first, ImportList);
1106 for (
auto &ELI : ExportLists) {
1110 const auto &DefinedGVSummaries =
1111 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1112 for (
auto &EI : ELI.second) {
1119 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1123 auto *S = DS->getSecond();
1124 S = S->getBaseObject();
1125 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1130 if (!
Index.isWriteOnly(GVS))
1131 for (
const auto &VI : GVS->refs())
1134 auto *FS = cast<FunctionSummary>(S);
1135 for (
const auto &Edge : FS->calls())
1136 NewExports.
insert(Edge.first);
1137 for (
const auto &
Ref : FS->refs())
1145 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1146 if (!DefinedGVSummaries.
count(EI->getGUID()))
1147 NewExports.
erase(EI++);
1151 ELI.second.insert(NewExports.
begin(), NewExports.
end());
1158 for (
auto &ModuleImports : ImportLists) {
1159 auto ModName = ModuleImports.first;
1160 auto &Exports = ExportLists[ModName];
1163 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1164 <<
" vars. Imports from " << ModuleImports.second.size()
1166 for (
auto &Src : ModuleImports.second) {
1167 auto SrcModName = Src.first;
1168 unsigned DefinedFS = 0;
1169 unsigned NumGVSPerMod =
1171 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1172 << Src.second.size() - NumGVSPerMod - DefinedFS
1173 <<
" function declarations imported from " << SrcModName
1176 <<
" global vars imported from " << SrcModName <<
"\n");
1186 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1187 << ImportList.
size() <<
" modules.\n");
1188 for (
auto &Src : ImportList) {
1189 auto SrcModName = Src.first;
1190 unsigned DefinedFS = 0;
1192 LLVM_DEBUG(
dbgs() <<
" - " << DefinedFS <<
" function definitions and "
1193 << Src.second.size() - DefinedFS - NumGVSPerMod
1194 <<
" function declarations imported from " << SrcModName
1196 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
1197 << SrcModName <<
"\n");
1219 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1222 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1224 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1239 for (
const auto &GlobalList :
Index) {
1241 if (GlobalList.second.SummaryList.empty())
1244 auto GUID = GlobalList.first;
1245 assert(GlobalList.second.SummaryList.size() == 1 &&
1246 "Expected individual combined index to have one summary per GUID");
1247 auto &Summary = GlobalList.second.SummaryList[0];
1250 if (Summary->modulePath() == ModulePath)
1253 auto [Iter, Inserted] = ImportList[Summary->modulePath()].
try_emplace(
1254 GUID, Summary->importType());
1258 Iter->second = std::min(Iter->second, Summary->importType());
1272 for (
auto &EI : FS->mutableCalls()) {
1273 if (!EI.first.getSummaryList().empty())
1275 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
1279 auto VI =
Index.getValueInfo(GUID);
1281 VI.getSummaryList(),
1282 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1292 return SummaryPtr->getSummaryKind() ==
1293 GlobalValueSummary::GlobalVarKind;
1301 for (
const auto &Entry :
Index) {
1302 for (
const auto &S : Entry.second.SummaryList) {
1303 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1316 GUIDPreservedSymbols.
empty()) {
1321 unsigned LiveSymbols = 0;
1323 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1324 for (
auto GUID : GUIDPreservedSymbols) {
1328 for (
const auto &S : VI.getSummaryList())
1333 for (
const auto &Entry :
Index) {
1334 auto VI =
Index.getValueInfo(Entry);
1335 for (
const auto &S : Entry.second.SummaryList) {
1336 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1348 auto visit = [&](
ValueInfo VI,
bool IsAliasee) {
1359 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1369 if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
1370 bool KeepAliveLinkage =
false;
1371 bool Interposable =
false;
1372 for (
const auto &S : VI.getSummaryList()) {
1376 KeepAliveLinkage =
true;
1378 Interposable =
true;
1382 if (!KeepAliveLinkage)
1387 "Interposable and available_externally/linkonce_odr/weak_odr "
1392 for (
const auto &S : VI.getSummaryList())
1398 while (!Worklist.
empty()) {
1400 for (
const auto &Summary : VI.getSummaryList()) {
1401 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1405 visit(AS->getAliaseeVI(),
true);
1408 for (
auto Ref : Summary->refs())
1410 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1411 for (
auto Call : FS->calls())
1412 visit(Call.first,
false);
1415 Index.setWithGlobalValueDeadStripping();
1417 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1418 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1419 <<
" symbols Dead \n");
1420 NumDeadSymbols += DeadSymbols;
1421 NumLiveSymbols += LiveSymbols;
1429 bool ImportEnabled) {
1433 Index.propagateAttributes(GUIDPreservedSymbols);
1442 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
1445 ModuleToSummariesForIndex[std::string(ModulePath)] =
1446 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1448 for (
const auto &ILI : ImportList) {
1449 auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];
1451 const auto &DefinedGVSummaries =
1452 ModuleToDefinedGVSummaries.
lookup(ILI.first);
1453 for (
const auto &[GUID,
Type] : ILI.second) {
1454 const auto &DS = DefinedGVSummaries.
find(GUID);
1455 assert(DS != DefinedGVSummaries.
end() &&
1456 "Expected a defined summary for imported global value");
1458 DecSummaries.insert(DS->second);
1460 SummariesForIndex[GUID] = DS->second;
1468 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1473 for (
const auto &ILI : ModuleToSummariesForIndex)
1477 if (ILI.first != ModulePath)
1478 ImportsOS << ILI.first <<
"\n";
1479 return std::error_code();
1485 if (
Function *
F = dyn_cast<Function>(&GV)) {
1488 F->setComdat(
nullptr);
1490 V->setInitializer(
nullptr);
1493 V->setComdat(
nullptr);
1521 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1523 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1524 if (GS == DefinedGlobals.
end())
1529 if (
Function *
F = dyn_cast<Function>(&GV)) {
1531 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1532 F->setDoesNotAccessMemory();
1534 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1535 F->setOnlyReadsMemory();
1537 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1538 F->setDoesNotRecurse();
1540 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1541 F->setDoesNotThrow();
1545 auto NewLinkage = GS->second->linkage();
1584 GS->second->canAutoHide()) {
1590 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1597 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1598 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1599 if (GO->getComdat()->getName() == GO->getName())
1600 NonPrevailingComdats.
insert(GO->getComdat());
1601 GO->setComdat(
nullptr);
1606 for (
auto &GV : TheModule)
1608 for (
auto &GV : TheModule.
globals())
1609 FinalizeInModule(GV);
1610 for (
auto &GV : TheModule.
aliases())
1611 FinalizeInModule(GV);
1616 if (NonPrevailingComdats.
empty())
1619 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1620 GO.setComdat(
nullptr);
1631 for (
auto &GA : TheModule.
aliases()) {
1632 if (GA.hasAvailableExternallyLinkage())
1635 assert(Obj &&
"aliasee without an base object is unimplemented");
1649 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1653 if (isa<GlobalIFunc>(&GV) ||
1654 (isa<GlobalAlias>(&GV) &&
1655 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1659 auto GS = DefinedGlobals.
find(GV.getGUID());
1660 if (GS == DefinedGlobals.
end()) {
1672 if (GS == DefinedGlobals.
end()) {
1709 for (
auto &GV : M.globals())
1712 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1724 unsigned ImportedCount = 0, ImportedGVCount = 0;
1728 std::set<StringRef> ModuleNameOrderedList;
1729 for (
const auto &FunctionsToImportPerModule : ImportList) {
1730 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);
1735 -> std::optional<GlobalValueSummary::ImportKind> {
1736 auto Iter = GUIDToImportType.find(GUID);
1737 if (Iter == GUIDToImportType.end())
1738 return std::nullopt;
1739 return Iter->second;
1742 for (
const auto &
Name : ModuleNameOrderedList) {
1744 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1745 assert(FunctionsToImportPerModule != ImportList.
end());
1747 if (!SrcModuleOrErr)
1749 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1751 "Context mismatch");
1755 if (
Error Err = SrcModule->materializeMetadata())
1756 return std::move(Err);
1758 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1765 auto GUID =
F.getGUID();
1766 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1768 bool ImportDefinition =
1773 <<
" importing function"
1774 << (ImportDefinition
1776 : (MaybeImportType ?
" declaration " :
" "))
1777 << GUID <<
" " <<
F.getName() <<
" from "
1778 << SrcModule->getSourceFileName() <<
"\n");
1779 if (ImportDefinition) {
1780 if (
Error Err =
F.materialize())
1781 return std::move(Err);
1788 "thinlto_src_module",
1790 {MDString::get(DestModule.getContext(),
1791 SrcModule->getModuleIdentifier())}));
1795 {MDString::get(DestModule.getContext(),
1796 SrcModule->getSourceFileName())}));
1804 auto GUID = GV.getGUID();
1805 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1807 bool ImportDefinition =
1812 <<
" importing global"
1813 << (ImportDefinition
1815 : (MaybeImportType ?
" declaration " :
" "))
1816 << GUID <<
" " << GV.getName() <<
" from "
1817 << SrcModule->getSourceFileName() <<
"\n");
1818 if (ImportDefinition) {
1819 if (
Error Err = GV.materialize())
1820 return std::move(Err);
1821 ImportedGVCount += GlobalsToImport.
insert(&GV);
1825 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1827 auto GUID = GA.getGUID();
1828 auto MaybeImportType = getImportType(ImportGUIDs, GUID);
1830 bool ImportDefinition =
1835 <<
" importing alias"
1836 << (ImportDefinition
1838 : (MaybeImportType ?
" declaration " :
" "))
1839 << GUID <<
" " << GA.getName() <<
" from "
1840 << SrcModule->getSourceFileName() <<
"\n");
1841 if (ImportDefinition) {
1842 if (
Error Err = GA.materialize())
1843 return std::move(Err);
1847 return std::move(Err);
1851 << SrcModule->getSourceFileName() <<
"\n");
1856 "thinlto_src_module",
1858 {MDString::get(DestModule.getContext(),
1859 SrcModule->getModuleIdentifier())}));
1863 {MDString::get(DestModule.getContext(),
1864 SrcModule->getSourceFileName())}));
1866 GlobalsToImport.
insert(Fn);
1878 SrcModule->setPartialSampleProfileRatio(
Index);
1886 for (
const auto *GV : GlobalsToImport)
1888 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1891 if (
Error Err = Mover.
move(std::move(SrcModule),
1895 Twine(
"Function Import: link error: ") +
1898 ImportedCount += GlobalsToImport.
size();
1899 NumImportedModules++;
1904 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1905 NumImportedGlobalVars += ImportedGVCount;
1908 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1909 <<
" functions for Module "
1912 <<
" global variables for Module "
1914 return ImportedCount;
1924 if (!IndexPtrOrErr) {
1929 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1938 *
Index, ImportList);
1941 isPrevailing, *
Index, ImportList);
1948 for (
auto &S :
I.second.SummaryList) {
1958 errs() <<
"Error renaming module\n";
1963 auto ModuleLoader = [&M](
StringRef Identifier) {
1964 return loadFile(std::string(Identifier), M.getContext());
1973 "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 > ImportAssumeUniqueLocal("import-assume-unique-local", cl::init(false), cl::desc("By default, a local-linkage global variable won't be imported in the " "edge mod1:func -> mod2:local-var (from value profiles) since compiler " "cannot assume mod2 is compiled with full path which gives local-var a " "program-wide unique GUID. Set this option to true will help cross " "module import of such variables. This is only safe if the compiler " "user specify the full module path."), cl::Hidden)
static cl::opt< bool > ForceImportAll("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute"))
static bool shouldSkipLocalInAnotherModule(const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static bool isGlobalVarSummary(const ModuleSummaryIndex &Index, ValueInfo VI)
static cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
static cl::opt< unsigned > ImportInstrLimit("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
static cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy ...
static cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
static cl::opt< std::string > SummaryFile("summary-file", cl::desc("The summary file to use for function importing."))
Summary file to use for function importing when using -function-import from the command line.
static cl::opt< bool > ImportAllIndex("import-all-index", cl::desc("Import all external functions in index."))
Used when testing importing from distributed indexes via opt.
static cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
static Function * replaceAliasWithAliasee(Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void dumpImportListForModule(const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleFromIndexForTest(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold fo...
static void ComputeCrossModuleImportForModuleForTest(StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
This file supports working with JSON data.
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
static cl::opt< bool > PropagateAttrs("propagate-attrs", cl::init(true), cl::Hidden, cl::desc("Propagate attributes in index"))
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
Module.h This file contains the declarations for the Module class.
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.