Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions llvm/include/llvm/Transforms/Scalar/GVN.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct GVNOptions {
std::optional<bool> AllowLoadInLoopPRE;
std::optional<bool> AllowLoadPRESplitBackedge;
std::optional<bool> AllowMemDep;
std::optional<bool> AllowMemorySSA;

GVNOptions() = default;

Expand Down Expand Up @@ -108,6 +109,12 @@ struct GVNOptions {
AllowMemDep = MemDep;
return *this;
}

/// Enables or disables use of MemorySSA.
GVNOptions &setMemorySSA(bool MemSSA) {
AllowMemorySSA = MemSSA;
return *this;
}
};

/// The core GVN pass object.
Expand Down Expand Up @@ -144,6 +151,7 @@ class GVNPass : public PassInfoMixin<GVNPass> {
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
Expand Down Expand Up @@ -383,9 +391,8 @@ class GVNPass : public PassInfoMixin<GVNPass> {
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.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ Expected<GVNOptions> parseGVNOptions(StringRef Params) {
Result.setLoadPRESplitBackedge(Enable);
} else if (ParamName == "memdep") {
Result.setMemDep(Enable);
} else if (ParamName == "memoryssa") {
Result.setMemorySSA(Enable);
} else {
return make_error<StringError>(
formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ FUNCTION_PASS_WITH_PARAMS(
"gvn", "GVNPass", [](GVNOptions Opts) { return GVNPass(Opts); },
parseGVNOptions,
"no-pre;pre;no-load-pre;load-pre;no-split-backedge-load-pre;"
"split-backedge-load-pre;no-memdep;memdep")
"split-backedge-load-pre;no-memdep;memdep;no-memoryssa;memoryssa")
FUNCTION_PASS_WITH_PARAMS(
"hardware-loops", "HardwareLoopsPass",
[](HardwareLoopOptions Opts) { return HardwareLoopsPass(Opts); },
Expand Down
35 changes: 25 additions & 10 deletions llvm/lib/Transforms/Scalar/GVN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ static cl::opt<bool>
GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre",
cl::init(false));
static cl::opt<bool> GVNEnableMemDep("enable-gvn-memdep", cl::init(true));
static cl::opt<bool> GVNEnableMemorySSA("enable-gvn-memoryssa",
cl::init(false));

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

bool GVNPass::isMemorySSAEnabled() const {
return Options.AllowMemorySSA.value_or(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
Expand All @@ -832,7 +838,10 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
auto *MemDep =
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
auto &LI = AM.getResult<LoopAnalysis>(F);
auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
auto *MSSA =
isMemorySSAEnabled() ? &AM.getResult<MemorySSAAnalysis>(F) : nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change here means that we no longer try to update and preserve an already computed MSSA instance. I've reverted this patch for now.

assert(!(MemDep && MSSA) &&
"Should not use both MemDep and MemorySSA simultaneously!");
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
MSSA ? &MSSA->getMSSA() : nullptr);
Expand Down Expand Up @@ -861,7 +870,9 @@ void GVNPass::printPipeline(
OS << (*Options.AllowLoadPRESplitBackedge ? "" : "no-")
<< "split-backedge-load-pre;";
if (Options.AllowMemDep != std::nullopt)
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep";
OS << (*Options.AllowMemDep ? "" : "no-") << "memdep;";
if (Options.AllowMemorySSA != std::nullopt)
OS << (*Options.AllowMemorySSA ? "" : "no-") << "memoryssa";
OS << '>';
}

Expand Down Expand Up @@ -3293,16 +3304,18 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
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());
}

bool runOnFunction(Function &F) override {
if (skipFunction(F))
return false;

auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
return Impl.runImpl(
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
Expand All @@ -3313,7 +3326,9 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
: nullptr,
getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
MSSAWP ? &MSSAWP->getMSSA() : nullptr);
Impl.isMemorySSAEnabled()
? &getAnalysis<MemorySSAWrapperPass>().getMSSA()
: nullptr);
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
Expand All @@ -3329,7 +3344,8 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
AU.addPreserved<TargetLibraryInfoWrapperPass>();
AU.addPreserved<LoopInfoWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
AU.addPreserved<MemorySSAWrapperPass>();
if (Impl.isMemorySSAEnabled())
AU.addRequired<MemorySSAWrapperPass>();
}

private:
Expand All @@ -3341,6 +3357,7 @@ char GVNLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(GVNLegacyPass, "gvn", "Global Value Numbering", false, false)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
Expand All @@ -3349,6 +3366,4 @@ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
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(); }
4 changes: 2 additions & 2 deletions llvm/test/Other/new-pm-print-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
; 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
; 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>)

; 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
; 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>)
; 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
; 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>)

; 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
; CHECK-12: function(early-cse<>,early-cse<memssa>)
Expand Down
Loading