summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/ModuleSummaryIndex.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/IR/ModuleSummaryIndex.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/IR/ModuleSummaryIndex.cpp')
-rw-r--r--llvm/lib/IR/ModuleSummaryIndex.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/llvm/lib/IR/ModuleSummaryIndex.cpp b/llvm/lib/IR/ModuleSummaryIndex.cpp
index 5d21ca759f35..f4ac6caf4f93 100644
--- a/llvm/lib/IR/ModuleSummaryIndex.cpp
+++ b/llvm/lib/IR/ModuleSummaryIndex.cpp
@@ -40,13 +40,29 @@ constexpr uint32_t FunctionSummary::ParamAccess::RangeWidth;
FunctionSummary FunctionSummary::ExternalNode =
FunctionSummary::makeDummyFunctionSummary({});
-bool ValueInfo::isDSOLocal() const {
- // Need to check all summaries are local in case of hash collisions.
- return getSummaryList().size() &&
- llvm::all_of(getSummaryList(),
- [](const std::unique_ptr<GlobalValueSummary> &Summary) {
- return Summary->isDSOLocal();
- });
+GlobalValue::VisibilityTypes ValueInfo::getELFVisibility() const {
+ bool HasProtected = false;
+ for (const auto &S : make_pointee_range(getSummaryList())) {
+ if (S.getVisibility() == GlobalValue::HiddenVisibility)
+ return GlobalValue::HiddenVisibility;
+ if (S.getVisibility() == GlobalValue::ProtectedVisibility)
+ HasProtected = true;
+ }
+ return HasProtected ? GlobalValue::ProtectedVisibility
+ : GlobalValue::DefaultVisibility;
+}
+
+bool ValueInfo::isDSOLocal(bool WithDSOLocalPropagation) const {
+ // With DSOLocal propagation done, the flag in evey summary is the same.
+ // Check the first one is enough.
+ return WithDSOLocalPropagation
+ ? getSummaryList().size() && getSummaryList()[0]->isDSOLocal()
+ : getSummaryList().size() &&
+ llvm::all_of(
+ getSummaryList(),
+ [](const std::unique_ptr<GlobalValueSummary> &Summary) {
+ return Summary->isDSOLocal();
+ });
}
bool ValueInfo::canAutoHide() const {
@@ -88,11 +104,13 @@ uint64_t ModuleSummaryIndex::getFlags() const {
Flags |= 0x10;
if (withAttributePropagation())
Flags |= 0x20;
+ if (withDSOLocalPropagation())
+ Flags |= 0x40;
return Flags;
}
void ModuleSummaryIndex::setFlags(uint64_t Flags) {
- assert(Flags <= 0x3f && "Unexpected bits in flag");
+ assert(Flags <= 0x7f && "Unexpected bits in flag");
// 1 bit: WithGlobalValueDeadStripping flag.
// Set on combined index only.
if (Flags & 0x1)
@@ -118,6 +136,10 @@ void ModuleSummaryIndex::setFlags(uint64_t Flags) {
// Set on combined index only.
if (Flags & 0x20)
setWithAttributePropagation();
+ // 1 bit: WithDSOLocalPropagation flag.
+ // Set on combined index only.
+ if (Flags & 0x40)
+ setWithDSOLocalPropagation();
}
// Collect for the given module the list of function it defines
@@ -193,7 +215,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
}
}
-// Do the access attribute propagation in combined index.
+// Do the access attribute and DSOLocal propagation in combined index.
// The goal of attribute propagation is internalization of readonly (RO)
// or writeonly (WO) variables. To determine which variables are RO or WO
// and which are not we take following steps:
@@ -204,7 +226,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
// or doesn't read it (writeonly).
//
// - After computing dead symbols in combined index we do the attribute
-// propagation. During this step we:
+// and DSOLocal propagation. During this step we:
// a. clear RO and WO attributes from variables which are preserved or
// can't be imported
// b. clear RO and WO attributes from variables referenced by any global
@@ -213,6 +235,7 @@ propagateAttributesToRefs(GlobalValueSummary *S,
// reference is not readonly
// d. clear WO attribute from variable referenced by a function when
// reference is not writeonly
+// e. clear IsDSOLocal flag in every summary if any of them is false.
//
// Because of (c, d) we don't internalize variables read by function A
// and modified by function B.
@@ -224,7 +247,8 @@ void ModuleSummaryIndex::propagateAttributes(
if (!PropagateAttrs)
return;
DenseSet<ValueInfo> MarkedNonReadWriteOnly;
- for (auto &P : *this)
+ for (auto &P : *this) {
+ bool IsDSOLocal = true;
for (auto &S : P.second.SummaryList) {
if (!isGlobalValueLive(S.get())) {
// computeDeadSymbols should have marked all copies live. Note that
@@ -261,8 +285,19 @@ void ModuleSummaryIndex::propagateAttributes(
GVS->setWriteOnly(false);
}
propagateAttributesToRefs(S.get(), MarkedNonReadWriteOnly);
+
+ // If the flag from any summary is false, the GV is not DSOLocal.
+ IsDSOLocal &= S->isDSOLocal();
}
+ if (!IsDSOLocal)
+ // Mark the flag in all summaries false so that we can do quick check
+ // without going through the whole list.
+ for (const std::unique_ptr<GlobalValueSummary> &Summary :
+ P.second.SummaryList)
+ Summary->setDSOLocal(false);
+ }
setWithAttributePropagation();
+ setWithDSOLocalPropagation();
if (llvm::AreStatisticsEnabled())
for (auto &P : *this)
if (P.second.SummaryList.size())
@@ -564,6 +599,8 @@ void ModuleSummaryIndex::exportToDot(
if (Flags.Live && hasConstantFlag(SummaryIt.second))
A.addComment("constant");
}
+ if (Flags.Visibility)
+ A.addComment("visibility");
if (Flags.DSOLocal)
A.addComment("dsoLocal");
if (Flags.CanAutoHide)