@@ -245,24 +245,25 @@ using EdgeInfo =
245245
246246} // anonymous namespace
247247
248- static bool shouldImportGlobal (const ValueInfo &VI,
249- const GVSummaryMapTy &DefinedGVSummaries) {
248+ static bool shouldImportGlobal (
249+ const ValueInfo &VI, const GVSummaryMapTy &DefinedGVSummaries,
250+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
251+ isPrevailing) {
250252 const auto &GVS = DefinedGVSummaries.find (VI.getGUID ());
251253 if (GVS == DefinedGVSummaries.end ())
252254 return true ;
253- // We should not skip import if the module contains a definition with
254- // interposable linkage type. This is required for correctness in
255- // the situation with two following conditions:
256- // * the def with interposable linkage is non-prevailing,
257- // * there is a prevailing def available for import and marked read-only.
258- // In this case, the non-prevailing def will be converted to a declaration,
259- // while the prevailing one becomes internal, thus no definitions will be
260- // available for linking. In order to prevent undefined symbol link error,
261- // the prevailing definition must be imported.
255+ // We should not skip import if the module contains a non-prevailing
256+ // definition with interposable linkage type. This is required for correctness
257+ // in the situation where there is a prevailing def available for import and
258+ // marked read-only. In this case, the non-prevailing def will be converted to
259+ // a declaration, while the prevailing one becomes internal, thus no
260+ // definitions will be available for linking. In order to prevent undefined
261+ // symbol link error, the prevailing definition must be imported.
262262 // FIXME: Consider adding a check that the suitable prevailing definition
263263 // exists and marked read-only.
264264 if (VI.getSummaryList ().size () > 1 &&
265- GlobalValue::isInterposableLinkage (GVS->second ->linkage ()))
265+ GlobalValue::isInterposableLinkage (GVS->second ->linkage ()) &&
266+ !isPrevailing (VI.getGUID (), GVS->second ))
266267 return true ;
267268
268269 return false ;
@@ -271,11 +272,13 @@ static bool shouldImportGlobal(const ValueInfo &VI,
271272static void computeImportForReferencedGlobals (
272273 const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
273274 const GVSummaryMapTy &DefinedGVSummaries,
275+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
276+ isPrevailing,
274277 SmallVectorImpl<EdgeInfo> &Worklist,
275278 FunctionImporter::ImportMapTy &ImportList,
276279 StringMap<FunctionImporter::ExportSetTy> *ExportLists) {
277280 for (const auto &VI : Summary.refs ()) {
278- if (!shouldImportGlobal (VI, DefinedGVSummaries)) {
281+ if (!shouldImportGlobal (VI, DefinedGVSummaries, isPrevailing )) {
279282 LLVM_DEBUG (
280283 dbgs () << " Ref ignored! Target already in destination module.\n " );
281284 continue ;
@@ -348,12 +351,15 @@ getFailureName(FunctionImporter::ImportFailureReason Reason) {
348351static void computeImportForFunction (
349352 const FunctionSummary &Summary, const ModuleSummaryIndex &Index,
350353 const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries,
354+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
355+ isPrevailing,
351356 SmallVectorImpl<EdgeInfo> &Worklist,
352357 FunctionImporter::ImportMapTy &ImportList,
353358 StringMap<FunctionImporter::ExportSetTy> *ExportLists,
354359 FunctionImporter::ImportThresholdsTy &ImportThresholds) {
355360 computeImportForReferencedGlobals (Summary, Index, DefinedGVSummaries,
356- Worklist, ImportList, ExportLists);
361+ isPrevailing, Worklist, ImportList,
362+ ExportLists);
357363 static int ImportCount = 0 ;
358364 for (const auto &Edge : Summary.calls ()) {
359365 ValueInfo VI = Edge.first ;
@@ -519,8 +525,11 @@ static void computeImportForFunction(
519525// / as well as the list of "exports", i.e. the list of symbols referenced from
520526// / another module (that may require promotion).
521527static void ComputeImportForModule (
522- const GVSummaryMapTy &DefinedGVSummaries, const ModuleSummaryIndex &Index,
523- StringRef ModName, FunctionImporter::ImportMapTy &ImportList,
528+ const GVSummaryMapTy &DefinedGVSummaries,
529+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
530+ isPrevailing,
531+ const ModuleSummaryIndex &Index, StringRef ModName,
532+ FunctionImporter::ImportMapTy &ImportList,
524533 StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
525534 // Worklist contains the list of function imported in this module, for which
526535 // we will analyse the callees and may import further down the callgraph.
@@ -546,8 +555,8 @@ static void ComputeImportForModule(
546555 continue ;
547556 LLVM_DEBUG (dbgs () << " Initialize import for " << VI << " \n " );
548557 computeImportForFunction (*FuncSummary, Index, ImportInstrLimit,
549- DefinedGVSummaries, Worklist, ImportList ,
550- ExportLists, ImportThresholds);
558+ DefinedGVSummaries, isPrevailing, Worklist ,
559+ ImportList, ExportLists, ImportThresholds);
551560 }
552561
553562 // Process the newly imported functions and add callees to the worklist.
@@ -558,11 +567,12 @@ static void ComputeImportForModule(
558567
559568 if (auto *FS = dyn_cast<FunctionSummary>(Summary))
560569 computeImportForFunction (*FS, Index, Threshold, DefinedGVSummaries,
561- Worklist, ImportList, ExportLists,
570+ isPrevailing, Worklist, ImportList, ExportLists,
562571 ImportThresholds);
563572 else
564573 computeImportForReferencedGlobals (*Summary, Index, DefinedGVSummaries,
565- Worklist, ImportList, ExportLists);
574+ isPrevailing, Worklist, ImportList,
575+ ExportLists);
566576 }
567577
568578 // Print stats about functions considered but rejected for importing
@@ -653,14 +663,16 @@ checkVariableImport(const ModuleSummaryIndex &Index,
653663void llvm::ComputeCrossModuleImport (
654664 const ModuleSummaryIndex &Index,
655665 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
666+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
667+ isPrevailing,
656668 StringMap<FunctionImporter::ImportMapTy> &ImportLists,
657669 StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
658670 // For each module that has function defined, compute the import/export lists.
659671 for (const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
660672 auto &ImportList = ImportLists[DefinedGVSummaries.first ()];
661673 LLVM_DEBUG (dbgs () << " Computing import for Module '"
662674 << DefinedGVSummaries.first () << " '\n " );
663- ComputeImportForModule (DefinedGVSummaries.second , Index,
675+ ComputeImportForModule (DefinedGVSummaries.second , isPrevailing, Index,
664676 DefinedGVSummaries.first (), ImportList,
665677 &ExportLists);
666678 }
@@ -759,7 +771,10 @@ static void dumpImportListForModule(const ModuleSummaryIndex &Index,
759771
760772// / Compute all the imports for the given module in the Index.
761773void llvm::ComputeCrossModuleImportForModule (
762- StringRef ModulePath, const ModuleSummaryIndex &Index,
774+ StringRef ModulePath,
775+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
776+ isPrevailing,
777+ const ModuleSummaryIndex &Index,
763778 FunctionImporter::ImportMapTy &ImportList) {
764779 // Collect the list of functions this module defines.
765780 // GUID -> Summary
@@ -768,7 +783,8 @@ void llvm::ComputeCrossModuleImportForModule(
768783
769784 // Compute the import list for this module.
770785 LLVM_DEBUG (dbgs () << " Computing import for Module '" << ModulePath << " '\n " );
771- ComputeImportForModule (FunctionSummaryMap, Index, ModulePath, ImportList);
786+ ComputeImportForModule (FunctionSummaryMap, isPrevailing, Index, ModulePath,
787+ ImportList);
772788
773789#ifndef NDEBUG
774790 dumpImportListForModule (Index, ModulePath, ImportList);
@@ -1395,7 +1411,9 @@ Expected<bool> FunctionImporter::importFunctions(
13951411 return ImportedCount;
13961412}
13971413
1398- static bool doImportingForModule (Module &M) {
1414+ static bool doImportingForModule (
1415+ Module &M, function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
1416+ isPrevailing) {
13991417 if (SummaryFile.empty ())
14001418 report_fatal_error (" error: -function-import requires -summary-file\n " );
14011419 Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =
@@ -1416,8 +1434,8 @@ static bool doImportingForModule(Module &M) {
14161434 ComputeCrossModuleImportForModuleFromIndex (M.getModuleIdentifier (), *Index,
14171435 ImportList);
14181436 else
1419- ComputeCrossModuleImportForModule (M.getModuleIdentifier (), *Index ,
1420- ImportList);
1437+ ComputeCrossModuleImportForModule (M.getModuleIdentifier (), isPrevailing ,
1438+ *Index, ImportList);
14211439
14221440 // Conservatively mark all internal values as promoted. This interface is
14231441 // only used when doing importing via the function importing pass. The pass
@@ -1458,7 +1476,14 @@ static bool doImportingForModule(Module &M) {
14581476
14591477PreservedAnalyses FunctionImportPass::run (Module &M,
14601478 ModuleAnalysisManager &AM) {
1461- if (!doImportingForModule (M))
1479+ // This is only used for testing the function import pass via opt, where we
1480+ // don't have prevailing information from the LTO context available, so just
1481+ // conservatively assume everything is prevailing (which is fine for the very
1482+ // limited use of prevailing checking in this pass).
1483+ auto isPrevailing = [](GlobalValue::GUID, const GlobalValueSummary *) {
1484+ return true ;
1485+ };
1486+ if (!doImportingForModule (M, isPrevailing))
14621487 return PreservedAnalyses::all ();
14631488
14641489 return PreservedAnalyses::none ();
0 commit comments