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."));
152 "thinlto-workload-def",
153 cl::desc(
"Pass a workload definition. This is a file containing a JSON "
154 "dictionary. The keys are root functions, the values are lists of "
155 "functions to import in the module defining the root. It is "
156 "assumed -funique-internal-linkage-names was used, to ensure "
157 "local linkage functions have unique names. For example: \n"
159 " \"rootFunction_1\": [\"function_to_import_1\", "
160 "\"function_to_import_2\"], \n"
161 " \"rootFunction_2\": [\"function_to_import_3\", "
162 "\"function_to_import_4\"] \n"
171static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
177 std::unique_ptr<Module> Result =
181 Err.print(
"function-import",
errs());
194 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
198 [&
Index, CalleeSummaryList,
199 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
202 auto *GVSummary = SummaryPtr.get();
203 if (!
Index.isGlobalValueLive(GVSummary))
204 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
207 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
210 auto *Summary = dyn_cast<FunctionSummary>(GVSummary->getBaseObject());
218 return {FunctionImporter::ImportFailureReason::GlobalVar, GVSummary};
231 CalleeSummaryList.size() > 1 &&
232 Summary->modulePath() != CallerModulePath)
234 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
239 if (Summary->notEligibleToImport())
240 return {FunctionImporter::ImportFailureReason::NotEligible,
243 return {FunctionImporter::ImportFailureReason::None, GVSummary};
260 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
261 unsigned Threshold,
StringRef CallerModulePath,
263 auto QualifiedCandidates =
265 for (
auto QualifiedValue : QualifiedCandidates) {
266 Reason = QualifiedValue.first;
267 if (Reason != FunctionImporter::ImportFailureReason::None)
270 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
272 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
274 Reason = FunctionImporter::ImportFailureReason::TooLarge;
280 Reason = FunctionImporter::ImportFailureReason::NoInline;
305 bool shouldImportGlobal(
const ValueInfo &VI) {
306 const auto &GVS = DefinedGVSummaries.
find(VI.getGUID());
307 if (GVS == DefinedGVSummaries.
end())
319 if (VI.getSummaryList().size() > 1 &&
321 !IsPrevailing(VI.getGUID(), GVS->second))
330 for (
const auto &VI : Summary.refs()) {
331 if (!shouldImportGlobal(VI)) {
333 dbgs() <<
"Ref ignored! Target already in destination module.\n");
345 auto LocalNotInModule =
348 RefSummary->modulePath() != Summary.modulePath();
351 for (
const auto &RefSummary : VI.getSummaryList()) {
352 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
358 if (!GVS || !
Index.canImportGlobalVar(GVS,
true) ||
359 LocalNotInModule(GVS))
361 auto ILI = ImportList[RefSummary->modulePath()].
insert(VI.getGUID());
366 NumImportedGlobalVarsThinLink++;
371 (*ExportLists)[RefSummary->modulePath()].insert(VI);
375 if (!
Index.isWriteOnly(GVS))
389 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
390 IsPrevailing(IsPrevailing), ImportList(ImportList),
391 ExportLists(ExportLists) {}
395 onImportingSummaryImpl(Summary, Worklist);
396 while (!Worklist.
empty())
397 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
429 static std::unique_ptr<ModuleImportsManager>
450 auto SetIter = Workloads.
find(ModName);
451 if (SetIter == Workloads.
end()) {
453 <<
" does not contain the root of any context.\n");
455 ModName, ImportList);
458 <<
" contains the root(s) of context(s).\n");
462 auto &ValueInfos = SetIter->second;
465 auto It = DefinedGVSummaries.
find(VI.getGUID());
466 if (It != DefinedGVSummaries.
end() &&
469 dbgs() <<
"[Workload] " << VI.name()
470 <<
" has the prevailing variant already in the module "
471 << ModName <<
". No need to import\n");
481 [&](
const auto &Candidate) {
483 <<
" from " << Candidate.second->modulePath()
484 <<
" ImportFailureReason: "
486 return Candidate.first ==
487 FunctionImporter::ImportFailureReason::None;
489 [](
const auto &Candidate) {
return Candidate.second; });
490 if (PotentialCandidates.empty()) {
492 <<
" because can't find eligible Callee. Guid is: "
493 << Function::getGUID(VI.name()) <<
"\n");
511 PotentialCandidates, [&](
const auto *Candidate) {
514 if (PrevailingCandidates.empty()) {
515 GVS = *PotentialCandidates.begin();
520 <<
"[Workload] Found multiple non-prevailing candidates for "
522 <<
". This is unexpected. Are module paths passed to the "
523 "compiler unique for the modules passed to the linker?");
532 GVS = *PrevailingCandidates.begin();
539 if (ExportingModule == ModName) {
541 <<
" because its defining module is the same as the "
545 LLVM_DEBUG(
dbgs() <<
"[Workload][Including]" << VI.name() <<
" from "
546 << ExportingModule <<
" : "
547 << Function::getGUID(VI.name()) <<
"\n");
548 ImportList[ExportingModule].
insert(VI.getGUID());
551 (*ExportLists)[ExportingModule].insert(VI);
569 if (!NameToValueInfo.
insert(std::make_pair(VI.name(), VI)).second)
574 dbgs() <<
"[Workload] Function name " << Name
575 <<
" present in the workload definition is ambiguous. Consider "
576 "compiling with -funique-internal-linkage-names.";
581 if (std::error_code EC = BufferOrErr.getError()) {
585 auto Buffer = std::move(BufferOrErr.get());
586 std::map<std::string, std::vector<std::string>> WorkloadDefs;
599 for (
const auto &Workload : WorkloadDefs) {
600 const auto &Root = Workload.first;
601 DbgReportIfAmbiguous(Root);
603 const auto &AllCallees = Workload.second;
604 auto RootIt = NameToValueInfo.
find(Root);
605 if (RootIt == NameToValueInfo.
end()) {
607 <<
" not found in this linkage unit.\n");
610 auto RootVI = RootIt->second;
611 if (RootVI.getSummaryList().size() != 1) {
613 <<
" should have exactly one summary, but has "
614 << RootVI.getSummaryList().size() <<
". Skipping.\n");
618 RootVI.getSummaryList().
front()->modulePath();
619 LLVM_DEBUG(
dbgs() <<
"[Workload] Root defining module for " << Root
620 <<
" is : " << RootDefiningModule <<
"\n");
621 auto &Set = Workloads[RootDefiningModule];
622 for (
const auto &Callee : AllCallees) {
624 DbgReportIfAmbiguous(Callee);
625 auto ElemIt = NameToValueInfo.
find(Callee);
626 if (ElemIt == NameToValueInfo.
end()) {
630 Set.insert(ElemIt->second);
633 dbgs() <<
"[Workload] Root: " << Root <<
" we have " << Set.size()
634 <<
" distinct callees.\n";
635 for (
const auto &VI : Set) {
636 dbgs() <<
"[Workload] Root: " << Root
637 <<
" Would include: " << VI.getGUID() <<
"\n";
650 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the regular imports manager.\n");
651 return std::unique_ptr<ModuleImportsManager>(
654 LLVM_DEBUG(
dbgs() <<
"[Workload] Using the contextual imports manager.\n");
662 case FunctionImporter::ImportFailureReason::None:
664 case FunctionImporter::ImportFailureReason::GlobalVar:
666 case FunctionImporter::ImportFailureReason::NotLive:
668 case FunctionImporter::ImportFailureReason::TooLarge:
670 case FunctionImporter::ImportFailureReason::InterposableLinkage:
671 return "InterposableLinkage";
672 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
673 return "LocalLinkageNotInModule";
674 case FunctionImporter::ImportFailureReason::NotEligible:
675 return "NotEligible";
676 case FunctionImporter::ImportFailureReason::NoInline:
687 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
695 static int ImportCount = 0;
696 for (
const auto &Edge : Summary.calls()) {
698 LLVM_DEBUG(
dbgs() <<
" edge -> " << VI <<
" Threshold:" << Threshold
707 if (DefinedGVSummaries.
count(VI.getGUID())) {
711 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
716 if (Hotness == CalleeInfo::HotnessType::Hot)
718 if (Hotness == CalleeInfo::HotnessType::Cold)
720 if (Hotness == CalleeInfo::HotnessType::Critical)
725 const auto NewThreshold =
726 Threshold * GetBonusMultiplier(Edge.second.getHotness());
728 auto IT = ImportThresholds.
insert(std::make_pair(
729 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
730 bool PreviouslyVisited = !
IT.second;
731 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
732 auto &CalleeSummary = std::get<1>(
IT.first->second);
733 auto &FailureInfo = std::get<2>(
IT.first->second);
736 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
737 bool IsCriticalCallsite =
738 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
742 assert(PreviouslyVisited);
747 if (NewThreshold <= ProcessedThreshold) {
749 dbgs() <<
"ignored! Target was already imported with Threshold "
750 << ProcessedThreshold <<
"\n");
754 ProcessedThreshold = NewThreshold;
755 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
759 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
761 dbgs() <<
"ignored! Target was already rejected with Threshold "
762 << ProcessedThreshold <<
"\n");
765 "Expected FailureInfo for previously rejected candidate");
766 FailureInfo->Attempts++;
773 Summary.modulePath(), Reason);
774 if (!CalleeSummary) {
778 if (PreviouslyVisited) {
779 ProcessedThreshold = NewThreshold;
782 "Expected FailureInfo for previously rejected candidate");
783 FailureInfo->Reason = Reason;
784 FailureInfo->Attempts++;
785 FailureInfo->MaxHotness =
786 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
790 "Expected no FailureInfo for newly rejected candidate");
791 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
792 VI, Edge.second.getHotness(), Reason, 1);
795 std::string Msg = std::string(
"Failed to import function ") +
796 VI.name().str() +
" due to " +
798 auto Error = make_error<StringError>(
801 "Error importing module: ");
805 <<
"ignored! No qualifying callee with summary found.\n");
811 CalleeSummary = CalleeSummary->getBaseObject();
812 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
815 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
816 "selectCallee() didn't honor the threshold");
818 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
819 auto ILI = ImportList[ExportModulePath].
insert(VI.getGUID());
822 bool PreviouslyImported = !ILI.second;
823 if (!PreviouslyImported) {
824 NumImportedFunctionsThinLink++;
826 NumImportedHotFunctionsThinLink++;
827 if (IsCriticalCallsite)
828 NumImportedCriticalFunctionsThinLink++;
835 (*ExportLists)[ExportModulePath].insert(VI);
838 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
847 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
852 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
868 for (
const auto &GVSummary : DefinedGVSummaries) {
872 auto VI =
Index.getValueInfo(GVSummary.first);
874 if (!
Index.isGlobalValueLive(GVSummary.second)) {
879 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
890 while (!Worklist.
empty()) {
892 auto *Summary = std::get<0>(GVInfo);
893 auto Threshold = std::get<1>(GVInfo);
895 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
904 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
905 for (
auto &
I : ImportThresholds) {
906 auto &ProcessedThreshold = std::get<0>(
I.second);
907 auto &CalleeSummary = std::get<1>(
I.second);
908 auto &FailureInfo = std::get<2>(
I.second);
913 if (!FailureInfo->VI.getSummaryList().empty())
914 FS = dyn_cast<FunctionSummary>(
915 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
916 dbgs() << FailureInfo->VI
918 <<
", Threshold = " << ProcessedThreshold
919 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
921 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
928 auto SL = VI.getSummaryList();
936 if (
const auto &VI =
Index.getValueInfo(
G))
960 for (
auto &ImportPerModule : ImportLists)
961 for (
auto &ExportPerModule : ImportPerModule.second)
962 FlattenedImports.
insert(ExportPerModule.second.begin(),
963 ExportPerModule.second.end());
971 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
973 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
974 Index.findSummaryInModule(VI, ModulePath));
975 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
981 for (
auto &ExportPerModule : ExportLists)
982 for (
auto &VI : ExportPerModule.second)
983 if (!FlattenedImports.
count(VI.getGUID()) &&
984 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first, VI))
1001 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
1002 auto &ImportList = ImportLists[DefinedGVSummaries.first];
1004 << DefinedGVSummaries.first <<
"'\n");
1005 MIS->computeImportForModule(DefinedGVSummaries.second,
1006 DefinedGVSummaries.first, ImportList);
1014 for (
auto &ELI : ExportLists) {
1016 const auto &DefinedGVSummaries =
1017 ModuleToDefinedGVSummaries.
lookup(ELI.first);
1018 for (
auto &EI : ELI.second) {
1025 auto DS = DefinedGVSummaries.
find(EI.getGUID());
1029 auto *S = DS->getSecond();
1030 S = S->getBaseObject();
1031 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
1036 if (!
Index.isWriteOnly(GVS))
1037 for (
const auto &VI : GVS->refs())
1040 auto *FS = cast<FunctionSummary>(S);
1041 for (
const auto &Edge : FS->calls())
1042 NewExports.
insert(Edge.first);
1043 for (
const auto &
Ref : FS->refs())
1051 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
1052 if (!DefinedGVSummaries.
count(EI->getGUID()))
1053 NewExports.
erase(EI++);
1057 ELI.second.insert(NewExports.
begin(), NewExports.
end());
1064 for (
auto &ModuleImports : ImportLists) {
1065 auto ModName = ModuleImports.first;
1066 auto &Exports = ExportLists[ModName];
1069 << Exports.
size() - NumGVS <<
" functions and " << NumGVS
1070 <<
" vars. Imports from " << ModuleImports.second.size()
1072 for (
auto &Src : ModuleImports.second) {
1073 auto SrcModName = Src.first;
1076 <<
" functions imported from " << SrcModName <<
"\n");
1078 <<
" global vars imported from " << SrcModName <<
"\n");
1088 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
1089 << ImportList.
size() <<
" modules.\n");
1090 for (
auto &Src : ImportList) {
1091 auto SrcModName = Src.first;
1094 <<
" functions imported from " << SrcModName <<
"\n");
1095 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
1096 << SrcModName <<
"\n");
1118 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
1121 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
1123 MIS->computeImportForModule(FunctionSummaryMap, ModulePath, ImportList);
1138 for (
const auto &GlobalList :
Index) {
1140 if (GlobalList.second.SummaryList.empty())
1143 auto GUID = GlobalList.first;
1144 assert(GlobalList.second.SummaryList.size() == 1 &&
1145 "Expected individual combined index to have one summary per GUID");
1146 auto &Summary = GlobalList.second.SummaryList[0];
1149 if (Summary->modulePath() == ModulePath)
1152 ImportList[Summary->modulePath()].
insert(GUID);
1165 for (
auto &EI : FS->mutableCalls()) {
1166 if (!EI.first.getSummaryList().empty())
1168 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
1172 auto VI =
Index.getValueInfo(GUID);
1174 VI.getSummaryList(),
1175 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
1185 return SummaryPtr->getSummaryKind() ==
1186 GlobalValueSummary::GlobalVarKind;
1194 for (
const auto &Entry :
Index) {
1195 for (
const auto &S : Entry.second.SummaryList) {
1196 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1209 GUIDPreservedSymbols.
empty()) {
1214 unsigned LiveSymbols = 0;
1216 Worklist.
reserve(GUIDPreservedSymbols.
size() * 2);
1217 for (
auto GUID : GUIDPreservedSymbols) {
1221 for (
const auto &S : VI.getSummaryList())
1226 for (
const auto &Entry :
Index) {
1227 auto VI =
Index.getValueInfo(Entry);
1228 for (
const auto &S : Entry.second.SummaryList) {
1229 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
1241 auto visit = [&](
ValueInfo VI,
bool IsAliasee) {
1252 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
1262 if (isPrevailing(VI.getGUID()) == PrevailingType::No) {
1263 bool KeepAliveLinkage =
false;
1264 bool Interposable =
false;
1265 for (
const auto &S : VI.getSummaryList()) {
1269 KeepAliveLinkage =
true;
1271 Interposable =
true;
1275 if (!KeepAliveLinkage)
1280 "Interposable and available_externally/linkonce_odr/weak_odr "
1285 for (
const auto &S : VI.getSummaryList())
1291 while (!Worklist.
empty()) {
1293 for (
const auto &Summary : VI.getSummaryList()) {
1294 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1298 visit(AS->getAliaseeVI(),
true);
1301 for (
auto Ref : Summary->refs())
1303 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1304 for (
auto Call : FS->calls())
1305 visit(Call.first,
false);
1308 Index.setWithGlobalValueDeadStripping();
1310 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1311 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1312 <<
" symbols Dead \n");
1313 NumDeadSymbols += DeadSymbols;
1314 NumLiveSymbols += LiveSymbols;
1322 bool ImportEnabled) {
1326 Index.propagateAttributes(GUIDPreservedSymbols);
1335 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1337 ModuleToSummariesForIndex[std::string(ModulePath)] =
1338 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1340 for (
const auto &ILI : ImportList) {
1341 auto &SummariesForIndex = ModuleToSummariesForIndex[std::string(ILI.first)];
1342 const auto &DefinedGVSummaries =
1343 ModuleToDefinedGVSummaries.
lookup(ILI.first);
1344 for (
const auto &GI : ILI.second) {
1345 const auto &DS = DefinedGVSummaries.
find(GI);
1346 assert(DS != DefinedGVSummaries.
end() &&
1347 "Expected a defined summary for imported global value");
1348 SummariesForIndex[GI] = DS->second;
1356 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1361 for (
const auto &ILI : ModuleToSummariesForIndex)
1365 if (ILI.first != ModulePath)
1366 ImportsOS << ILI.first <<
"\n";
1367 return std::error_code();
1373 if (
Function *
F = dyn_cast<Function>(&GV)) {
1376 F->setComdat(
nullptr);
1378 V->setInitializer(
nullptr);
1381 V->setComdat(
nullptr);
1409 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1411 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1412 if (GS == DefinedGlobals.
end())
1417 if (
Function *
F = dyn_cast<Function>(&GV)) {
1419 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1420 F->setDoesNotAccessMemory();
1422 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1423 F->setOnlyReadsMemory();
1425 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1426 F->setDoesNotRecurse();
1428 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1429 F->setDoesNotThrow();
1433 auto NewLinkage = GS->second->linkage();
1472 GS->second->canAutoHide()) {
1478 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1485 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1486 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1487 if (GO->getComdat()->getName() == GO->getName())
1488 NonPrevailingComdats.
insert(GO->getComdat());
1489 GO->setComdat(
nullptr);
1494 for (
auto &GV : TheModule)
1496 for (
auto &GV : TheModule.
globals())
1497 FinalizeInModule(GV);
1498 for (
auto &GV : TheModule.
aliases())
1499 FinalizeInModule(GV);
1504 if (NonPrevailingComdats.
empty())
1507 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1508 GO.setComdat(
nullptr);
1519 for (
auto &GA : TheModule.
aliases()) {
1520 if (GA.hasAvailableExternallyLinkage())
1523 assert(Obj &&
"aliasee without an base object is unimplemented");
1537 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1541 if (isa<GlobalIFunc>(&GV) ||
1542 (isa<GlobalAlias>(&GV) &&
1543 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1547 auto GS = DefinedGlobals.
find(GV.getGUID());
1548 if (GS == DefinedGlobals.
end()) {
1560 if (GS == DefinedGlobals.
end()) {
1597 for (
auto &GV : M.globals())
1600 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1612 unsigned ImportedCount = 0, ImportedGVCount = 0;
1616 std::set<StringRef> ModuleNameOrderedList;
1617 for (
const auto &FunctionsToImportPerModule : ImportList) {
1618 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first);
1620 for (
const auto &
Name : ModuleNameOrderedList) {
1622 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1623 assert(FunctionsToImportPerModule != ImportList.
end());
1625 if (!SrcModuleOrErr)
1627 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1629 "Context mismatch");
1633 if (
Error Err = SrcModule->materializeMetadata())
1634 return std::move(Err);
1636 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1642 auto GUID =
F.getGUID();
1643 auto Import = ImportGUIDs.count(GUID);
1645 << GUID <<
" " <<
F.getName() <<
" from "
1646 << SrcModule->getSourceFileName() <<
"\n");
1648 if (
Error Err =
F.materialize())
1649 return std::move(Err);
1656 "thinlto_src_module",
1658 {MDString::get(DestModule.getContext(),
1659 SrcModule->getModuleIdentifier())}));
1663 {MDString::get(DestModule.getContext(),
1664 SrcModule->getSourceFileName())}));
1672 auto GUID = GV.getGUID();
1673 auto Import = ImportGUIDs.count(GUID);
1675 << GUID <<
" " << GV.getName() <<
" from "
1676 << SrcModule->getSourceFileName() <<
"\n");
1678 if (
Error Err = GV.materialize())
1679 return std::move(Err);
1680 ImportedGVCount += GlobalsToImport.
insert(&GV);
1684 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1686 auto GUID = GA.getGUID();
1687 auto Import = ImportGUIDs.count(GUID);
1689 << GUID <<
" " << GA.getName() <<
" from "
1690 << SrcModule->getSourceFileName() <<
"\n");
1692 if (
Error Err = GA.materialize())
1693 return std::move(Err);
1697 return std::move(Err);
1701 << SrcModule->getSourceFileName() <<
"\n");
1706 "thinlto_src_module",
1708 {MDString::get(DestModule.getContext(),
1709 SrcModule->getModuleIdentifier())}));
1713 {MDString::get(DestModule.getContext(),
1714 SrcModule->getSourceFileName())}));
1716 GlobalsToImport.
insert(Fn);
1728 SrcModule->setPartialSampleProfileRatio(
Index);
1736 for (
const auto *GV : GlobalsToImport)
1738 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1741 if (
Error Err = Mover.
move(std::move(SrcModule),
1745 Twine(
"Function Import: link error: ") +
1748 ImportedCount += GlobalsToImport.
size();
1749 NumImportedModules++;
1754 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1755 NumImportedGlobalVars += ImportedGVCount;
1757 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1758 <<
" functions for Module "
1761 <<
" global variables for Module "
1763 return ImportedCount;
1773 if (!IndexPtrOrErr) {
1778 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1787 *
Index, ImportList);
1790 isPrevailing, *
Index, ImportList);
1797 for (
auto &S :
I.second.SummaryList) {
1807 errs() <<
"Error renaming module\n";
1812 auto ModuleLoader = [&M](
StringRef Identifier) {
1813 return loadFile(std::string(Identifier), M.getContext());
1822 "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 const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold.
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< 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 unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont)
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)
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.
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)
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.
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
void setVisibility(VisibilityTypes V)
static bool isInterposableLinkage(LinkageTypes Linkage)
Whether the definition of this global may be replaced by something non-equivalent at link time.
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...
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 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.
@ Import
Import information from summary.
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.