Skip to content

Commit 7a0f75c

Browse files
Reapply "[GVN] MemorySSA for GVN: add optional AllowMemorySSA"
Original commit: eb63cd6 Previously reverted due to non-negligible compile-time impact in stage1-ReleaseLTO-g scenario. The issue has been addressed by always reusing previously computed MemorySSA results, and request new ones only when `isMemorySSAEnabled` is set. Co-authored-by: Momchil Velikov <[email protected]>
1 parent a94f081 commit 7a0f75c

File tree

5 files changed

+41
-12
lines changed

5 files changed

+41
-12
lines changed

llvm/include/llvm/Transforms/Scalar/GVN.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct GVNOptions {
7777
std::optional<bool> AllowLoadInLoopPRE;
7878
std::optional<bool> AllowLoadPRESplitBackedge;
7979
std::optional<bool> AllowMemDep;
80+
std::optional<bool> AllowMemorySSA;
8081

8182
GVNOptions() = default;
8283

@@ -108,6 +109,12 @@ struct GVNOptions {
108109
AllowMemDep = MemDep;
109110
return *this;
110111
}
112+
113+
/// Enables or disables use of MemorySSA.
114+
GVNOptions &setMemorySSA(bool MemSSA) {
115+
AllowMemorySSA = MemSSA;
116+
return *this;
117+
}
111118
};
112119

113120
/// The core GVN pass object.
@@ -144,6 +151,7 @@ class GVNPass : public PassInfoMixin<GVNPass> {
144151
bool isLoadInLoopPREEnabled() const;
145152
bool isLoadPRESplitBackedgeEnabled() const;
146153
bool isMemDepEnabled() const;
154+
bool isMemorySSAEnabled() const;
147155

148156
/// This class holds the mapping between values and value numbers. It is used
149157
/// as an efficient mechanism to determine the expression-wise equivalence of
@@ -383,9 +391,8 @@ class GVNPass : public PassInfoMixin<GVNPass> {
383391
void assignBlockRPONumber(Function &F);
384392
};
385393

386-
/// Create a legacy GVN pass. This also allows parameterizing whether or not
387-
/// MemDep is enabled.
388-
FunctionPass *createGVNPass(bool NoMemDepAnalysis = false);
394+
/// Create a legacy GVN pass.
395+
FunctionPass *createGVNPass();
389396

390397
/// A simple and fast domtree-based GVN pass to hoist common expressions
391398
/// from sibling branches.

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,8 @@ Expected<GVNOptions> parseGVNOptions(StringRef Params) {
10421042
Result.setLoadPRESplitBackedge(Enable);
10431043
} else if (ParamName == "memdep") {
10441044
Result.setMemDep(Enable);
1045+
} else if (ParamName == "memoryssa") {
1046+
Result.setMemorySSA(Enable);
10451047
} else {
10461048
return make_error<StringError>(
10471049
formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ FUNCTION_PASS_WITH_PARAMS(
526526
"gvn", "GVNPass", [](GVNOptions Opts) { return GVNPass(Opts); },
527527
parseGVNOptions,
528528
"no-pre;pre;no-load-pre;load-pre;no-split-backedge-load-pre;"
529-
"split-backedge-load-pre;no-memdep;memdep")
529+
"split-backedge-load-pre;no-memdep;memdep;no-memoryssa;memoryssa")
530530
FUNCTION_PASS_WITH_PARAMS(
531531
"hardware-loops", "HardwareLoopsPass",
532532
[](HardwareLoopOptions Opts) { return HardwareLoopsPass(Opts); },

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ static cl::opt<bool>
113113
GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre",
114114
cl::init(false));
115115
static cl::opt<bool> GVNEnableMemDep("enable-gvn-memdep", cl::init(true));
116+
static cl::opt<bool> GVNEnableMemorySSA("enable-gvn-memoryssa",
117+
cl::init(false));
116118

117119
static cl::opt<uint32_t> MaxNumDeps(
118120
"gvn-max-num-deps", cl::Hidden, cl::init(100),
@@ -820,6 +822,10 @@ bool GVNPass::isMemDepEnabled() const {
820822
return Options.AllowMemDep.value_or(GVNEnableMemDep);
821823
}
822824

825+
bool GVNPass::isMemorySSAEnabled() const {
826+
return Options.AllowMemorySSA.value_or(GVNEnableMemorySSA);
827+
}
828+
823829
PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
824830
// FIXME: The order of evaluation of these 'getResult' calls is very
825831
// significant! Re-ordering these variables will cause GVN when run alone to
@@ -833,6 +839,11 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
833839
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
834840
auto &LI = AM.getResult<LoopAnalysis>(F);
835841
auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
842+
if (isMemorySSAEnabled() && !MSSA) {
843+
assert(!MemDep &&
844+
"On-demand computation of MemSSA implies that MemDep is disabled!");
845+
MSSA = &AM.getResult<MemorySSAAnalysis>(F);
846+
}
836847
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
837848
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
838849
MSSA ? &MSSA->getMSSA() : nullptr);
@@ -861,7 +872,9 @@ void GVNPass::printPipeline(
861872
OS << (*Options.AllowLoadPRESplitBackedge ? "" : "no-")
862873
<< "split-backedge-load-pre;";
863874
if (Options.AllowMemDep != std::nullopt)
864-
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep";
875+
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep;";
876+
if (Options.AllowMemorySSA != std::nullopt)
877+
OS << (*Options.AllowMemorySSA ? "" : "no-") << "memoryssa";
865878
OS << '>';
866879
}
867880

@@ -3293,8 +3306,11 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
32933306
public:
32943307
static char ID; // Pass identification, replacement for typeid
32953308

3296-
explicit GVNLegacyPass(bool NoMemDepAnalysis = !GVNEnableMemDep)
3297-
: FunctionPass(ID), Impl(GVNOptions().setMemDep(!NoMemDepAnalysis)) {
3309+
explicit GVNLegacyPass(bool MemDepAnalysis = GVNEnableMemDep,
3310+
bool MemSSAAnalysis = GVNEnableMemorySSA)
3311+
: FunctionPass(ID), Impl(GVNOptions()
3312+
.setMemDep(MemDepAnalysis)
3313+
.setMemorySSA(MemSSAAnalysis)) {
32983314
initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry());
32993315
}
33003316

@@ -3303,6 +3319,9 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
33033319
return false;
33043320

33053321
auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
3322+
if (Impl.isMemorySSAEnabled() && !MSSAWP)
3323+
MSSAWP = &getAnalysis<MemorySSAWrapperPass>();
3324+
33063325
return Impl.runImpl(
33073326
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
33083327
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
@@ -3330,6 +3349,8 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
33303349
AU.addPreserved<LoopInfoWrapperPass>();
33313350
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
33323351
AU.addPreserved<MemorySSAWrapperPass>();
3352+
if (Impl.isMemorySSAEnabled())
3353+
AU.addRequired<MemorySSAWrapperPass>();
33333354
}
33343355

33353356
private:
@@ -3341,6 +3362,7 @@ char GVNLegacyPass::ID = 0;
33413362
INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
33423363
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
33433364
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
3365+
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
33443366
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
33453367
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
33463368
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
@@ -3349,6 +3371,4 @@ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
33493371
INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
33503372

33513373
// The public interface to this file...
3352-
FunctionPass *llvm::createGVNPass(bool NoMemDepAnalysis) {
3353-
return new GVNLegacyPass(NoMemDepAnalysis);
3354-
}
3374+
FunctionPass *llvm::createGVNPass() { return new GVNLegacyPass(); }

llvm/test/Other/new-pm-print-pipeline.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-unroll<>,loop-unroll<partial;peeling;runtime;upperbound;profile-peeling;full-unroll-max=5;O1>,loop-unroll<no-partial;no-peeling;no-runtime;no-upperbound;no-profile-peeling;full-unroll-max=7;O1>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-10
3232
; CHECK-10: function(loop-unroll<O2>,loop-unroll<partial;peeling;runtime;upperbound;profile-peeling;full-unroll-max=5;O1>,loop-unroll<no-partial;no-peeling;no-runtime;no-upperbound;no-profile-peeling;full-unroll-max=7;O1>)
3333

34-
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(gvn<>,gvn<pre;load-pre;split-backedge-load-pre;memdep>,gvn<no-pre;no-load-pre;no-split-backedge-load-pre;no-memdep>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-11
35-
; CHECK-11: function(gvn<>,gvn<pre;load-pre;split-backedge-load-pre;memdep>,gvn<no-pre;no-load-pre;no-split-backedge-load-pre;no-memdep>)
34+
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(gvn<>,gvn<pre;load-pre;split-backedge-load-pre;memdep;memoryssa>,gvn<no-pre;no-load-pre;no-split-backedge-load-pre;no-memdep;no-memoryssa>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-11
35+
; CHECK-11: function(gvn<>,gvn<pre;load-pre;split-backedge-load-pre;memdep;memoryssa>,gvn<no-pre;no-load-pre;no-split-backedge-load-pre;no-memdep;no-memoryssa>)
3636

3737
; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(early-cse<>,early-cse<memssa>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-12
3838
; CHECK-12: function(early-cse<>,early-cse<memssa>)

0 commit comments

Comments
 (0)