Index: llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h =================================================================== --- llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -159,7 +159,6 @@ bool LoopsInterleaved; bool RerollLoops; bool NewGVN; - bool DisableGVNLoadPRE; bool ForgetAllSCEVInLoopUnroll; bool VerifyInput; bool VerifyOutput; Index: llvm/include/llvm/Transforms/Scalar/GVN.h =================================================================== --- llvm/include/llvm/Transforms/Scalar/GVN.h +++ llvm/include/llvm/Transforms/Scalar/GVN.h @@ -76,6 +76,7 @@ Optional AllowLoadInLoopPRE = None; Optional AllowLoadPRESplitBackedge = None; Optional AllowMemDep = None; + Optional AllowMemorySSA = None; GVNOptions() = default; @@ -107,6 +108,12 @@ AllowMemDep = MemDep; return *this; } + + /// Enables or disables use of MemorySSA. + GVNOptions &setMemorySSA(bool MemSSA) { + AllowMemorySSA = MemSSA; + return *this; + } }; /// The core GVN pass object. @@ -143,6 +150,7 @@ bool isLoadInLoopPREEnabled() const; bool isLoadPRESplitBackedgeEnabled() const; bool isMemDepEnabled() const; + bool isMemorySSAEnabled() const; /// This class holds the mapping between values and value numbers. It is used /// as an efficient mechanism to determine the expression-wise equivalence of @@ -367,9 +375,8 @@ void assignBlockRPONumber(Function &F); }; -/// Create a legacy GVN pass. This also allows parameterizing whether or not -/// MemDep is enabled. -FunctionPass *createGVNPass(bool NoMemDepAnalysis = false); +/// Create a legacy GVN pass. +FunctionPass *createGVNPass(); /// A simple and fast domtree-based GVN pass to hoist common expressions /// from sibling branches. Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -821,6 +821,8 @@ Result.setLoadPRESplitBackedge(Enable); } else if (ParamName == "memdep") { Result.setMemDep(Enable); + } else if (ParamName == "memoryssa") { + Result.setMemorySSA(Enable); } else { return make_error( formatv("invalid GVN pass parameter '{0}' ", ParamName).str(), Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -466,7 +466,8 @@ "no-pre;pre;" "no-load-pre;load-pre;" "no-split-backedge-load-pre;split-backedge-load-pre;" - "no-memdep;memdep") + "no-memdep;memdep;" + "no-memoryssa;memoryssa") FUNCTION_PASS_WITH_PARAMS("print", "StackLifetimePrinterPass", [](StackLifetime::LivenessType Type) { Index: llvm/lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -187,7 +187,6 @@ NewGVN = RunNewGVN; LicmMssaOptCap = SetLicmMssaOptCap; LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap; - DisableGVNLoadPRE = false; ForgetAllSCEVInLoopUnroll = ForgetSCEVInLoopUnroll; VerifyInput = false; VerifyOutput = false; @@ -426,7 +425,7 @@ if (OptLevel > 1) { MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds MPM.add(NewGVN ? createNewGVNPass() - : createGVNPass(DisableGVNLoadPRE)); // Remove redundancies + : createGVNPass()); // Remove redundancies } MPM.add(createSCCPPass()); // Constant prop with SCCP @@ -1021,9 +1020,8 @@ PM.add(createLICMPass(LicmMssaOptCap, LicmMssaNoAccForPromotionCap, /*AllowSpeculation=*/true)); - PM.add(NewGVN ? createNewGVNPass() - : createGVNPass(DisableGVNLoadPRE)); // Remove redundancies. - PM.add(createMemCpyOptPass()); // Remove dead memcpys. + PM.add(NewGVN ? createNewGVNPass() : createGVNPass()); // Remove redundancies. + PM.add(createMemCpyOptPass()); // Remove dead memcpys. // Nuke dead stores. PM.add(createDeadStoreEliminationPass()); Index: llvm/lib/Transforms/Scalar/GVN.cpp =================================================================== --- llvm/lib/Transforms/Scalar/GVN.cpp +++ llvm/lib/Transforms/Scalar/GVN.cpp @@ -109,6 +109,7 @@ GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre", cl::init(false)); static cl::opt GVNEnableMemDep("enable-gvn-memdep", cl::init(true)); +static cl::opt GVNEnableMemorySSA("enable-gvn-memoryssa", cl::init(false)); static cl::opt MaxNumDeps( "gvn-max-num-deps", cl::Hidden, cl::init(100), @@ -713,6 +714,10 @@ return Options.AllowMemDep.value_or(GVNEnableMemDep); } +bool GVNPass::isMemorySSAEnabled() const { + return Options.AllowMemorySSA.getValueOr(GVNEnableMemorySSA); +} + PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) { // FIXME: The order of evaluation of these 'getResult' calls is very // significant! Re-ordering these variables will cause GVN when run alone to @@ -725,7 +730,8 @@ auto *MemDep = isMemDepEnabled() ? &AM.getResult(F) : nullptr; auto *LI = AM.getCachedResult(F); - auto *MSSA = AM.getCachedResult(F); + auto *MSSA = + isMemorySSAEnabled() ? &AM.getResult(F) : nullptr; auto &ORE = AM.getResult(F); bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE, MSSA ? &MSSA->getMSSA() : nullptr); @@ -755,7 +761,9 @@ OS << (Options.AllowLoadPRESplitBackedge.getValue() ? "" : "no-") << "split-backedge-load-pre;"; if (Options.AllowMemDep != None) - OS << (Options.AllowMemDep.getValue() ? "" : "no-") << "memdep"; + OS << (Options.AllowMemDep.getValue() ? "" : "no-") << "memdep;"; + if (Options.AllowMemorySSA != None) + OS << (Options.AllowMemorySSA.getValue() ? "" : "no-") << "memoryssa"; OS << ">"; } @@ -3186,8 +3194,11 @@ public: static char ID; // Pass identification, replacement for typeid - explicit GVNLegacyPass(bool NoMemDepAnalysis = !GVNEnableMemDep) - : FunctionPass(ID), Impl(GVNOptions().setMemDep(!NoMemDepAnalysis)) { + explicit GVNLegacyPass(bool MemDepAnalysis = GVNEnableMemDep, + bool MemSSAAnalysis = GVNEnableMemorySSA) + : FunctionPass(ID), Impl(GVNOptions() + .setMemDep(MemDepAnalysis) + .setMemorySSA(MemSSAAnalysis)) { initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry()); } @@ -3218,6 +3229,8 @@ AU.addRequired(); if (Impl.isMemDepEnabled()) AU.addRequired(); + if (Impl.isMemorySSAEnabled()) + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); @@ -3235,6 +3248,7 @@ INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) @@ -3244,6 +3258,4 @@ INITIALIZE_PASS_END(GVNLegacyPass, "gvn", "Global Value Numbering", false, false) // The public interface to this file... -FunctionPass *llvm::createGVNPass(bool NoMemDepAnalysis) { - return new GVNLegacyPass(NoMemDepAnalysis); -} +FunctionPass *llvm::createGVNPass() { return new GVNLegacyPass(); } Index: llvm/test/CodeGen/AMDGPU/llc-pipeline.ll =================================================================== --- llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -9,7 +9,7 @@ ; RUN: | grep -v 'Verify generated machine code' | FileCheck -match-full-lines -strict-whitespace -check-prefix=GCN-O1-OPTS %s ; RUN: llc -O2 -mtriple=amdgcn--amdhsa -disable-verify -debug-pass=Structure < %s 2>&1 \ ; RUN: | grep -v 'Verify generated machine code' | FileCheck -match-full-lines -strict-whitespace -check-prefix=GCN-O2 %s -; RUN: llc -O3 -mtriple=amdgcn--amdhsa -disable-verify -debug-pass=Structure < %s 2>&1 \ +; RUN: llc -O3 -mtriple=amdgcn--amdhsa -disable-verify -debug-pass=Structure -enable-gvn-memoryssa=false < %s 2>&1 \ ; RUN: | grep -v 'Verify generated machine code' | FileCheck -match-full-lines -strict-whitespace -check-prefix=GCN-O3 %s ; REQUIRES: asserts Index: llvm/test/Other/new-pm-print-pipeline.ll =================================================================== --- llvm/test/Other/new-pm-print-pipeline.ll +++ llvm/test/Other/new-pm-print-pipeline.ll @@ -34,8 +34,8 @@ ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-unroll<>,loop-unroll,loop-unroll)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-10 ; CHECK-10: function(loop-unroll,loop-unroll,loop-unroll) -; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(gvn<>,gvn,gvn)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-11 -; CHECK-11: function(gvn<>,gvn,gvn) +; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(gvn<>,gvn,gvn)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-11 +; CHECK-11: function(gvn<>,gvn,gvn) ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(early-cse<>,early-cse)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-12 ; CHECK-12: function(early-cse<>,early-cse)