diff --git a/llvm/lib/IR/ModuleSummaryIndex.cpp b/llvm/lib/IR/ModuleSummaryIndex.cpp --- a/llvm/lib/IR/ModuleSummaryIndex.cpp +++ b/llvm/lib/IR/ModuleSummaryIndex.cpp @@ -163,7 +163,9 @@ return false; } -static void propagateAttributesToRefs(GlobalValueSummary *S) { +static void +propagateAttributesToRefs(GlobalValueSummary *S, + DenseSet &MarkedNonReadWriteOnly) { // If reference is not readonly or writeonly then referenced summary is not // read/writeonly either. Note that: // - All references from GlobalVarSummary are conservatively considered as @@ -174,6 +176,11 @@ // for them. for (auto &VI : S->refs()) { assert(VI.getAccessSpecifier() == 0 || isa(S)); + if (!VI.getAccessSpecifier()) { + if (!MarkedNonReadWriteOnly.insert(VI).second) + continue; + } else if (MarkedNonReadWriteOnly.find(VI) != MarkedNonReadWriteOnly.end()) + continue; for (auto &Ref : VI.getSummaryList()) // If references to alias is not read/writeonly then aliasee // is not read/writeonly @@ -216,11 +223,24 @@ const DenseSet &GUIDPreservedSymbols) { if (!PropagateAttrs) return; + DenseSet MarkedNonReadWriteOnly; for (auto &P : *this) for (auto &S : P.second.SummaryList) { - if (!isGlobalValueLive(S.get())) + if (!isGlobalValueLive(S.get())) { + // computeDeadSymbols should have marked all copies live. Note that + // it is possible that there is a GUID collision between internal + // symbols with the same name in different files of the same name but + // not enough distinguishing path. Because computeDeadSymbols should + // conservatively mark all copies live we can assert here that all are + // dead if any copy is dead. + assert(llvm::none_of( + P.second.SummaryList, + [&](const std::unique_ptr &Summary) { + return isGlobalValueLive(Summary.get()); + })); // We don't examine references from dead objects - continue; + break; + } // Global variable can't be marked read/writeonly if it is not eligible // to import since we need to ensure that all external references get @@ -240,7 +260,7 @@ GVS->setReadOnly(false); GVS->setWriteOnly(false); } - propagateAttributesToRefs(S.get()); + propagateAttributesToRefs(S.get(), MarkedNonReadWriteOnly); } setWithAttributePropagation(); if (llvm::AreStatisticsEnabled()) diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -884,6 +884,7 @@ while (!Worklist.empty()) { auto VI = Worklist.pop_back_val(); for (auto &Summary : VI.getSummaryList()) { + Summary->setLive(true); if (auto *AS = dyn_cast(Summary.get())) { // If this is an alias, visit the aliasee VI to ensure that all copies // are marked live and it is added to the worklist for further @@ -891,8 +892,6 @@ visit(AS->getAliaseeVI(), true); continue; } - - Summary->setLive(true); for (auto Ref : Summary->refs()) visit(Ref, false); if (auto *FS = dyn_cast(Summary.get()))