diff --git a/llvm/include/llvm/Transforms/Scalar/GVN.h b/llvm/include/llvm/Transforms/Scalar/GVN.h --- a/llvm/include/llvm/Transforms/Scalar/GVN.h +++ b/llvm/include/llvm/Transforms/Scalar/GVN.h @@ -61,14 +61,51 @@ } // end namespace gvn +/// A set of parameters to control various transforms performed by GVN pass. +// Each of the optional boolean parameters can be set to: +/// true - enabling the transformation. +/// false - disabling the transformation. +/// None - relying on a global default. +/// Intended use is to create a default object, modify parameters with +/// additional setters and then pass it to GVN. +struct GVNOptions { + Optional AllowPRE = None; + Optional AllowLoadPRE = None; + Optional AllowMemDep = None; + + GVNOptions() = default; + + /// Enables or disables PRE in GVN. + GVNOptions &setPRE(bool PRE) { + AllowPRE = PRE; + return *this; + } + + /// Enables or disables PRE of loads in GVN. + GVNOptions &setLoadPRE(bool LoadPRE) { + AllowLoadPRE = LoadPRE; + return *this; + } + + /// Enables or disables PRE of loads in GVN. + GVNOptions &setMemDep(bool MemDep) { + AllowMemDep = MemDep; + return *this; + } +}; + /// The core GVN pass object. /// /// FIXME: We should have a good summary of the GVN algorithm implemented by /// this particular pass here. class GVN : public PassInfoMixin { + GVNOptions Options; + public: struct Expression; + GVN(GVNOptions Options = {}) : Options(Options) {} + /// Run the pass over the function. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); @@ -83,6 +120,10 @@ AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); } MemoryDependenceResults &getMemDep() const { return *MD; } + bool isPREEnabled() const; + bool isLoadPREEnabled() const; + bool isMemDepEnabled() 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 /// two values. diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -97,10 +97,9 @@ STATISTIC(NumGVNEqProp, "Number of equalities propagated"); STATISTIC(NumPRELoad, "Number of loads PRE'd"); -static cl::opt EnablePRE("enable-pre", - cl::init(true), cl::Hidden); -static cl::opt EnableLoadPRE("enable-load-pre", cl::init(true)); -static cl::opt EnableMemDep("enable-gvn-memdep", cl::init(true)); +static cl::opt GVNEnablePRE("enable-pre", cl::init(true), cl::Hidden); +static cl::opt GVNEnableLoadPRE("enable-load-pre", cl::init(true)); +static cl::opt GVNEnableMemDep("enable-gvn-memdep", cl::init(true)); // Maximum allowed recursion depth. static cl::opt @@ -610,6 +609,17 @@ // GVN Pass //===----------------------------------------------------------------------===// +bool GVN::isPREEnabled() const { + return Options.AllowPRE.getValueOr(GVNEnablePRE); +} + +bool GVN::isLoadPREEnabled() const { + return Options.AllowLoadPRE.getValueOr(GVNEnableLoadPRE); +} +bool GVN::isMemDepEnabled() const { + return Options.AllowMemDep.getValueOr(GVNEnableMemDep); +} + PreservedAnalyses GVN::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 @@ -622,7 +632,8 @@ auto &MemDep = AM.getResult(F); auto *LI = AM.getCachedResult(F); auto &ORE = AM.getResult(F); - bool Changed = runImpl(F, AC, DT, TLI, AA, &MemDep, LI, &ORE); + bool Changed = runImpl(F, AC, DT, TLI, AA, + isMemDepEnabled() ? &MemDep : nullptr, LI, &ORE); if (!Changed) return PreservedAnalyses::all(); PreservedAnalyses PA; @@ -1383,7 +1394,7 @@ } // Step 4: Eliminate partial redundancy. - if (!EnablePRE || !EnableLoadPRE) + if (!isPREEnabled() || !isLoadPREEnabled()) return false; return PerformLoadPRE(LI, ValuesPerBlock, UnavailableBlocks); @@ -2148,7 +2159,7 @@ ++Iteration; } - if (EnablePRE) { + if (isPREEnabled()) { // Fabricate val-num for dead-code in order to suppress assertion in // performPRE(). assignValNumForDeadCode(); @@ -2682,8 +2693,9 @@ public: static char ID; // Pass identification, replacement for typeid - explicit GVNLegacyPass(bool NoMemDepAnalysis = !EnableMemDep) - : FunctionPass(ID), NoMemDepAnalysis(NoMemDepAnalysis) { + explicit GVNLegacyPass(bool NoMemDepAnalysis = !GVNEnableMemDep) + : FunctionPass(ID), NoMemDepAnalysis(NoMemDepAnalysis), + Impl(GVNOptions().setMemDep(!NoMemDepAnalysis)) { initializeGVNLegacyPassPass(*PassRegistry::getPassRegistry()); }