Skip to content

Commit 3478551

Browse files
author
Fedor Sergeev
committed
[GVN] introduce GVNOptions to control GVN pass behavior
There are a few global (cl::opt) controls that enable optional behavior in GVN. Introduce GVNOptions that provide corresponding per-pass instance controls. That will allow to use GVN multiple times in pipeline each time with different settings. Reviewers: asbirlea, rnk, reames, skatkov, fhahn Reviewed By: fhahn Tags: #llvm Differential Revision: https://reviews.llvm.org/D72732
1 parent 2664676 commit 3478551

File tree

2 files changed

+66
-15
lines changed
  • llvm
    • include/llvm/Transforms/Scalar
    • lib/Transforms/Scalar

2 files changed

+66
-15
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,51 @@ class GVNLegacyPass;
6161

6262
} // end namespace gvn
6363

64+
/// A set of parameters to control various transforms performed by GVN pass.
65+
// Each of the optional boolean parameters can be set to:
66+
/// true - enabling the transformation.
67+
/// false - disabling the transformation.
68+
/// None - relying on a global default.
69+
/// Intended use is to create a default object, modify parameters with
70+
/// additional setters and then pass it to GVN.
71+
struct GVNOptions {
72+
Optional<bool> AllowPRE = None;
73+
Optional<bool> AllowLoadPRE = None;
74+
Optional<bool> AllowMemDep = None;
75+
76+
GVNOptions() = default;
77+
78+
/// Enables or disables PRE in GVN.
79+
GVNOptions &setPRE(bool PRE) {
80+
AllowPRE = PRE;
81+
return *this;
82+
}
83+
84+
/// Enables or disables PRE of loads in GVN.
85+
GVNOptions &setLoadPRE(bool LoadPRE) {
86+
AllowLoadPRE = LoadPRE;
87+
return *this;
88+
}
89+
90+
/// Enables or disables use of MemDepAnalysis.
91+
GVNOptions &setMemDep(bool MemDep) {
92+
AllowMemDep = MemDep;
93+
return *this;
94+
}
95+
};
96+
6497
/// The core GVN pass object.
6598
///
6699
/// FIXME: We should have a good summary of the GVN algorithm implemented by
67100
/// this particular pass here.
68101
class GVN : public PassInfoMixin<GVN> {
102+
GVNOptions Options;
103+
69104
public:
70105
struct Expression;
71106

107+
GVN(GVNOptions Options = {}) : Options(Options) {}
108+
72109
/// Run the pass over the function.
73110
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
74111

@@ -83,6 +120,10 @@ class GVN : public PassInfoMixin<GVN> {
83120
AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
84121
MemoryDependenceResults &getMemDep() const { return *MD; }
85122

123+
bool isPREEnabled() const;
124+
bool isLoadPREEnabled() const;
125+
bool isMemDepEnabled() const;
126+
86127
/// This class holds the mapping between values and value numbers. It is used
87128
/// as an efficient mechanism to determine the expression-wise equivalence of
88129
/// two values.

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,9 @@ STATISTIC(NumGVNSimpl, "Number of instructions simplified");
9797
STATISTIC(NumGVNEqProp, "Number of equalities propagated");
9898
STATISTIC(NumPRELoad, "Number of loads PRE'd");
9999

100-
static cl::opt<bool> EnablePRE("enable-pre",
101-
cl::init(true), cl::Hidden);
102-
static cl::opt<bool> EnableLoadPRE("enable-load-pre", cl::init(true));
103-
static cl::opt<bool> EnableMemDep("enable-gvn-memdep", cl::init(true));
100+
static cl::opt<bool> GVNEnablePRE("enable-pre", cl::init(true), cl::Hidden);
101+
static cl::opt<bool> GVNEnableLoadPRE("enable-load-pre", cl::init(true));
102+
static cl::opt<bool> GVNEnableMemDep("enable-gvn-memdep", cl::init(true));
104103

105104
// Maximum allowed recursion depth.
106105
static cl::opt<uint32_t>
@@ -610,6 +609,17 @@ void GVN::ValueTable::verifyRemoved(const Value *V) const {
610609
// GVN Pass
611610
//===----------------------------------------------------------------------===//
612611

612+
bool GVN::isPREEnabled() const {
613+
return Options.AllowPRE.getValueOr(GVNEnablePRE);
614+
}
615+
616+
bool GVN::isLoadPREEnabled() const {
617+
return Options.AllowLoadPRE.getValueOr(GVNEnableLoadPRE);
618+
}
619+
bool GVN::isMemDepEnabled() const {
620+
return Options.AllowMemDep.getValueOr(GVNEnableMemDep);
621+
}
622+
613623
PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
614624
// FIXME: The order of evaluation of these 'getResult' calls is very
615625
// significant! Re-ordering these variables will cause GVN when run alone to
@@ -619,10 +629,11 @@ PreservedAnalyses GVN::run(Function &F, FunctionAnalysisManager &AM) {
619629
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
620630
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
621631
auto &AA = AM.getResult<AAManager>(F);
622-
auto &MemDep = AM.getResult<MemoryDependenceAnalysis>(F);
632+
auto *MemDep =
633+
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
623634
auto *LI = AM.getCachedResult<LoopAnalysis>(F);
624635
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
625-
bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI, &ORE);
636+
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE);
626637
if (!Changed)
627638
return PreservedAnalyses::all();
628639
PreservedAnalyses PA;
@@ -1383,7 +1394,7 @@ bool GVN::processNonLocalLoad(LoadInst *LI) {
13831394
}
13841395

13851396
// Step 4: Eliminate partial redundancy.
1386-
if (!EnablePRE || !EnableLoadPRE)
1397+
if (!isPREEnabled() || !isLoadPREEnabled())
13871398
return false;
13881399

13891400
return PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks);
@@ -2148,7 +2159,7 @@ bool GVN::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
21482159
++Iteration;
21492160
}
21502161

2151-
if (EnablePRE) {
2162+
if (isPREEnabled()) {
21522163
// Fabricate val-num for dead-code in order to suppress assertion in
21532164
// performPRE().
21542165
assignValNumForDeadCode();
@@ -2682,8 +2693,8 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
26822693
public:
26832694
static char ID; // Pass identification, replacement for typeid
26842695

2685-
explicit GVNLegacyPass(bool NoMemDepAnalysis = !EnableMemDep)
2686-
: FunctionPass(ID), NoMemDepAnalysis(NoMemDepAnalysis) {
2696+
explicit GVNLegacyPass(bool NoMemDepAnalysis = !GVNEnableMemDep)
2697+
: FunctionPass(ID), Impl(GVNOptions().setMemDep(!NoMemDepAnalysis)) {
26872698
initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry());
26882699
}
26892700

@@ -2698,9 +2709,9 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
26982709
getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
26992710
getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F),
27002711
getAnalysis<AAResultsWrapperPass>().getAAResults(),
2701-
NoMemDepAnalysis
2702-
? nullptr
2703-
: &getAnalysis<MemoryDependenceWrapperPass>().getMemDep(),
2712+
Impl.isMemDepEnabled()
2713+
? &getAnalysis<MemoryDependenceWrapperPass>().getMemDep()
2714+
: nullptr,
27042715
LIWP ? &LIWP->getLoopInfo() : nullptr,
27052716
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE());
27062717
}
@@ -2710,7 +2721,7 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
27102721
AU.addRequired<DominatorTreeWrapperPass>();
27112722
AU.addRequired<TargetLibraryInfoWrapperPass>();
27122723
AU.addRequired<LoopInfoWrapperPass>();
2713-
if (!NoMemDepAnalysis)
2724+
if (Impl.isMemDepEnabled())
27142725
AU.addRequired<MemoryDependenceWrapperPass>();
27152726
AU.addRequired<AAResultsWrapperPass>();
27162727

@@ -2723,7 +2734,6 @@ class llvm::gvn::GVNLegacyPass : public FunctionPass {
27232734
}
27242735

27252736
private:
2726-
bool NoMemDepAnalysis;
27272737
GVN Impl;
27282738
};
27292739

0 commit comments

Comments
 (0)