@@ -245,24 +245,25 @@ using EdgeInfo =
245
245
246
246
} // anonymous namespace
247
247
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) {
250
252
const auto &GVS = DefinedGVSummaries.find (VI.getGUID ());
251
253
if (GVS == DefinedGVSummaries.end ())
252
254
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.
262
262
// FIXME: Consider adding a check that the suitable prevailing definition
263
263
// exists and marked read-only.
264
264
if (VI.getSummaryList ().size () > 1 &&
265
- GlobalValue::isInterposableLinkage (GVS->second ->linkage ()))
265
+ GlobalValue::isInterposableLinkage (GVS->second ->linkage ()) &&
266
+ !isPrevailing (VI.getGUID (), GVS->second ))
266
267
return true ;
267
268
268
269
return false ;
@@ -271,11 +272,13 @@ static bool shouldImportGlobal(const ValueInfo &VI,
271
272
static void computeImportForReferencedGlobals (
272
273
const GlobalValueSummary &Summary, const ModuleSummaryIndex &Index,
273
274
const GVSummaryMapTy &DefinedGVSummaries,
275
+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
276
+ isPrevailing,
274
277
SmallVectorImpl<EdgeInfo> &Worklist,
275
278
FunctionImporter::ImportMapTy &ImportList,
276
279
StringMap<FunctionImporter::ExportSetTy> *ExportLists) {
277
280
for (const auto &VI : Summary.refs ()) {
278
- if (!shouldImportGlobal (VI, DefinedGVSummaries)) {
281
+ if (!shouldImportGlobal (VI, DefinedGVSummaries, isPrevailing )) {
279
282
LLVM_DEBUG (
280
283
dbgs () << " Ref ignored! Target already in destination module.\n " );
281
284
continue ;
@@ -348,12 +351,15 @@ getFailureName(FunctionImporter::ImportFailureReason Reason) {
348
351
static void computeImportForFunction (
349
352
const FunctionSummary &Summary, const ModuleSummaryIndex &Index,
350
353
const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries,
354
+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
355
+ isPrevailing,
351
356
SmallVectorImpl<EdgeInfo> &Worklist,
352
357
FunctionImporter::ImportMapTy &ImportList,
353
358
StringMap<FunctionImporter::ExportSetTy> *ExportLists,
354
359
FunctionImporter::ImportThresholdsTy &ImportThresholds) {
355
360
computeImportForReferencedGlobals (Summary, Index, DefinedGVSummaries,
356
- Worklist, ImportList, ExportLists);
361
+ isPrevailing, Worklist, ImportList,
362
+ ExportLists);
357
363
static int ImportCount = 0 ;
358
364
for (const auto &Edge : Summary.calls ()) {
359
365
ValueInfo VI = Edge.first ;
@@ -519,8 +525,11 @@ static void computeImportForFunction(
519
525
// / as well as the list of "exports", i.e. the list of symbols referenced from
520
526
// / another module (that may require promotion).
521
527
static 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,
524
533
StringMap<FunctionImporter::ExportSetTy> *ExportLists = nullptr) {
525
534
// Worklist contains the list of function imported in this module, for which
526
535
// we will analyse the callees and may import further down the callgraph.
@@ -546,8 +555,8 @@ static void ComputeImportForModule(
546
555
continue ;
547
556
LLVM_DEBUG (dbgs () << " Initialize import for " << VI << " \n " );
548
557
computeImportForFunction (*FuncSummary, Index, ImportInstrLimit,
549
- DefinedGVSummaries, Worklist, ImportList ,
550
- ExportLists, ImportThresholds);
558
+ DefinedGVSummaries, isPrevailing, Worklist ,
559
+ ImportList, ExportLists, ImportThresholds);
551
560
}
552
561
553
562
// Process the newly imported functions and add callees to the worklist.
@@ -558,11 +567,12 @@ static void ComputeImportForModule(
558
567
559
568
if (auto *FS = dyn_cast<FunctionSummary>(Summary))
560
569
computeImportForFunction (*FS, Index, Threshold, DefinedGVSummaries,
561
- Worklist, ImportList, ExportLists,
570
+ isPrevailing, Worklist, ImportList, ExportLists,
562
571
ImportThresholds);
563
572
else
564
573
computeImportForReferencedGlobals (*Summary, Index, DefinedGVSummaries,
565
- Worklist, ImportList, ExportLists);
574
+ isPrevailing, Worklist, ImportList,
575
+ ExportLists);
566
576
}
567
577
568
578
// Print stats about functions considered but rejected for importing
@@ -653,14 +663,16 @@ checkVariableImport(const ModuleSummaryIndex &Index,
653
663
void llvm::ComputeCrossModuleImport (
654
664
const ModuleSummaryIndex &Index,
655
665
const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
666
+ function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
667
+ isPrevailing,
656
668
StringMap<FunctionImporter::ImportMapTy> &ImportLists,
657
669
StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
658
670
// For each module that has function defined, compute the import/export lists.
659
671
for (const auto &DefinedGVSummaries : ModuleToDefinedGVSummaries) {
660
672
auto &ImportList = ImportLists[DefinedGVSummaries.first ()];
661
673
LLVM_DEBUG (dbgs () << " Computing import for Module '"
662
674
<< DefinedGVSummaries.first () << " '\n " );
663
- ComputeImportForModule (DefinedGVSummaries.second , Index,
675
+ ComputeImportForModule (DefinedGVSummaries.second , isPrevailing, Index,
664
676
DefinedGVSummaries.first (), ImportList,
665
677
&ExportLists);
666
678
}
@@ -759,7 +771,10 @@ static void dumpImportListForModule(const ModuleSummaryIndex &Index,
759
771
760
772
// / Compute all the imports for the given module in the Index.
761
773
void 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,
763
778
FunctionImporter::ImportMapTy &ImportList) {
764
779
// Collect the list of functions this module defines.
765
780
// GUID -> Summary
@@ -768,7 +783,8 @@ void llvm::ComputeCrossModuleImportForModule(
768
783
769
784
// Compute the import list for this module.
770
785
LLVM_DEBUG (dbgs () << " Computing import for Module '" << ModulePath << " '\n " );
771
- ComputeImportForModule (FunctionSummaryMap, Index, ModulePath, ImportList);
786
+ ComputeImportForModule (FunctionSummaryMap, isPrevailing, Index, ModulePath,
787
+ ImportList);
772
788
773
789
#ifndef NDEBUG
774
790
dumpImportListForModule (Index, ModulePath, ImportList);
@@ -1395,7 +1411,9 @@ Expected<bool> FunctionImporter::importFunctions(
1395
1411
return ImportedCount;
1396
1412
}
1397
1413
1398
- static bool doImportingForModule (Module &M) {
1414
+ static bool doImportingForModule (
1415
+ Module &M, function_ref<bool (GlobalValue::GUID, const GlobalValueSummary *)>
1416
+ isPrevailing) {
1399
1417
if (SummaryFile.empty ())
1400
1418
report_fatal_error (" error: -function-import requires -summary-file\n " );
1401
1419
Expected<std::unique_ptr<ModuleSummaryIndex>> IndexPtrOrErr =
@@ -1416,8 +1434,8 @@ static bool doImportingForModule(Module &M) {
1416
1434
ComputeCrossModuleImportForModuleFromIndex (M.getModuleIdentifier (), *Index,
1417
1435
ImportList);
1418
1436
else
1419
- ComputeCrossModuleImportForModule (M.getModuleIdentifier (), *Index ,
1420
- ImportList);
1437
+ ComputeCrossModuleImportForModule (M.getModuleIdentifier (), isPrevailing ,
1438
+ *Index, ImportList);
1421
1439
1422
1440
// Conservatively mark all internal values as promoted. This interface is
1423
1441
// only used when doing importing via the function importing pass. The pass
@@ -1458,7 +1476,14 @@ static bool doImportingForModule(Module &M) {
1458
1476
1459
1477
PreservedAnalyses FunctionImportPass::run (Module &M,
1460
1478
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))
1462
1487
return PreservedAnalyses::all ();
1463
1488
1464
1489
return PreservedAnalyses::none ();
0 commit comments