Skip to content

Commit eb63cd6

Browse files
[GVN] MemorySSA for GVN: add optional AllowMemorySSA
Preparatory work to migrate from MemoryDependenceAnalysis towards MemorySSA in GVN. Co-authored-by: Antonio Frighetto <[email protected]>
1 parent 66e41a1 commit eb63cd6

File tree

5 files changed

+40
-16
lines changed

5 files changed

+40
-16
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: 25 additions & 10 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
@@ -832,7 +838,10 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
832838
auto *MemDep =
833839
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
834840
auto &LI = AM.getResult<LoopAnalysis>(F);
835-
auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
841+
auto *MSSA =
842+
isMemorySSAEnabled() ? &AM.getResult<MemorySSAAnalysis>(F) : nullptr;
843+
assert(!(MemDep && MSSA) &&
844+
"Should not use both MemDep and MemorySSA simultaneously!");
836845
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
837846
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
838847
MSSA ? &MSSA->getMSSA() : nullptr);
@@ -861,7 +870,9 @@ void GVNPass::printPipeline(
861870
OS << (*Options.AllowLoadPRESplitBackedge ? "" : "no-")
862871
<< "split-backedge-load-pre;";
863872
if (Options.AllowMemDep != std::nullopt)
864-
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep";
873+
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep;";
874+
if (Options.AllowMemorySSA != std::nullopt)
875+
OS << (*Options.AllowMemorySSA ? "" : "no-") << "memoryssa";
865876
OS << '>';
866877
}
867878

@@ -3293,16 +3304,18 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
32933304
public:
32943305
static char ID; // Pass identification, replacement for typeid
32953306

3296-
explicit GVNLegacyPass(bool NoMemDepAnalysis = !GVNEnableMemDep)
3297-
: FunctionPass(ID), Impl(GVNOptions().setMemDep(!NoMemDepAnalysis)) {
3307+
explicit GVNLegacyPass(bool MemDepAnalysis = GVNEnableMemDep,
3308+
bool MemSSAAnalysis = GVNEnableMemorySSA)
3309+
: FunctionPass(ID), Impl(GVNOptions()
3310+
.setMemDep(MemDepAnalysis)
3311+
.setMemorySSA(MemSSAAnalysis)) {
32983312
initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry());
32993313
}
33003314

33013315
bool runOnFunction(Function &F) override {
33023316
if (skipFunction(F))
33033317
return false;
33043318

3305-
auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
33063319
return Impl.runImpl(
33073320
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
33083321
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
@@ -3313,7 +3326,9 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
33133326
: nullptr,
33143327
getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
33153328
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
3316-
MSSAWP ? &MSSAWP->getMSSA() : nullptr);
3329+
Impl.isMemorySSAEnabled()
3330+
? &getAnalysis<MemorySSAWrapperPass>().getMSSA()
3331+
: nullptr);
33173332
}
33183333

33193334
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -3329,7 +3344,8 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
33293344
AU.addPreserved<TargetLibraryInfoWrapperPass>();
33303345
AU.addPreserved<LoopInfoWrapperPass>();
33313346
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
3332-
AU.addPreserved<MemorySSAWrapperPass>();
3347+
if (Impl.isMemorySSAEnabled())
3348+
AU.addRequired<MemorySSAWrapperPass>();
33333349
}
33343350

33353351
private:
@@ -3341,6 +3357,7 @@ char GVNLegacyPass::ID = 0;
33413357
INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
33423358
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
33433359
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
3360+
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
33443361
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
33453362
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
33463363
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
@@ -3349,6 +3366,4 @@ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
33493366
INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
33503367

33513368
// The public interface to this file...
3352-
FunctionPass *llvm::createGVNPass(bool NoMemDepAnalysis) {
3353-
return new GVNLegacyPass(NoMemDepAnalysis);
3354-
}
3369+
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)