[LTO] Perform DSOLocal propagation in combined index
Perform DSOLocal propagation within summary list of every GV. This avoids the repeated query of this information during function importing. Differential Revision: https://reviews.llvm.org/D96398
This commit is contained in:
parent
1f6ec3d08f
commit
80dc0661bd
|
@ -228,7 +228,9 @@ struct ValueInfo {
|
|||
/// protected and hidden.
|
||||
GlobalValue::VisibilityTypes getELFVisibility() const;
|
||||
|
||||
bool isDSOLocal() const;
|
||||
/// Checks if all summaries are DSO local (have the flag set). When DSOLocal
|
||||
/// propagation has been done, set the parameter to enable fast check.
|
||||
bool isDSOLocal(bool WithDSOLocalPropagation = false) const;
|
||||
|
||||
/// Checks if all copies are eligible for auto-hiding (have flag set).
|
||||
bool canAutoHide() const;
|
||||
|
@ -1055,6 +1057,10 @@ private:
|
|||
/// read/write only.
|
||||
bool WithAttributePropagation = false;
|
||||
|
||||
/// Indicates that summary-based DSOLocal propagation has run and the flag in
|
||||
/// every summary of a GV is synchronized.
|
||||
bool WithDSOLocalPropagation = false;
|
||||
|
||||
/// Indicates that summary-based synthetic entry count propagation has run
|
||||
bool HasSyntheticEntryCounts = false;
|
||||
|
||||
|
@ -1210,6 +1216,9 @@ public:
|
|||
WithAttributePropagation = true;
|
||||
}
|
||||
|
||||
bool withDSOLocalPropagation() const { return WithDSOLocalPropagation; }
|
||||
void setWithDSOLocalPropagation() { WithDSOLocalPropagation = true; }
|
||||
|
||||
bool isReadOnly(const GlobalVarSummary *GVS) const {
|
||||
return WithAttributePropagation && GVS->maybeReadOnly();
|
||||
}
|
||||
|
@ -1513,7 +1522,7 @@ public:
|
|||
/// Print out strongly connected components for debugging.
|
||||
void dumpSCCs(raw_ostream &OS);
|
||||
|
||||
/// Analyze index and detect unmodified globals
|
||||
/// Do the access attribute and DSOLocal propagation in combined index.
|
||||
void propagateAttributes(const DenseSet<GlobalValue::GUID> &PreservedSymbols);
|
||||
|
||||
/// Checks if we can import global variable from another module.
|
||||
|
|
|
@ -6845,7 +6845,7 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream,
|
|||
case bitc::FS_FLAGS: { // [flags]
|
||||
uint64_t Flags = Record[0];
|
||||
// Scan flags.
|
||||
assert(Flags <= 0x3f && "Unexpected bits in flag");
|
||||
assert(Flags <= 0x7f && "Unexpected bits in flag");
|
||||
|
||||
return Flags & 0x8;
|
||||
}
|
||||
|
|
|
@ -52,13 +52,17 @@ GlobalValue::VisibilityTypes ValueInfo::getELFVisibility() const {
|
|||
: GlobalValue::DefaultVisibility;
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
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 {
|
||||
|
@ -100,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)
|
||||
|
@ -130,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
|
||||
|
@ -205,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:
|
||||
|
@ -216,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
|
||||
|
@ -225,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.
|
||||
|
@ -236,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
|
||||
|
@ -273,8 +285,20 @@ 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.
|
||||
llvm::for_each(P.second.SummaryList,
|
||||
[](const std::unique_ptr<GlobalValueSummary> &Summary) {
|
||||
return Summary->setDSOLocal(false);
|
||||
});
|
||||
}
|
||||
setWithAttributePropagation();
|
||||
setWithDSOLocalPropagation();
|
||||
if (llvm::AreStatisticsEnabled())
|
||||
for (auto &P : *this)
|
||||
if (P.second.SummaryList.size())
|
||||
|
|
|
@ -207,7 +207,7 @@ void llvm::computeLTOCacheKey(
|
|||
AddUnsigned(GS->isLive());
|
||||
AddUnsigned(GS->canAutoHide());
|
||||
for (const ValueInfo &VI : GS->refs()) {
|
||||
AddUnsigned(VI.isDSOLocal());
|
||||
AddUnsigned(VI.isDSOLocal(Index.withDSOLocalPropagation()));
|
||||
AddUsedCfiGlobal(VI.getGUID());
|
||||
}
|
||||
if (auto *GVS = dyn_cast<GlobalVarSummary>(GS)) {
|
||||
|
@ -226,7 +226,7 @@ void llvm::computeLTOCacheKey(
|
|||
for (auto &TT : FS->type_checked_load_const_vcalls())
|
||||
UsedTypeIds.insert(TT.VFunc.GUID);
|
||||
for (auto &ET : FS->calls()) {
|
||||
AddUnsigned(ET.first.isDSOLocal());
|
||||
AddUnsigned(ET.first.isDSOLocal(Index.withDSOLocalPropagation()));
|
||||
AddUsedCfiGlobal(ET.first.getGUID());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
|
|||
if (ClearDSOLocalOnDeclarations && GV.isDeclarationForLinker() &&
|
||||
!GV.isImplicitDSOLocal()) {
|
||||
GV.setDSOLocal(false);
|
||||
} else if (VI && VI.isDSOLocal()) {
|
||||
} else if (VI && VI.isDSOLocal(ImportIndex.withDSOLocalPropagation())) {
|
||||
// If all summaries are dso_local, symbol gets resolved to a known local
|
||||
// definition.
|
||||
GV.setDSOLocal(true);
|
||||
|
|
|
@ -5,8 +5,8 @@ source_filename = "tmp.bc"
|
|||
; RUN: llvm-as %s -o - | llvm-dis -o - | FileCheck %s
|
||||
; CHECK: ^0 = module
|
||||
; CHECK-NEXT: ^1 = gv
|
||||
; CHECK-NEXT: ^2 = flags: 33
|
||||
; CHECK-NEXT: ^2 = flags: 97
|
||||
|
||||
^0 = module: (path: "main.bc", hash: (3499594384, 1671013073, 3271036935, 1830411232, 59290952))
|
||||
^1 = gv: (guid: 15822663052811949562, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 1, dsoLocal: 1, canAutoHide: 0), insts: 2)))
|
||||
^2 = flags: 33
|
||||
^2 = flags: 97
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
|
||||
; RUN: -r %t.o,glob,plx
|
||||
; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=WITHDEAD
|
||||
; WITHDEAD: <FLAGS op0=33/>
|
||||
; WITHDEAD: <FLAGS op0=97/>
|
||||
|
||||
; Ensure dead stripping performed flag is not set on distributed index
|
||||
; when option used to disable dead stripping computation.
|
||||
; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
|
||||
; RUN: -r %t.o,glob,plx -compute-dead=false
|
||||
; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=NODEAD
|
||||
; NODEAD: <FLAGS op0=32/>
|
||||
; NODEAD: <FLAGS op0=96/>
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
; RUN: llvm-lto2 run %t.o -o %t.out -thinlto-distributed-indexes \
|
||||
; RUN: -r %t.o,glob,plx -compute-dead=false
|
||||
; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=NOSYNTHETIC
|
||||
; NOSYNTHETIC: <FLAGS op0=32/>
|
||||
; NOSYNTHETIC: <FLAGS op0=96/>
|
||||
|
||||
; Ensure synthetic entry count flag is set on distributed index
|
||||
; when option used to enable synthetic count propagation
|
||||
|
@ -13,7 +13,7 @@
|
|||
; RUN: -r %t.o,glob,plx -thinlto-synthesize-entry-counts \
|
||||
; RUN: -compute-dead=false
|
||||
; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=HASSYNTHETIC
|
||||
; HASSYNTHETIC: <FLAGS op0=36/>
|
||||
; HASSYNTHETIC: <FLAGS op0=100/>
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
|
Loading…
Reference in New Issue
Block a user