53#include <system_error>
59#define DEBUG_TYPE "function-import"
62 "Number of functions thin link decided to import");
64 "Number of hot functions thin link decided to import");
66 "Number of critical functions thin link decided to import");
68 "Number of global variables thin link decided to import");
69STATISTIC(NumImportedFunctions,
"Number of functions imported in backend");
71 "Number of global variables imported in backend");
72STATISTIC(NumImportedModules,
"Number of modules imported from");
73STATISTIC(NumDeadSymbols,
"Number of dead stripped symbols in index");
74STATISTIC(NumLiveSymbols,
"Number of live symbols in index");
79 cl::desc(
"Only import functions with less than N instructions"));
83 cl::desc(
"Only import first N functions if N>=0 (default -1)"));
87 cl::desc(
"Import functions with noinline attribute"));
92 cl::desc(
"As we import functions, multiply the "
93 "`import-instr-limit` threshold by this factor "
94 "before processing newly imported functions"));
99 cl::desc(
"As we import functions called from hot callsite, multiply the "
100 "`import-instr-limit` threshold by this factor "
101 "before processing newly imported functions"));
105 cl::desc(
"Multiply the `import-instr-limit` threshold for hot callsites"));
111 "Multiply the `import-instr-limit` threshold for critical callsites"));
116 cl::desc(
"Multiply the `import-instr-limit` threshold for cold callsites"));
119 cl::desc(
"Print imported functions"));
123 cl::desc(
"Print information for functions rejected for importing"));
130 cl::desc(
"Enable import metadata like 'thinlto_src_module'"));
136 cl::desc(
"The summary file to use for function importing."));
142 cl::desc(
"Import all external functions in index."));
145static std::unique_ptr<Module>
loadFile(
const std::string &FileName,
151 std::unique_ptr<Module> Result =
155 Err.print(
"function-import",
errs());
174 ArrayRef<std::unique_ptr<GlobalValueSummary>> CalleeSummaryList,
175 unsigned Threshold,
StringRef CallerModulePath,
178 Reason = FunctionImporter::ImportFailureReason::None;
181 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
182 auto *GVSummary = SummaryPtr.get();
183 if (!
Index.isGlobalValueLive(GVSummary)) {
184 Reason = FunctionImporter::ImportFailureReason::NotLive;
189 Reason = FunctionImporter::ImportFailureReason::InterposableLinkage;
194 auto *Summary = cast<FunctionSummary>(GVSummary->getBaseObject());
207 CalleeSummaryList.size() > 1 &&
208 Summary->modulePath() != CallerModulePath) {
210 FunctionImporter::ImportFailureReason::LocalLinkageNotInModule;
214 if ((Summary->instCount() > Threshold) &&
216 Reason = FunctionImporter::ImportFailureReason::TooLarge;
222 if (Summary->notEligibleToImport()) {
223 Reason = FunctionImporter::ImportFailureReason::NotEligible;
229 Reason = FunctionImporter::ImportFailureReason::NoInline;
235 if (It == CalleeSummaryList.end())
238 return cast<GlobalValueSummary>(It->get());
250 const auto &GVS = DefinedGVSummaries.
find(
VI.getGUID());
251 if (GVS == DefinedGVSummaries.
end())
264 if (
VI.getSummaryList().size() > 1 &&
277 for (
const auto &
VI : Summary.refs()) {
280 dbgs() <<
"Ref ignored! Target already in destination module.\n");
294 RefSummary->modulePath() != Summary.modulePath();
297 for (
const auto &RefSummary :
VI.getSummaryList())
298 if (isa<GlobalVarSummary>(RefSummary.get()) &&
299 Index.canImportGlobalVar(RefSummary.get(),
true) &&
300 !LocalNotInModule(RefSummary.get())) {
301 auto ILI = ImportList[RefSummary->modulePath()].
insert(
VI.getGUID());
306 NumImportedGlobalVarsThinLink++;
311 (*ExportLists)[RefSummary->modulePath()].insert(
VI);
315 if (!
Index.isWriteOnly(cast<GlobalVarSummary>(RefSummary.get())))
325 case FunctionImporter::ImportFailureReason::None:
327 case FunctionImporter::ImportFailureReason::GlobalVar:
329 case FunctionImporter::ImportFailureReason::NotLive:
331 case FunctionImporter::ImportFailureReason::TooLarge:
333 case FunctionImporter::ImportFailureReason::InterposableLinkage:
334 return "InterposableLinkage";
335 case FunctionImporter::ImportFailureReason::LocalLinkageNotInModule:
336 return "LocalLinkageNotInModule";
337 case FunctionImporter::ImportFailureReason::NotEligible:
338 return "NotEligible";
339 case FunctionImporter::ImportFailureReason::NoInline:
350 const unsigned Threshold,
const GVSummaryMapTy &DefinedGVSummaries,
356 Worklist, ImportList, ExportLists);
357 static int ImportCount = 0;
358 for (
const auto &Edge : Summary.calls()) {
369 if (DefinedGVSummaries.
count(
VI.getGUID())) {
373 LLVM_DEBUG(
dbgs() <<
"ignored! Target already in destination module.\n");
378 if (Hotness == CalleeInfo::HotnessType::Hot)
380 if (Hotness == CalleeInfo::HotnessType::Cold)
382 if (Hotness == CalleeInfo::HotnessType::Critical)
387 const auto NewThreshold =
388 Threshold * GetBonusMultiplier(Edge.second.getHotness());
390 auto IT = ImportThresholds.
insert(std::make_pair(
391 VI.getGUID(), std::make_tuple(NewThreshold,
nullptr,
nullptr)));
392 bool PreviouslyVisited = !
IT.second;
393 auto &ProcessedThreshold = std::get<0>(
IT.first->second);
394 auto &CalleeSummary = std::get<1>(
IT.first->second);
395 auto &FailureInfo = std::get<2>(
IT.first->second);
398 Edge.second.getHotness() == CalleeInfo::HotnessType::Hot;
399 bool IsCriticalCallsite =
400 Edge.second.getHotness() == CalleeInfo::HotnessType::Critical;
404 assert(PreviouslyVisited);
409 if (NewThreshold <= ProcessedThreshold) {
411 dbgs() <<
"ignored! Target was already imported with Threshold "
412 << ProcessedThreshold <<
"\n");
416 ProcessedThreshold = NewThreshold;
417 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
421 if (PreviouslyVisited && NewThreshold <= ProcessedThreshold) {
423 dbgs() <<
"ignored! Target was already rejected with Threshold "
424 << ProcessedThreshold <<
"\n");
427 "Expected FailureInfo for previously rejected candidate");
428 FailureInfo->Attempts++;
435 Summary.modulePath(), Reason,
VI.getGUID());
436 if (!CalleeSummary) {
440 if (PreviouslyVisited) {
441 ProcessedThreshold = NewThreshold;
444 "Expected FailureInfo for previously rejected candidate");
445 FailureInfo->Reason = Reason;
446 FailureInfo->Attempts++;
447 FailureInfo->MaxHotness =
448 std::max(FailureInfo->MaxHotness, Edge.second.getHotness());
452 "Expected no FailureInfo for newly rejected candidate");
453 FailureInfo = std::make_unique<FunctionImporter::ImportFailureInfo>(
454 VI, Edge.second.getHotness(), Reason, 1);
457 std::string Msg = std::string(
"Failed to import function ") +
458 VI.name().str() +
" due to " +
460 auto Error = make_error<StringError>(
463 "Error importing module: ");
467 <<
"ignored! No qualifying callee with summary found.\n");
473 CalleeSummary = CalleeSummary->getBaseObject();
474 ResolvedCalleeSummary = cast<FunctionSummary>(CalleeSummary);
477 (ResolvedCalleeSummary->
instCount() <= NewThreshold)) &&
478 "selectCallee() didn't honor the threshold");
480 auto ExportModulePath = ResolvedCalleeSummary->
modulePath();
481 auto ILI = ImportList[ExportModulePath].
insert(
VI.getGUID());
484 bool PreviouslyImported = !ILI.second;
485 if (!PreviouslyImported) {
486 NumImportedFunctionsThinLink++;
488 NumImportedHotFunctionsThinLink++;
489 if (IsCriticalCallsite)
490 NumImportedCriticalFunctionsThinLink++;
497 (*ExportLists)[ExportModulePath].insert(
VI);
500 auto GetAdjustedThreshold = [](
unsigned Threshold,
bool IsHotCallsite) {
509 const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite);
514 Worklist.
emplace_back(ResolvedCalleeSummary, AdjThreshold);
532 for (
const auto &GVSummary : DefinedGVSummaries) {
536 auto VI =
Index.getValueInfo(GVSummary.first);
538 if (!
Index.isGlobalValueLive(GVSummary.second)) {
543 dyn_cast<FunctionSummary>(GVSummary.second->getBaseObject());
549 DefinedGVSummaries, Worklist, ImportList,
550 ExportLists, ImportThresholds);
554 while (!Worklist.
empty()) {
556 auto *Summary = std::get<0>(GVInfo);
557 auto Threshold = std::get<1>(GVInfo);
559 if (
auto *FS = dyn_cast<FunctionSummary>(Summary))
561 Worklist, ImportList, ExportLists,
565 Worklist, ImportList, ExportLists);
571 dbgs() <<
"Missed imports into module " << ModName <<
"\n";
572 for (
auto &
I : ImportThresholds) {
573 auto &ProcessedThreshold = std::get<0>(
I.second);
574 auto &CalleeSummary = std::get<1>(
I.second);
575 auto &FailureInfo = std::get<2>(
I.second);
580 if (!FailureInfo->VI.getSummaryList().empty())
581 FS = dyn_cast<FunctionSummary>(
582 FailureInfo->VI.getSummaryList()[0]->getBaseObject());
583 dbgs() << FailureInfo->VI
585 <<
", Threshold = " << ProcessedThreshold
586 <<
", Size = " << (FS ? (int)FS->instCount() : -1)
588 <<
", Attempts = " << FailureInfo->Attempts <<
"\n";
595 auto SL =
VI.getSummaryList();
603 if (
const auto &
VI =
Index.getValueInfo(
G))
627 for (
auto &ImportPerModule : ImportLists)
628 for (
auto &ExportPerModule : ImportPerModule.second)
629 FlattenedImports.
insert(ExportPerModule.second.begin(),
630 ExportPerModule.second.end());
637 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
638 Index.findSummaryInModule(
VI, ModulePath));
639 return GVS && (
Index.isReadOnly(GVS) ||
Index.isWriteOnly(GVS));
642 for (
auto &ExportPerModule : ExportLists)
643 for (
auto &
VI : ExportPerModule.second)
644 if (!FlattenedImports.
count(
VI.getGUID()) &&
645 IsReadOrWriteOnlyVar(ExportPerModule.first(),
VI))
659 for (
const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
660 auto &ImportList = ImportLists[DefinedGVSummaries.first()];
662 << DefinedGVSummaries.first() <<
"'\n");
664 DefinedGVSummaries.first(), ImportList,
673 for (
auto &ELI : ExportLists) {
675 const auto &DefinedGVSummaries =
676 ModuleToDefinedGVSummaries.
lookup(ELI.first());
677 for (
auto &EI : ELI.second) {
684 auto DS = DefinedGVSummaries.find(EI.getGUID());
687 assert(DS != DefinedGVSummaries.end());
688 auto *S = DS->getSecond();
689 S = S->getBaseObject();
690 if (
auto *GVS = dyn_cast<GlobalVarSummary>(S)) {
695 if (!
Index.isWriteOnly(GVS))
696 for (
const auto &
VI : GVS->refs())
699 auto *FS = cast<FunctionSummary>(S);
700 for (
const auto &Edge : FS->calls())
701 NewExports.
insert(Edge.first);
702 for (
const auto &
Ref : FS->refs())
710 for (
auto EI = NewExports.
begin(); EI != NewExports.
end();) {
711 if (!DefinedGVSummaries.count(EI->getGUID()))
712 NewExports.
erase(EI++);
716 ELI.second.insert(NewExports.
begin(), NewExports.
end());
723 for (
auto &ModuleImports : ImportLists) {
724 auto ModName = ModuleImports.first();
725 auto &
Exports = ExportLists[ModName];
728 <<
Exports.size() - NumGVS <<
" functions and " << NumGVS
729 <<
" vars. Imports from " << ModuleImports.second.size()
731 for (
auto &Src : ModuleImports.second) {
732 auto SrcModName = Src.first();
735 <<
" functions imported from " << SrcModName <<
"\n");
737 <<
" global vars imported from " << SrcModName <<
"\n");
747 LLVM_DEBUG(
dbgs() <<
"* Module " << ModulePath <<
" imports from "
748 << ImportList.
size() <<
" modules.\n");
749 for (
auto &Src : ImportList) {
750 auto SrcModName = Src.first();
753 <<
" functions imported from " << SrcModName <<
"\n");
754 LLVM_DEBUG(
dbgs() <<
" - " << NumGVSPerMod <<
" vars imported from "
755 << SrcModName <<
"\n");
767 Index.collectDefinedFunctionsForModule(ModulePath, FunctionSummaryMap);
770 LLVM_DEBUG(
dbgs() <<
"Computing import for Module '" << ModulePath <<
"'\n");
783 for (
const auto &GlobalList :
Index) {
785 if (GlobalList.second.SummaryList.empty())
788 auto GUID = GlobalList.first;
789 assert(GlobalList.second.SummaryList.size() == 1 &&
790 "Expected individual combined index to have one summary per GUID");
791 auto &Summary = GlobalList.second.SummaryList[0];
794 if (Summary->modulePath() == ModulePath)
797 ImportList[Summary->modulePath()].
insert(GUID);
810 for (
auto &EI : FS->mutableCalls()) {
811 if (!EI.first.getSummaryList().empty())
813 auto GUID =
Index.getGUIDFromOriginalID(EI.first.getGUID());
817 auto VI =
Index.getValueInfo(GUID);
820 [&](
const std::unique_ptr<GlobalValueSummary> &SummaryPtr) {
830 return SummaryPtr->getSummaryKind() ==
831 GlobalValueSummary::GlobalVarKind;
839 for (
const auto &Entry :
Index) {
840 for (
const auto &S : Entry.second.SummaryList) {
841 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
854 GUIDPreservedSymbols.
empty()) {
859 unsigned LiveSymbols = 0;
862 for (
auto GUID : GUIDPreservedSymbols) {
866 for (
const auto &S :
VI.getSummaryList())
871 for (
const auto &Entry :
Index) {
872 auto VI =
Index.getValueInfo(Entry);
873 for (
const auto &S : Entry.second.SummaryList) {
874 if (
auto *FS = dyn_cast<FunctionSummary>(S.get()))
897 [](
const std::unique_ptr<llvm::GlobalValueSummary> &S) {
907 if (isPrevailing(
VI.getGUID()) == PrevailingType::No) {
908 bool KeepAliveLinkage =
false;
909 bool Interposable =
false;
910 for (
const auto &S :
VI.getSummaryList()) {
914 KeepAliveLinkage =
true;
920 if (!KeepAliveLinkage)
925 "Interposable and available_externally/linkonce_odr/weak_odr "
930 for (
const auto &S :
VI.getSummaryList())
936 while (!Worklist.
empty()) {
938 for (
const auto &Summary :
VI.getSummaryList()) {
939 if (
auto *AS = dyn_cast<AliasSummary>(Summary.get())) {
943 visit(AS->getAliaseeVI(),
true);
946 for (
auto Ref : Summary->refs())
948 if (
auto *FS = dyn_cast<FunctionSummary>(Summary.get()))
949 for (
auto Call : FS->calls())
950 visit(Call.first,
false);
953 Index.setWithGlobalValueDeadStripping();
955 unsigned DeadSymbols =
Index.size() - LiveSymbols;
956 LLVM_DEBUG(
dbgs() << LiveSymbols <<
" symbols Live, and " << DeadSymbols
957 <<
" symbols Dead \n");
958 NumDeadSymbols += DeadSymbols;
959 NumLiveSymbols += LiveSymbols;
967 bool ImportEnabled) {
971 Index.propagateAttributes(GUIDPreservedSymbols);
980 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
982 ModuleToSummariesForIndex[std::string(ModulePath)] =
983 ModuleToDefinedGVSummaries.
lookup(ModulePath);
985 for (
const auto &ILI : ImportList) {
986 auto &SummariesForIndex =
987 ModuleToSummariesForIndex[std::string(ILI.first())];
988 const auto &DefinedGVSummaries =
989 ModuleToDefinedGVSummaries.
lookup(ILI.first());
990 for (
const auto &GI : ILI.second) {
991 const auto &DS = DefinedGVSummaries.find(GI);
992 assert(DS != DefinedGVSummaries.end() &&
993 "Expected a defined summary for imported global value");
994 SummariesForIndex[GI] = DS->second;
1002 const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex) {
1007 for (
const auto &ILI : ModuleToSummariesForIndex)
1011 if (ILI.first != ModulePath)
1012 ImportsOS << ILI.first <<
"\n";
1013 return std::error_code();
1019 if (
Function *
F = dyn_cast<Function>(&GV)) {
1022 F->setComdat(
nullptr);
1024 V->setInitializer(
nullptr);
1027 V->setComdat(
nullptr);
1055 auto FinalizeInModule = [&](
GlobalValue &GV,
bool Propagate =
false) {
1057 const auto &GS = DefinedGlobals.
find(GV.
getGUID());
1058 if (GS == DefinedGlobals.
end())
1063 if (
Function *
F = dyn_cast<Function>(&GV)) {
1065 if (FS->fflags().ReadNone && !
F->doesNotAccessMemory())
1066 F->setDoesNotAccessMemory();
1068 if (FS->fflags().ReadOnly && !
F->onlyReadsMemory())
1069 F->setOnlyReadsMemory();
1071 if (FS->fflags().NoRecurse && !
F->doesNotRecurse())
1072 F->setDoesNotRecurse();
1074 if (FS->fflags().NoUnwind && !
F->doesNotThrow())
1075 F->setDoesNotThrow();
1079 auto NewLinkage = GS->second->linkage();
1118 GS->second->canAutoHide()) {
1124 <<
"` from " << GV.
getLinkage() <<
" to " << NewLinkage
1131 auto *GO = dyn_cast_or_null<GlobalObject>(&GV);
1132 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
1133 if (GO->getComdat()->getName() == GO->getName())
1134 NonPrevailingComdats.
insert(GO->getComdat());
1135 GO->setComdat(
nullptr);
1140 for (
auto &GV : TheModule)
1142 for (
auto &GV : TheModule.
globals())
1143 FinalizeInModule(GV);
1144 for (
auto &GV : TheModule.
aliases())
1145 FinalizeInModule(GV);
1150 if (NonPrevailingComdats.
empty())
1153 if (
auto *
C = GO.getComdat();
C && NonPrevailingComdats.
count(
C)) {
1154 GO.setComdat(
nullptr);
1165 for (
auto &GA : TheModule.
aliases()) {
1166 if (GA.hasAvailableExternallyLinkage())
1169 assert(Obj &&
"aliasee without an base object is unimplemented");
1183 auto MustPreserveGV = [&](
const GlobalValue &GV) ->
bool {
1187 if (isa<GlobalIFunc>(&GV) ||
1188 (isa<GlobalAlias>(&GV) &&
1189 isa<GlobalIFunc>(cast<GlobalAlias>(&GV)->getAliaseeObject())))
1193 auto GS = DefinedGlobals.
find(GV.getGUID());
1194 if (GS == DefinedGlobals.
end()) {
1206 if (GS == DefinedGlobals.
end()) {
1243 for (
auto &GV : M.globals())
1246 if (!GV.isDeclaration() && GV.hasAttribute(
"thinlto-internalize")) {
1258 unsigned ImportedCount = 0, ImportedGVCount = 0;
1262 std::set<StringRef> ModuleNameOrderedList;
1263 for (
const auto &FunctionsToImportPerModule : ImportList) {
1264 ModuleNameOrderedList.insert(FunctionsToImportPerModule.first());
1266 for (
const auto &
Name : ModuleNameOrderedList) {
1268 const auto &FunctionsToImportPerModule = ImportList.
find(
Name);
1269 assert(FunctionsToImportPerModule != ImportList.
end());
1271 if (!SrcModuleOrErr)
1273 std::unique_ptr<Module> SrcModule = std::move(*SrcModuleOrErr);
1275 "Context mismatch");
1279 if (
Error Err = SrcModule->materializeMetadata())
1280 return std::move(Err);
1282 auto &ImportGUIDs = FunctionsToImportPerModule->second;
1288 auto GUID =
F.getGUID();
1289 auto Import = ImportGUIDs.count(GUID);
1291 << GUID <<
" " <<
F.getName() <<
" from "
1292 << SrcModule->getSourceFileName() <<
"\n");
1294 if (
Error Err =
F.materialize())
1295 return std::move(Err);
1299 "thinlto_src_module",
1301 {MDString::get(DestModule.getContext(),
1302 SrcModule->getSourceFileName())}));
1310 auto GUID = GV.getGUID();
1311 auto Import = ImportGUIDs.count(GUID);
1313 << GUID <<
" " << GV.getName() <<
" from "
1314 << SrcModule->getSourceFileName() <<
"\n");
1316 if (
Error Err = GV.materialize())
1317 return std::move(Err);
1318 ImportedGVCount += GlobalsToImport.
insert(&GV);
1322 if (!GA.hasName() || isa<GlobalIFunc>(GA.getAliaseeObject()))
1324 auto GUID = GA.getGUID();
1325 auto Import = ImportGUIDs.count(GUID);
1327 << GUID <<
" " << GA.getName() <<
" from "
1328 << SrcModule->getSourceFileName() <<
"\n");
1330 if (
Error Err = GA.materialize())
1331 return std::move(Err);
1335 return std::move(Err);
1339 << SrcModule->getSourceFileName() <<
"\n");
1343 "thinlto_src_module",
1345 {MDString::get(DestModule.getContext(),
1346 SrcModule->getSourceFileName())}));
1348 GlobalsToImport.
insert(Fn);
1360 SrcModule->setPartialSampleProfileRatio(
Index);
1368 for (
const auto *GV : GlobalsToImport)
1370 <<
" from " << SrcModule->getSourceFileName() <<
"\n";
1373 if (
Error Err = Mover.
move(std::move(SrcModule),
1377 Twine(
"Function Import: link error: ") +
1380 ImportedCount += GlobalsToImport.
size();
1381 NumImportedModules++;
1386 NumImportedFunctions += (ImportedCount - ImportedGVCount);
1387 NumImportedGlobalVars += ImportedGVCount;
1389 LLVM_DEBUG(
dbgs() <<
"Imported " << ImportedCount - ImportedGVCount
1390 <<
" functions for Module "
1393 <<
" global variables for Module "
1395 return ImportedCount;
1403 if (!IndexPtrOrErr) {
1408 std::unique_ptr<ModuleSummaryIndex>
Index = std::move(*IndexPtrOrErr);
1427 for (
auto &S :
I.second.SummaryList) {
1437 errs() <<
"Error renaming module\n";
1442 auto ModuleLoader = [&M](
StringRef Identifier) {
1443 return loadFile(std::string(Identifier), M.getContext());
1452 "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 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 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 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 void computeImportForFunction(const FunctionSummary &Summary, const ModuleSummaryIndex &Index, const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, SmallVectorImpl< EdgeInfo > &Worklist, FunctionImporter::ImportMapTy &ImportList, StringMap< FunctionImporter::ExportSetTy > *ExportLists, FunctionImporter::ImportThresholdsTy &ImportThresholds)
Compute the list of functions to import for a given caller.
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 bool doImportingForModule(Module &M)
static void ComputeImportForModule(const GVSummaryMapTy &DefinedGVSummaries, 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 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 void computeImportForReferencedGlobals(const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index, const GVSummaryMapTy &DefinedGVSummaries, SmallVectorImpl< EdgeInfo > &Worklist, FunctionImporter::ImportMapTy &ImportList, StringMap< FunctionImporter::ExportSetTy > *ExportLists)
static bool shouldImportGlobal(const ValueInfo &VI, const GVSummaryMapTy &DefinedGVSummaries)
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 unsigned numGlobalVarSummaries(const ModuleSummaryIndex &Index, T &Cont)
static const GlobalValueSummary * selectCallee(const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, FunctionImporter::ImportFailureReason &Reason, GlobalValue::GUID GUID)
Given a list of possible callee implementation for a call site, select one that fits the Threshold.
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)
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)
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.
ArrayRef< T > getArrayRef() const
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)
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 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.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
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 ComputeCrossModuleImport(const ModuleSummaryIndex &Index, const StringMap< GVSummaryMapTy > &ModuleToDefinedGVSummaries, StringMap< FunctionImporter::ImportMapTy > &ImportLists, StringMap< FunctionImporter::ExportSetTy > &ExportLists)
Compute all the imports and exports for every module in the Index.
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...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool UpgradeDebugInfo(Module &M)
Check the debug info version number, if it is out-dated, drop the debug info.
void ComputeCrossModuleImportForModule(StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
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.