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'"));
134 cl::desc(
"The summary file to use for function importing."));
140 cl::desc(
"Import all external functions in index."));
143static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
149 std::unique_ptr<Module> Result =
153 Err.print(
"function-import",
errs());
166 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
170 [&
Index, CalleeSummaryList,
171 CallerModulePath](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr)
174 auto *GVSummary = SummaryPtr.get();
175 if (!
Index.isGlobalValueLive(GVSummary))
176 return {FunctionImporter::ImportFailureReason::NotLive, GVSummary};
179 return {FunctionImporter::ImportFailureReason::InterposableLinkage,
182 auto *Summary = cast<FunctionSummary>(GVSummary->getBaseObject());
195 CalleeSummaryList.size() > 1 &&
196 Summary->modulePath() != CallerModulePath)
198 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule,
203 if (Summary->notEligibleToImport())
204 return {FunctionImporter::ImportFailureReason::NotEligible,
207 return {FunctionImporter::ImportFailureReason::None, GVSummary};
224 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
225 unsigned Threshold,
StringRef CallerModulePath,
227 auto QualifiedCandidates =
229 for (
auto QualifiedValue : QualifiedCandidates) {
230 Reason = QualifiedValue.first;
231 if (Reason != FunctionImporter::ImportFailureReason::None)
234 cast<FunctionSummary>(QualifiedValue.second->getBaseObject());
236 if ((Summary->instCount() > Threshold) && !Summary->fflags().AlwaysInline &&
238 Reason = FunctionImporter::ImportFailureReason::TooLarge;
244 Reason = FunctionImporter::ImportFailureReason::NoInline;
270 const auto &GVS = DefinedGVSummaries.
find(
VI.getGUID());
271 if (GVS == DefinedGVSummaries.
end())
283 if (
VI.getSummaryList().size() > 1 &&
285 !IsPrevailing(
VI.getGUID(), GVS->second))
294 for (
const auto &
VI : Summary.refs()) {
295 if (!shouldImportGlobal(
VI)) {
297 dbgs() <<
"Ref ignored! Target already in destination module.\n");
309 auto LocalNotInModule =
312 RefSummary->modulePath() != Summary.modulePath();
315 for (
const auto &RefSummary :
VI.getSummaryList()) {
316 const auto *GVS = dyn_cast<GlobalVarSummary>(RefSummary.get());
322 if (!GVS || !
Index.canImportGlobalVar(GVS,
true) ||
323 LocalNotInModule(GVS))
325 auto ILI = ImportList[RefSummary->modulePath()].
insert(
VI.getGUID());
330 NumImportedGlobalVarsThinLink++;
335 (*ExportLists)[RefSummary->modulePath()].insert(
VI);
339 if (!
Index.isWriteOnly(GVS))
353 :
Index(
Index), DefinedGVSummaries(DefinedGVSummaries),
354 IsPrevailing(IsPrevailing), ImportList(ImportList),
355 ExportLists(ExportLists) {}
359 onImportingSummaryImpl(Summary, Worklist);
360 while (!Worklist.
empty())
361 onImportingSummaryImpl(*Worklist.
pop_back_val(), Worklist);
368 case FunctionImporter::ImportFailureReason::None:
370 case FunctionImporter::ImportFailureReason::GlobalVar:
372 case FunctionImporter::ImportFailureReason::NotLive:
374 case FunctionImporter::ImportFailureReason::TooLarge:
376 case FunctionImporter::ImportFailureReason::InterposableLinkage:
377 return "InterposableLinkage";
378 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
379 return "LocalLinkageNotInModule";
380 case FunctionImporter::ImportFailureReason::NotEligible:
381 return "NotEligible";
382 case FunctionImporter::ImportFailureReason::NoInline:
393 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
401 static int ImportCount = 0;
402 for (
const auto &Edge : Summary.calls()) {
413 if (DefinedGVSummaries.
count(
VI.getGUID())) {
417 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
422 if (Hotness == CalleeInfo::HotnessType::Hot)
424 if (Hotness == CalleeInfo::HotnessType::Cold)
426 if (Hotness == CalleeInfo::HotnessType::Critical)
431 const auto NewThreshold =
432 Threshold * GetBonusMultiplier(Edge.second.getHotness());
434 auto IT = ImportThresholds.
insert(std::make_pair(
435 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
436 bool PreviouslyVisited = !
IT.second;
437 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
438 auto &CalleeSummary = std::get<1>(
IT.first->second);
439 auto &FailureInfo = std::get<2>(
IT.first->second);
442 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
443 bool IsCriticalCallsite =
444 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
448 assert(PreviouslyVisited);
453 if (NewThreshold <= ProcessedThreshold) {
455 dbgs() <<
"ignored! Target was already imported with Threshold "
456 << ProcessedThreshold <<
"\n");
460 ProcessedThreshold = NewThreshold;
461 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
465 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
467 dbgs() <<
"ignored! Target was already rejected with Threshold "
468 << ProcessedThreshold <<
"\n");
471 "Expected FailureInfo for previously rejected candidate");
472 FailureInfo->Attempts++;
479 Summary.modulePath(), Reason);
480 if (!CalleeSummary) {
484 if (PreviouslyVisited) {
485 ProcessedThreshold = NewThreshold;
488 "Expected FailureInfo for previously rejected candidate");
489 FailureInfo->Reason = Reason;
490 FailureInfo->Attempts++;
491 FailureInfo->MaxHotness =
492 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
496 "Expected no FailureInfo for newly rejected candidate");
497 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
498 VI, Edge.second.getHotness(), Reason, 1);
501 std::string Msg = std::string(
"Failed to import function ") +
502 VI.name().str() +
" due to " +
504 auto Error = make_error<StringError>(
507 "Error importing module: ");
511 <<
"ignored! No qualifying callee with summary found.\n");
517 CalleeSummary = CalleeSummary->getBaseObject();
518 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
521 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
522 "selectCallee() didn't honor the threshold");
524 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
525 auto ILI = ImportList[ExportModulePath].
insert(
VI.getGUID());
528 bool PreviouslyImported = !ILI.second;
529 if (!PreviouslyImported) {
530 NumImportedFunctionsThinLink++;
532 NumImportedHotFunctionsThinLink++;
533 if (IsCriticalCallsite)
534 NumImportedCriticalFunctionsThinLink++;
541 (*ExportLists)[ExportModulePath].insert(
VI);
544 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
553 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
558 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
581 for (
const auto &GVSummary : DefinedGVSummaries) {
585 auto VI =
Index.getValueInfo(GVSummary.first);
587 if (!
Index.isGlobalValueLive(GVSummary.second)) {
592 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
598 DefinedGVSummaries, isPrevailing, Worklist, GVI,
599 ImportList, ExportLists, ImportThresholds);
603 while (!Worklist.
empty()) {
605 auto *Summary = std::get<0>(GVInfo);
606 auto Threshold = std::get<1>(GVInfo);
608 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
610 isPrevailing, Worklist, GVI, ImportList,
611 ExportLists, ImportThresholds);
617 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
618 for (
auto &
I : ImportThresholds) {
619 auto &ProcessedThreshold = std::get<0>(
I.second);
620 auto &CalleeSummary = std::get<1>(
I.second);
621 auto &FailureInfo = std::get<2>(
I.second);
626 if (!FailureInfo->VI.getSummaryList().empty())
627 FS = dyn_cast<FunctionSummary>(
628 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
629 dbgs() << FailureInfo->VI
631 <<
", Threshold = " << ProcessedThreshold
632 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
634 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
641 auto SL =
VI.getSummaryList();
649 if (
const auto &
VI =
Index.getValueInfo(
G))
673 for (
auto &ImportPerModule : ImportLists)
674 for (
auto &ExportPerModule : ImportPerModule.second)
675 FlattenedImports.
insert(ExportPerModule.second.begin(),
676 ExportPerModule.second.end());
684 auto IsReadOrWriteOnlyVarNeedingImporting = [&](
StringRef ModulePath,
686 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
687 Index.findSummaryInModule(
VI, ModulePath));
688 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS)) &&
694 for (
auto &ExportPerModule : ExportLists)
695 for (
auto &
VI : ExportPerModule.second)
696 if (!FlattenedImports.
count(
VI.getGUID()) &&
697 IsReadOrWriteOnlyVarNeedingImporting(ExportPerModule.first(),
VI))
713 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
714 auto &ImportList = ImportLists[DefinedGVSummaries.first()];
716 << DefinedGVSummaries.first() <<
"'\n");
718 DefinedGVSummaries.first(), ImportList,
727 for (
auto &ELI : ExportLists) {
729 const auto &DefinedGVSummaries =
730 ModuleToDefinedGVSummaries.
lookup(ELI.first());
731 for (
auto &EI : ELI.second) {
738 auto DS = DefinedGVSummaries.
find(EI.getGUID());
742 auto *S = DS->getSecond();
743 S = S->getBaseObject();
744 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
749 if (!
Index.isWriteOnly(GVS))
750 for (
const auto &
VI : GVS->refs())
753 auto *FS = cast<FunctionSummary>(S);
754 for (
const auto &Edge : FS->calls())
755 NewExports.
insert(Edge.first);
756 for (
const auto &
Ref : FS->refs())
764 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
765 if (!DefinedGVSummaries.
count(EI->getGUID()))
766 NewExports.
erase(EI++);
770 ELI.second.insert(NewExports.
begin(), NewExports.
end());
777 for (
auto &ModuleImports : ImportLists) {
778 auto ModName = ModuleImports.first();
779 auto &
Exports = ExportLists[ModName];
782 <<
Exports.size() - NumGVS <<
" functions and " << NumGVS
783 <<
" vars. Imports from " << ModuleImports.second.size()
785 for (
auto &Src : ModuleImports.second) {
786 auto SrcModName = Src.first();
789 <<
" functions imported from " << SrcModName <<
"\n");
791 <<
" global vars imported from " << SrcModName <<
"\n");
801 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
802 << ImportList.
size() <<
" modules.\n");
803 for (
auto &Src : ImportList) {
804 auto SrcModName = Src.first();
807 <<
" functions imported from " << SrcModName <<
"\n");
808 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
809 << SrcModName <<
"\n");
824 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
827 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
841 for (
const auto &GlobalList :
Index) {
843 if (GlobalList.second.SummaryList.empty())
846 auto GUID = GlobalList.first;
847 assert(GlobalList.second.SummaryList.size() == 1 &&
848 "Expected individual combined index to have one summary per GUID");
849 auto &Summary = GlobalList.second.SummaryList[0];
852 if (Summary->modulePath() == ModulePath)
855 ImportList[Summary->modulePath()].
insert(GUID);
868 for (
auto &EI : FS->mutableCalls()) {
869 if (!EI.first.getSummaryList().empty())
871 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
875 auto VI =
Index.getValueInfo(GUID);
878 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
888 return SummaryPtr->getSummaryKind() ==
889 GlobalValueSummary::GlobalVarKind;
897 for (
const auto &Entry :
Index) {
898 for (
const auto &S : Entry.second.SummaryList) {
899 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
912 GUIDPreservedSymbols.
empty()) {
917 unsigned LiveSymbols = 0;
920 for (
auto GUID : GUIDPreservedSymbols) {
924 for (
const auto &S :
VI.getSummaryList())
929 for (
const auto &Entry :
Index) {
930 auto VI =
Index.getValueInfo(Entry);
931 for (
const auto &S : Entry.second.SummaryList) {
932 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
955 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
965 if (isPrevailing(
VI.getGUID()) == PrevailingType::No) {
966 bool KeepAliveLinkage =
false;
967 bool Interposable =
false;
968 for (
const auto &S :
VI.getSummaryList()) {
972 KeepAliveLinkage =
true;
978 if (!KeepAliveLinkage)
983 "Interposable and available_externally/linkonce_odr/weak_odr "
988 for (
const auto &S :
VI.getSummaryList())
994 while (!Worklist.
empty()) {
996 for (
const auto &Summary :
VI.getSummaryList()) {
997 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
1001 visit(AS->getAliaseeVI(),
true);
1004 for (
auto Ref : Summary->refs())
1006 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
1007 for (
auto Call : FS->calls())
1008 visit(Call.first,
false);
1011 Index.setWithGlobalValueDeadStripping();
1013 unsigned DeadSymbols =
Index.size() - LiveSymbols;
1014 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
1015 <<
" symbols Dead \n");
1016 NumDeadSymbols += DeadSymbols;
1017 NumLiveSymbols += LiveSymbols;
1025 bool ImportEnabled) {
1029 Index.propagateAttributes(GUIDPreservedSymbols);
1038 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1040 ModuleToSummariesForIndex[std::string(ModulePath)] =
1041 ModuleToDefinedGVSummaries.
lookup(ModulePath);
1043 for (
const auto &ILI : ImportList) {
1044 auto &SummariesForIndex =
1045 ModuleToSummariesForIndex[std::string(ILI.first())];
1046 const auto &DefinedGVSummaries =
1047 ModuleToDefinedGVSummaries.
lookup(ILI.first());
1048 for (
const auto &GI : ILI.second) {
1049 const auto &DS = DefinedGVSummaries.
find(GI);
1050 assert(DS != DefinedGVSummaries.
end() &&
1051 "Expected a defined summary for imported global value");
1052 SummariesForIndex[GI] = DS->second;
1060 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1065 for (
const auto &ILI : ModuleToSummariesForIndex)
1069 if (ILI.first != ModulePath)
1070 ImportsOS << ILI.first <<
"\n";
1071 return std::error_code();
1077 if (
Function *
F = dyn_cast<Function>(&GV)) {
1080 F->setComdat(
nullptr);
1082 V->setInitializer(
nullptr);
1085 V->setComdat(
nullptr);
1113 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1115 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1116 if (GS == DefinedGlobals.
end())
1121 if (
Function *
F = dyn_cast<Function>(&GV)) {
1123 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1124 F->setDoesNotAccessMemory();
1126 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1127 F->setOnlyReadsMemory();
1129 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1130 F->setDoesNotRecurse();
1132 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1133 F->setDoesNotThrow();
1137 auto NewLinkage = GS->second->linkage();
1176 GS->second->canAutoHide()) {
1182 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1189 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1190 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1191 if (GO->getComdat()->getName() == GO->getName())
1192 NonPrevailingComdats.
insert(GO->getComdat());
1193 GO->setComdat(
nullptr);
1198 for (
auto &GV : TheModule)
1200 for (
auto &GV : TheModule.
globals())
1201 FinalizeInModule(GV);
1202 for (
auto &GV : TheModule.
aliases())
1203 FinalizeInModule(GV);
1208 if (NonPrevailingComdats.
empty())
1211 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1212 GO.setComdat(
nullptr);
1223 for (
auto &GA : TheModule.
aliases()) {
1224 if (GA.hasAvailableExternallyLinkage())
1227 assert(Obj &&
"aliasee without an base object is unimplemented");
1241 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1245 if (isa<GlobalIFunc>(&GV) ||
1246 (isa<GlobalAlias>(&GV) &&
1247 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1251 auto GS = DefinedGlobals.
find(GV.getGUID());
1252 if (GS == DefinedGlobals.
end()) {
1264 if (GS == DefinedGlobals.
end()) {
1301 for (
auto &GV : M.globals())
1304 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1316 unsigned ImportedCount = 0, ImportedGVCount = 0;
1320 std::set<StringRef> ModuleNameOrderedList;
1321 for (
const auto &FunctionsToImportPerModule : ImportList) {
1322 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
1324 for (
const auto &
Name : ModuleNameOrderedList) {
1326 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1327 assert(FunctionsToImportPerModule != ImportList.
end());
1329 if (!SrcModuleOrErr)
1331 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1333 "Context mismatch");
1337 if (
Error Err = SrcModule->materializeMetadata())
1338 return std::move(Err);
1340 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1346 auto GUID =
F.getGUID();
1347 auto Import = ImportGUIDs.count(GUID);
1349 << GUID <<
" " <<
F.getName() <<
" from "
1350 << SrcModule->getSourceFileName() <<
"\n");
1352 if (
Error Err =
F.materialize())
1353 return std::move(Err);
1357 "thinlto_src_module",
1359 {MDString::get(DestModule.getContext(),
1360 SrcModule->getSourceFileName())}));
1368 auto GUID = GV.getGUID();
1369 auto Import = ImportGUIDs.count(GUID);
1371 << GUID <<
" " << GV.getName() <<
" from "
1372 << SrcModule->getSourceFileName() <<
"\n");
1374 if (
Error Err = GV.materialize())
1375 return std::move(Err);
1376 ImportedGVCount += GlobalsToImport.
insert(&GV);
1380 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1382 auto GUID = GA.getGUID();
1383 auto Import = ImportGUIDs.count(GUID);
1385 << GUID <<
" " << GA.getName() <<
" from "
1386 << SrcModule->getSourceFileName() <<
"\n");
1388 if (
Error Err = GA.materialize())
1389 return std::move(Err);
1393 return std::move(Err);
1397 << SrcModule->getSourceFileName() <<
"\n");
1401 "thinlto_src_module",
1403 {MDString::get(DestModule.getContext(),
1404 SrcModule->getSourceFileName())}));
1406 GlobalsToImport.
insert(Fn);
1418 SrcModule->setPartialSampleProfileRatio(
Index);
1426 for (
const auto *GV : GlobalsToImport)
1428 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1431 if (
Error Err = Mover.
move(std::move(SrcModule),
1435 Twine(
"Function Import: link error: ") +
1438 ImportedCount += GlobalsToImport.
size();
1439 NumImportedModules++;
1444 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1445 NumImportedGlobalVars += ImportedGVCount;
1447 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1448 <<
" functions for Module "
1451 <<
" global variables for Module "
1453 return ImportedCount;
1463 if (!IndexPtrOrErr) {
1468 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1480 *
Index, ImportList);
1487 for (
auto &S :
I.second.SummaryList) {
1497 errs() <<
"Error renaming module\n";
1502 auto ModuleLoader = [&M](
StringRef Identifier) {
1503 return loadFile(std::string(Identifier), M.getContext());
1512 "Error importing module: ");
This file defines the StringMap class.
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 bool checkVariableImport(const ModuleSummaryIndex &Index, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
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< 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 cl::opt< bool > EnableImportMetadata("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module'"))
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 bool doImportingForModule(Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
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"))
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, StringMap< FunctionImporter::ExportSetTy > *ExportLists, FunctionImporter::ImportThresholdsTy &ImportThresholds)
Compute the list of functions to import for a given caller.
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< 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 ComputeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, StringRef ModName, FunctionImporter::ImportMapTy &ImportList, StringMap< FunctionImporter::ExportSetTy > *ExportLists=nullptr)
Given the list of globals defined in a module, compute the list of imports as well as the list of "ex...
static unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont)
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, StringMap< 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),...
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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.
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)
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.
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.
ArrayRef< value_type > getArrayRef() const
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)
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
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.
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.
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.
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)
void ComputeCrossModuleImportForModule(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.
void gatherImportedSummariesForModule(StringRef ModulePath, const StringMap< 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.
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.
bool convertToDeclaration(GlobalValue &GV)
Converts value GV to declaration, or replaces with a declaration if it is an alias.
void ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
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 ComputeCrossModuleImportForModuleFromIndex(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
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.
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.
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.