[Mlir-commits] [mlir] 9a277af - [mlir][Pass] Add support for generating pass utilities via tablegen

River Riddle llvmlistbot at llvm.org
Wed Apr 1 02:12:18 PDT 2020


Author: River Riddle
Date: 2020-04-01T02:10:46-07:00
New Revision: 9a277af2d429e1d53f65417400583d5ea66d3ed1

URL: https://github.com/llvm/llvm-project/commit/9a277af2d429e1d53f65417400583d5ea66d3ed1
DIFF: https://github.com/llvm/llvm-project/commit/9a277af2d429e1d53f65417400583d5ea66d3ed1.diff

LOG: [mlir][Pass] Add support for generating pass utilities via tablegen

This revision adds support for generating utilities for passes such as options/statistics/etc. that can be inferred from the tablegen definition. This removes additional boilerplate from the pass, and also makes it easier to remove the reliance on the pass registry to provide certain things(e.g. the pass argument).

Differential Revision: https://reviews.llvm.org/D76659

Added: 
    

Modified: 
    mlir/include/mlir/Conversion/Passes.td
    mlir/include/mlir/Dialect/Affine/Passes.td
    mlir/include/mlir/Dialect/Linalg/Passes.td
    mlir/include/mlir/Dialect/LoopOps/Passes.td
    mlir/include/mlir/Pass/PassBase.td
    mlir/include/mlir/TableGen/Pass.h
    mlir/include/mlir/Transforms/Passes.td
    mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp
    mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp
    mlir/lib/Conversion/GPUToCUDA/ConvertLaunchFuncToCudaCalls.cpp
    mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp
    mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp
    mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
    mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
    mlir/lib/Conversion/GPUToVulkan/ConvertLaunchFuncToVulkanCalls.cpp
    mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
    mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
    mlir/lib/Conversion/LoopToStandard/LoopToStandard.cpp
    mlir/lib/Conversion/LoopsToGPU/LoopsToGPUPass.cpp
    mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
    mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp
    mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp
    mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
    mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp
    mlir/lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp
    mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
    mlir/lib/Dialect/Affine/Transforms/LoopUnroll.cpp
    mlir/lib/Dialect/Affine/Transforms/LoopUnrollAndJam.cpp
    mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
    mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
    mlir/lib/Dialect/FxpMathOps/Transforms/LowerUniformRealMath.cpp
    mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
    mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp
    mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
    mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp
    mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
    mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
    mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopFusion.cpp
    mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopSpecialization.cpp
    mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopTiling.cpp
    mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp
    mlir/lib/Dialect/Quant/Transforms/ConvertSimQuant.cpp
    mlir/lib/Quantizer/Transforms/AddDefaultStatsTestPass.cpp
    mlir/lib/Quantizer/Transforms/InferQuantizedTypesPass.cpp
    mlir/lib/Quantizer/Transforms/RemoveInstrumentationPass.cpp
    mlir/lib/TableGen/Pass.cpp
    mlir/lib/Transforms/CSE.cpp
    mlir/lib/Transforms/Canonicalizer.cpp
    mlir/lib/Transforms/Inliner.cpp
    mlir/lib/Transforms/LocationSnapshot.cpp
    mlir/lib/Transforms/LoopCoalescing.cpp
    mlir/lib/Transforms/LoopFusion.cpp
    mlir/lib/Transforms/LoopInvariantCodeMotion.cpp
    mlir/lib/Transforms/MemRefDataFlowOpt.cpp
    mlir/lib/Transforms/OpStats.cpp
    mlir/lib/Transforms/ParallelLoopCollapsing.cpp
    mlir/lib/Transforms/PipelineDataTransfer.cpp
    mlir/lib/Transforms/StripDebugInfo.cpp
    mlir/lib/Transforms/SymbolDCE.cpp
    mlir/lib/Transforms/ViewOpGraph.cpp
    mlir/lib/Transforms/ViewRegionGraph.cpp
    mlir/tools/mlir-tblgen/PassGen.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 30e1a836f4eb..3cbdc03c0cbd 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -119,11 +119,25 @@ def ConvertLoopToStandard : Pass<"convert-loop-to-std"> {
 def ConvertSimpleLoopsToGPU : Pass<"convert-loops-to-gpu"> {
   let summary = "Convert top-level loops to GPU kernels";
   let constructor = "mlir::createSimpleLoopsToGPUPass()";
+  let options = [
+    Option<"numBlockDims", "gpu-block-dims", "unsigned", /*default=*/"1u",
+           "Number of GPU block dimensions for mapping">,
+    Option<"numThreadDims", "gpu-thread-dims", "unsigned", /*default=*/"1u",
+           "Number of GPU thread dimensions for mapping">
+  ];
 }
 
 def ConvertLoopsToGPU : Pass<"convert-loop-op-to-gpu"> {
   let summary = "Convert top-level loop::ForOp to GPU kernels";
   let constructor = "mlir::createLoopToGPUPass()";
+  let options = [
+    ListOption<"numWorkGroups", "gpu-num-workgroups", "int64_t",
+               "Num workgroups in the GPU launch",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">,
+    ListOption<"workGroupSize", "gpu-workgroup-size", "int64_t",
+               "Workgroup Size in the GPU launch",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
 }
 
 def ConvertParallelLoopToGpu : Pass<"convert-parallel-loops-to-gpu"> {
@@ -139,6 +153,20 @@ def ConvertStandardToLLVM : Pass<"convert-std-to-llvm"> {
   let summary = "Convert scalar and vector operations from the Standard to the "
                 "LLVM dialect";
   let constructor = "mlir::createLowerToLLVMPass()";
+  let options = [
+    Option<"useAlloca", "use-alloca", "bool", /*default=*/"false",
+           "Use `alloca` instead of `call @malloc` for converting std.alloc">,
+    Option<"useBarePtrCallConv", "use-bare-ptr-memref-call-conv", "bool",
+           /*default=*/"false",
+           "Replace FuncOp's MemRef arguments with bare pointers to the MemRef "
+           "element types">,
+    Option<"emitCWrappers", "emit-c-wrappers", "bool", /*default=*/"false",
+           "Emit wrappers for C-compatible pointer-to-struct memref "
+           "descriptors">,
+    Option<"indexBitwidth", "index-bitwidth", "unsigned",
+           /*default=*/"kDeriveIndexBitwidthFromDataLayout",
+           "Bitwidth of the index type, 0 to use size of machine word">,
+  ];
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/Dialect/Affine/Passes.td b/mlir/include/mlir/Dialect/Affine/Passes.td
index 5832e4200a44..4ae53571d1f4 100644
--- a/mlir/include/mlir/Dialect/Affine/Passes.td
+++ b/mlir/include/mlir/Dialect/Affine/Passes.td
@@ -43,6 +43,22 @@ def AffineLoopUnrollAndJam : Pass<"affine-loop-unroll-jam"> {
 def AffineVectorize : Pass<"affine-super-vectorize"> {
   let summary = "Vectorize to a target independent n-D vector abstraction";
   let constructor = "mlir::createSuperVectorizePass()";
+  let options = [
+    ListOption<"vectorSizes", "virtual-vector-size", "int64_t",
+               "Specify an n-D virtual vector size for vectorization",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">,
+    // Optionally, the fixed mapping from loop to fastest varying MemRef
+    // dimension for all the MemRefs within a loop pattern:
+    //   the index represents the loop depth, the value represents the k^th
+    //   fastest varying memory dimension.
+    // This is voluntarily restrictive and is meant to precisely target a
+    // particular loop/op pair, for testing purposes.
+    ListOption<"fastestVaryingPattern", "test-fastest-varying", "int64_t",
+               "Specify a 1-D, 2-D or 3-D pattern of fastest varying memory "
+               "dimensions to match. See defaultPatterns in Vectorize.cpp for "
+               "a description and examples. This is used for testing purposes",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
 }
 
 def SimplifyAffineStructures : Pass<"simplify-affine-structures"> {

diff  --git a/mlir/include/mlir/Dialect/Linalg/Passes.td b/mlir/include/mlir/Dialect/Linalg/Passes.td
index 8e7ebbe385d3..210ad1092c66 100644
--- a/mlir/include/mlir/Dialect/Linalg/Passes.td
+++ b/mlir/include/mlir/Dialect/Linalg/Passes.td
@@ -41,16 +41,30 @@ def LinalgLowerToParallelLoops : Pass<"convert-linalg-to-parallel-loops"> {
 def LinalgPromotion : Pass<"linalg-promote-subviews"> {
   let summary = "Promote subview ops to local buffers";
   let constructor = "mlir::createLinalgPromotionPass()";
+  let options = [
+    Option<"dynamicBuffers", "test-promote-dynamic", "bool",
+           /*default=*/"false", "Test generation of dynamic promoted buffers">
+  ];
 }
 
 def LinalgTiling : Pass<"linalg-tile"> {
   let summary = "Tile operations in the linalg dialect";
   let constructor = "mlir::createLinalgTilingPass()";
+  let options = [
+    ListOption<"tileSizes", "linalg-tile-sizes", "int64_t",
+               "Test generation of dynamic promoted buffers",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
 }
 
 def LinalgTilingToParallelLoops : Pass<"linalg-tile-to-parallel-loops"> {
   let summary = "Tile operations in the linalg dialect to parallel loops";
   let constructor = "mlir::createLinalgTilingToParallelLoopsPass()";
+  let options = [
+    ListOption<"tileSizes", "linalg-tile-sizes", "int64_t",
+               "Test generation of dynamic promoted buffers",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
 }
 
 #endif // MLIR_DIALECT_LINALG_PASSES

diff  --git a/mlir/include/mlir/Dialect/LoopOps/Passes.td b/mlir/include/mlir/Dialect/LoopOps/Passes.td
index 7d984afd8ea8..444dcfe22201 100644
--- a/mlir/include/mlir/Dialect/LoopOps/Passes.td
+++ b/mlir/include/mlir/Dialect/LoopOps/Passes.td
@@ -24,6 +24,11 @@ def LoopParallelLoopSpecialization : Pass<"parallel-loop-specialization"> {
 def LoopParallelLoopTiling : Pass<"parallel-loop-tiling"> {
   let summary = "Tile parallel loops";
   let constructor = "mlir::createParallelLoopTilingPass()";
+  let options = [
+    ListOption<"tileSizes", "parallel-loop-tile-sizes", "int64_t",
+               "Factors to tile parallel loops by",
+               "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
 }
 
 #endif // MLIR_DIALECT_LOOP_PASSES

diff  --git a/mlir/include/mlir/Pass/PassBase.td b/mlir/include/mlir/Pass/PassBase.td
index 9929d6b07ae7..29478047f757 100644
--- a/mlir/include/mlir/Pass/PassBase.td
+++ b/mlir/include/mlir/Pass/PassBase.td
@@ -14,6 +14,50 @@
 #ifndef MLIR_PASS_PASSBASE
 #define MLIR_PASS_PASSBASE
 
+//===----------------------------------------------------------------------===//
+// Options
+//===----------------------------------------------------------------------===//
+
+class Option<string varName, string arg, string valueType, string default,
+             string desc, string additionalFlags = ""> {
+  // The name for the C++ option variable.
+  string cppName = varName;
+
+  // The command line argument to use for this option.
+  string argument = arg;
+
+  // The C++ type of the option.
+  string type = valueType;
+
+  // The default value of the option. "" corresponds to no default.
+  string defaultValue = default;
+
+  // A description for this option.
+  string description = desc;
+
+  // A set of additional flags to pass along to the option constructor.
+  string additionalOptFlags = additionalFlags;
+}
+
+class ListOption<string varName, string arg, string valueType,
+                 string desc, string additionalFlags = "">
+  : Option<varName, arg, valueType, /*default=*/"", desc, additionalFlags> {}
+
+//===----------------------------------------------------------------------===//
+// Statistics
+//===----------------------------------------------------------------------===//
+
+class Statistic<string varName, string statName, string desc> {
+  // The C++ variable name for the statistic.
+  string cppName = varName;
+
+  // The displayed name of the statistic, similar to the argument of an option.
+  string name = statName;
+
+  // The description of the statistic.
+  string description = desc;
+}
+
 //===----------------------------------------------------------------------===//
 // Pass
 //===----------------------------------------------------------------------===//
@@ -30,6 +74,12 @@ class Pass<string passArg> {
 
   // A C++ constructor call to create an instance of this pass.
   code constructor = [{}];
+
+  // A set of options provided by this pass.
+  list<Option> options = [];
+
+  // A set of statistics provided by this pass.
+  list<Statistic> statistics = [];
 }
 
 #endif // MLIR_PASS_PASSBASE

diff  --git a/mlir/include/mlir/TableGen/Pass.h b/mlir/include/mlir/TableGen/Pass.h
index 82615fa7e948..d8b5eaa04313 100644
--- a/mlir/include/mlir/TableGen/Pass.h
+++ b/mlir/include/mlir/TableGen/Pass.h
@@ -18,6 +18,58 @@ class Record;
 
 namespace mlir {
 namespace tblgen {
+//===----------------------------------------------------------------------===//
+// PassOption
+//===----------------------------------------------------------------------===//
+class PassOption {
+public:
+  explicit PassOption(const llvm::Record *def) : def(def) {}
+
+  /// Return the name for the C++ option variable.
+  StringRef getCppVariableName() const;
+
+  /// Return the command line argument to use for this option.
+  StringRef getArgument() const;
+
+  /// Return the C++ type of the option.
+  StringRef getType() const;
+
+  /// Return the default value of the option.
+  Optional<StringRef> getDefaultValue() const;
+
+  /// Return the description for this option.
+  StringRef getDescription() const;
+
+  /// Return the additional flags passed to the option constructor.
+  Optional<StringRef> getAdditionalFlags() const;
+
+  /// Flag indicating if this is a list option.
+  bool isListOption() const;
+
+private:
+  const llvm::Record *def;
+};
+
+//===----------------------------------------------------------------------===//
+// PassStatistic
+//===----------------------------------------------------------------------===//
+class PassStatistic {
+public:
+  explicit PassStatistic(const llvm::Record *def) : def(def) {}
+
+  /// Return the name for the C++ statistic variable.
+  StringRef getCppVariableName() const;
+
+  /// Return the name of the statistic.
+  StringRef getName() const;
+
+  /// Return the description for this statistic.
+  StringRef getDescription() const;
+
+private:
+  const llvm::Record *def;
+};
+
 //===----------------------------------------------------------------------===//
 // Pass
 //===----------------------------------------------------------------------===//
@@ -39,8 +91,18 @@ class Pass {
   /// Return the C++ constructor call to create an instance of this pass.
   StringRef getConstructor() const;
 
+  /// Return the options provided by this pass.
+  ArrayRef<PassOption> getOptions() const;
+
+  /// Return the statistics provided by this pass.
+  ArrayRef<PassStatistic> getStatistics() const;
+
+  const llvm::Record *getDef() const { return def; }
+
 private:
   const llvm::Record *def;
+  std::vector<PassOption> options;
+  std::vector<PassStatistic> statistics;
 };
 
 } // end namespace tblgen

diff  --git a/mlir/include/mlir/Transforms/Passes.td b/mlir/include/mlir/Transforms/Passes.td
index 077863ec0b7d..625decb4de47 100644
--- a/mlir/include/mlir/Transforms/Passes.td
+++ b/mlir/include/mlir/Transforms/Passes.td
@@ -35,6 +35,10 @@ def Canonicalizer : Pass<"canonicalize"> {
 def CSE : Pass<"cse"> {
   let summary = "Eliminate common sub-expressions";
   let constructor = "mlir::createCSEPass()";
+  let statistics = [
+    Statistic<"numCSE", "num-cse'd", "Number of operations CSE'd">,
+    Statistic<"numDCE", "num-dce'd", "Number of operations DCE'd">
+  ];
 }
 
 def Inliner : Pass<"inline"> {
@@ -45,6 +49,13 @@ def Inliner : Pass<"inline"> {
 def LocationSnapshot : Pass<"snapshot-op-locations"> {
   let summary = "Generate new locations from the current IR";
   let constructor = "mlir::createLocationSnapshotPass()";
+  let options = [
+    Option<"fileName", "filename", "std::string", /*default=*/"",
+           "The filename to print the generated IR.">,
+    Option<"tag", "tag", "std::string", /*default=*/"",
+           "A tag to use when fusing the new locations with the "
+           "original. If unset, the locations are replaced.">,
+  ];
 }
 
 def LoopCoalescing : Pass<"loop-coalescing"> {
@@ -66,6 +77,17 @@ def MemRefDataFlowOpt : Pass<"memref-dataflow-opt"> {
 def ParallelLoopCollapsing : Pass<"parallel-loop-collapsing"> {
   let summary = "Collapse parallel loops to use less induction variables";
   let constructor = "mlir::createParallelLoopCollapsingPass()";
+  let options = [
+    ListOption<"clCollapsedIndices0", "collapsed-indices-0", "unsigned",
+               "Which loop indices to combine 0th loop index",
+               "llvm::cl::MiscFlags::CommaSeparated">,
+    ListOption<"clCollapsedIndices1", "collapsed-indices-1", "unsigned",
+               "Which loop indices to combine into the position 1 loop index",
+               "llvm::cl::MiscFlags::CommaSeparated">,
+    ListOption<"clCollapsedIndices2", "collapsed-indices-2", "unsigned",
+               "Which loop indices to combine into the position 2 loop index",
+               "llvm::cl::MiscFlags::CommaSeparated">,
+  ];
 }
 
 def PrintCFG : Pass<"print-cfg-graph"> {

diff  --git a/mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp b/mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp
index 59e2b21d76fc..91f3cc933a02 100644
--- a/mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp
+++ b/mlir/lib/Conversion/AVX512ToLLVM/ConvertAVX512ToLLVM.cpp
@@ -164,6 +164,10 @@ void mlir::populateAVX512ToLLVMConversionPatterns(
 
 namespace {
 struct ConvertAVX512ToLLVMPass : public ModulePass<ConvertAVX512ToLLVMPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertAVX512ToLLVM
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp b/mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp
index d7685c87934c..56928da2c633 100644
--- a/mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp
+++ b/mlir/lib/Conversion/AffineToStandard/AffineToStandard.cpp
@@ -578,6 +578,10 @@ void mlir::populateAffineToStdConversionPatterns(
 
 namespace {
 class LowerAffinePass : public FunctionPass<LowerAffinePass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertAffineToStandard
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnFunction() override {
     OwningRewritePatternList patterns;
     populateAffineToStdConversionPatterns(patterns, &getContext());

diff  --git a/mlir/lib/Conversion/GPUToCUDA/ConvertLaunchFuncToCudaCalls.cpp b/mlir/lib/Conversion/GPUToCUDA/ConvertLaunchFuncToCudaCalls.cpp
index 0677ed65d059..38c092a2eaf0 100644
--- a/mlir/lib/Conversion/GPUToCUDA/ConvertLaunchFuncToCudaCalls.cpp
+++ b/mlir/lib/Conversion/GPUToCUDA/ConvertLaunchFuncToCudaCalls.cpp
@@ -63,6 +63,10 @@ namespace {
 class GpuLaunchFuncToCudaCallsPass
     : public ModulePass<GpuLaunchFuncToCudaCallsPass> {
 private:
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertGpuLaunchFuncToCudaCalls
+#include "mlir/Conversion/Passes.h.inc"
+
   LLVM::LLVMDialect *getLLVMDialect() { return llvmDialect; }
 
   llvm::LLVMContext &getLLVMContext() {

diff  --git a/mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp b/mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp
index 12903f57ef27..d8297c76ba9a 100644
--- a/mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp
+++ b/mlir/lib/Conversion/GPUToNVVM/LowerGpuOpsToNVVMOps.cpp
@@ -248,6 +248,10 @@ struct GPUReturnOpLowering : public ConvertToLLVMPattern {
 class LowerGpuOpsToNVVMOpsPass
     : public OperationPass<LowerGpuOpsToNVVMOpsPass, gpu::GPUModuleOp> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertGpuOpsToNVVMOps
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnOperation() override {
     gpu::GPUModuleOp m = getOperation();
 

diff  --git a/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp b/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp
index 0be69cca41ed..b89a1704e9f5 100644
--- a/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp
+++ b/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp
@@ -34,6 +34,10 @@ namespace {
 class LowerGpuOpsToROCDLOpsPass
     : public OperationPass<LowerGpuOpsToROCDLOpsPass, gpu::GPUModuleOp> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertGpuOpsToROCDLOps
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnOperation() override {
     gpu::GPUModuleOp m = getOperation();
 

diff  --git a/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp b/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
index d8262249c32f..1102ef182c5f 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
@@ -34,6 +34,10 @@ namespace {
 ///
 /// 2) Lower the body of the spirv::ModuleOp.
 struct GPUToSPIRVPass : public ModulePass<GPUToSPIRVPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertGpuToSPIRV
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp b/mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
index b025da9ff133..415df03e620f 100644
--- a/mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
+++ b/mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
@@ -40,6 +40,10 @@ namespace {
 class ConvertGpuLaunchFuncToVulkanLaunchFunc
     : public ModulePass<ConvertGpuLaunchFuncToVulkanLaunchFunc> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertGpuLaunchFuncToVulkanLaunchFunc
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 
 private:

diff  --git a/mlir/lib/Conversion/GPUToVulkan/ConvertLaunchFuncToVulkanCalls.cpp b/mlir/lib/Conversion/GPUToVulkan/ConvertLaunchFuncToVulkanCalls.cpp
index 76ad84d440b8..3b5ca17c5f1e 100644
--- a/mlir/lib/Conversion/GPUToVulkan/ConvertLaunchFuncToVulkanCalls.cpp
+++ b/mlir/lib/Conversion/GPUToVulkan/ConvertLaunchFuncToVulkanCalls.cpp
@@ -59,6 +59,10 @@ namespace {
 class VulkanLaunchFuncToVulkanCallsPass
     : public ModulePass<VulkanLaunchFuncToVulkanCallsPass> {
 private:
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertVulkanLaunchFuncToVulkanCalls
+#include "mlir/Conversion/Passes.h.inc"
+
   LLVM::LLVMDialect *getLLVMDialect() { return llvmDialect; }
 
   llvm::LLVMContext &getLLVMContext() {

diff  --git a/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp b/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
index 8baf278c8e55..febf4eb74a44 100644
--- a/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
+++ b/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
@@ -557,6 +557,10 @@ void mlir::populateLinalgToLLVMConversionPatterns(
 
 namespace {
 struct ConvertLinalgToLLVMPass : public ModulePass<ConvertLinalgToLLVMPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertLinalgToLLVM
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp b/mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
index ebac1f9418c6..0962746c486a 100644
--- a/mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
@@ -17,6 +17,10 @@ using namespace mlir;
 namespace {
 /// A pass converting MLIR Linalg ops into SPIR-V ops.
 class LinalgToSPIRVPass : public ModulePass<LinalgToSPIRVPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertLinalgToSPIRV
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/LoopToStandard/LoopToStandard.cpp b/mlir/lib/Conversion/LoopToStandard/LoopToStandard.cpp
index bf81a2317b07..e72c83027611 100644
--- a/mlir/lib/Conversion/LoopToStandard/LoopToStandard.cpp
+++ b/mlir/lib/Conversion/LoopToStandard/LoopToStandard.cpp
@@ -31,6 +31,10 @@ using namespace mlir::loop;
 namespace {
 
 struct LoopToStandardPass : public OperationPass<LoopToStandardPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertLoopToStandard
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnOperation() override;
 };
 

diff  --git a/mlir/lib/Conversion/LoopsToGPU/LoopsToGPUPass.cpp b/mlir/lib/Conversion/LoopsToGPU/LoopsToGPUPass.cpp
index 69ea260610ec..98a855c105c3 100644
--- a/mlir/lib/Conversion/LoopsToGPU/LoopsToGPUPass.cpp
+++ b/mlir/lib/Conversion/LoopsToGPU/LoopsToGPUPass.cpp
@@ -29,6 +29,10 @@ namespace {
 // GPU launch operations.  Nested launches are not allowed, so this does not
 // walk the function recursively to avoid considering nested loops.
 struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertSimpleLoopsToGPU
+#include "mlir/Conversion/Passes.h.inc"
+
   ForLoopMapper() = default;
   ForLoopMapper(const ForLoopMapper &) {}
   ForLoopMapper(unsigned numBlockDims, unsigned numThreadDims) {
@@ -50,15 +54,6 @@ struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
         }
       }
   }
-
-  Option<unsigned> numBlockDims{
-      *this, "gpu-block-dims",
-      llvm::cl::desc("Number of GPU block dimensions for mapping"),
-      llvm::cl::init(1u)};
-  Option<unsigned> numThreadDims{
-      *this, "gpu-thread-dims",
-      llvm::cl::desc("Number of GPU thread dimensions for mapping"),
-      llvm::cl::init(1u)};
 };
 
 // A pass that traverses top-level loops in the function and convertes them to
@@ -68,6 +63,10 @@ struct ForLoopMapper : public FunctionPass<ForLoopMapper> {
 // to be perfectly nested upto depth equal to size of `workGroupSize`.
 struct ImperfectlyNestedForLoopMapper
     : public FunctionPass<ImperfectlyNestedForLoopMapper> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertLoopsToGPU
+#include "mlir/Conversion/Passes.h.inc"
+
   ImperfectlyNestedForLoopMapper() = default;
   ImperfectlyNestedForLoopMapper(const ImperfectlyNestedForLoopMapper &) {}
   ImperfectlyNestedForLoopMapper(ArrayRef<int64_t> numWorkGroups,
@@ -103,17 +102,13 @@ struct ImperfectlyNestedForLoopMapper
       }
     }
   }
-  ListOption<int64_t> numWorkGroups{
-      *this, "gpu-num-workgroups",
-      llvm::cl::desc("Num workgroups in the GPU launch"), llvm::cl::ZeroOrMore,
-      llvm::cl::MiscFlags::CommaSeparated};
-  ListOption<int64_t> workGroupSize{
-      *this, "gpu-workgroup-size",
-      llvm::cl::desc("Workgroup Size in the GPU launch"), llvm::cl::ZeroOrMore,
-      llvm::cl::MiscFlags::CommaSeparated};
 };
 
 struct ParallelLoopToGpuPass : public OperationPass<ParallelLoopToGpuPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertParallelLoopToGpu
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnOperation() override {
     OwningRewritePatternList patterns;
     populateParallelLoopToGPUPatterns(patterns, &getContext());

diff  --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
index fdef9a98d650..91c7a249a941 100644
--- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
+++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
@@ -2798,6 +2798,10 @@ LLVMTypeConverter::promoteMemRefDescriptors(Location loc, ValueRange opOperands,
 namespace {
 /// A pass converting MLIR operations into the LLVM IR dialect.
 struct LLVMLoweringPass : public ModulePass<LLVMLoweringPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertStandardToLLVM
+#include "mlir/Conversion/Passes.h.inc"
+
   /// Creates an LLVM lowering pass.
   LLVMLoweringPass(bool useAlloca, bool useBarePtrCallConv, bool emitCWrappers,
                    unsigned indexBitwidth) {
@@ -2840,31 +2844,6 @@ struct LLVMLoweringPass : public ModulePass<LLVMLoweringPass> {
       signalPassFailure();
   }
 
-  /// Use `alloca` instead of `call @malloc` for converting std.alloc.
-  Option<bool> useAlloca{
-      *this, "use-alloca",
-      llvm::cl::desc("Replace emission of malloc/free by alloca"),
-      llvm::cl::init(false)};
-
-  /// Convert memrefs to bare pointers in function signatures.
-  Option<bool> useBarePtrCallConv{
-      *this, "use-bare-ptr-memref-call-conv",
-      llvm::cl::desc("Replace FuncOp's MemRef arguments with "
-                     "bare pointers to the MemRef element types"),
-      llvm::cl::init(false)};
-
-  /// Emit wrappers for C-compatible pointer-to-struct memref descriptors.
-  Option<bool> emitCWrappers{
-      *this, "emit-c-wrappers",
-      llvm::cl::desc("Emit C-compatible wrapper functions"),
-      llvm::cl::init(false)};
-
-  /// Configure the bitwidth of the index type when lowered to LLVM.
-  Option<unsigned> indexBitwidth{
-      *this, "index-bitwidth",
-      llvm::cl::desc(
-          "Bitwidth of the index type, 0 to use size of machine word"),
-      llvm::cl::init(kDeriveIndexBitwidthFromDataLayout)};
 };
 } // end namespace
 

diff  --git a/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp b/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp
index 569adb6f0593..ab7dd8546995 100644
--- a/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp
@@ -23,6 +23,10 @@ namespace {
 /// A pass converting MLIR Standard operations into the SPIR-V dialect.
 class ConvertStandardToSPIRVPass
     : public ModulePass<ConvertStandardToSPIRVPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertStandardToSPIRV
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp b/mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp
index e7a98a8cc45b..381087fbdf76 100644
--- a/mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp
+++ b/mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp
@@ -161,6 +161,10 @@ void mlir::populateStdLegalizationPatternsForSPIRVLowering(
 
 namespace {
 struct SPIRVLegalization final : public OperationPass<SPIRVLegalization> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LegalizeStandardForSPIRV
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnOperation() override;
 };
 } // namespace

diff  --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
index 498b5a79cdd9..d5a4f86d2ca9 100644
--- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
+++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
@@ -1119,6 +1119,10 @@ void mlir::populateVectorToLLVMMatrixConversionPatterns(
 
 namespace {
 struct LowerVectorToLLVMPass : public ModulePass<LowerVectorToLLVMPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ConvertVectorToLLVM
+#include "mlir/Conversion/Passes.h.inc"
+
   void runOnModule() override;
 };
 } // namespace

diff  --git a/mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp b/mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp
index 551a3339fc46..3101a2ec6694 100644
--- a/mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/AffineDataCopyGeneration.cpp
@@ -75,6 +75,10 @@ namespace {
 // are strided. Check for strided stores.
 struct AffineDataCopyGeneration
     : public FunctionPass<AffineDataCopyGeneration> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineDataCopyGeneration
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   explicit AffineDataCopyGeneration(
       unsigned slowMemorySpace = 0,
       unsigned fastMemorySpace = clFastMemorySpace, unsigned tagMemorySpace = 0,

diff  --git a/mlir/lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp b/mlir/lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp
index e12dfe7fc6de..12fdb37bf841 100644
--- a/mlir/lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/AffineLoopInvariantCodeMotion.cpp
@@ -42,6 +42,10 @@ namespace {
 /// TODO: This code should be removed once the new LICM pass can handle its
 ///       uses.
 struct LoopInvariantCodeMotion : public FunctionPass<LoopInvariantCodeMotion> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineLoopInvariantCodeMotion
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   void runOnFunction() override;
   void runOnAffineForOp(AffineForOp forOp);
 };

diff  --git a/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp b/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
index 2666947a8f86..2f5eea7606a9 100644
--- a/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/LoopTiling.cpp
@@ -59,6 +59,10 @@ namespace {
 
 /// A pass to perform loop tiling on all suitable loop nests of a Function.
 struct LoopTiling : public FunctionPass<LoopTiling> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineLoopTiling
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   explicit LoopTiling(uint64_t cacheSizeBytes = kDefaultCacheMemCapacity,
                       bool avoidMaxMinBounds = true)
       : cacheSizeBytes(cacheSizeBytes), avoidMaxMinBounds(avoidMaxMinBounds) {}

diff  --git a/mlir/lib/Dialect/Affine/Transforms/LoopUnroll.cpp b/mlir/lib/Dialect/Affine/Transforms/LoopUnroll.cpp
index b675f567d4ac..7f33630d3b8a 100644
--- a/mlir/lib/Dialect/Affine/Transforms/LoopUnroll.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/LoopUnroll.cpp
@@ -59,6 +59,10 @@ namespace {
 /// with trip count less than the specified threshold. The latter is for testing
 /// purposes, especially for testing outer loop unrolling.
 struct LoopUnroll : public FunctionPass<LoopUnroll> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineUnroll
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   const Optional<unsigned> unrollFactor;
   const Optional<bool> unrollFull;
   // Callback to obtain unroll factors; if this has a callable target, takes

diff  --git a/mlir/lib/Dialect/Affine/Transforms/LoopUnrollAndJam.cpp b/mlir/lib/Dialect/Affine/Transforms/LoopUnrollAndJam.cpp
index 5206ef8e1e48..5f419a83d6cf 100644
--- a/mlir/lib/Dialect/Affine/Transforms/LoopUnrollAndJam.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/LoopUnrollAndJam.cpp
@@ -61,6 +61,10 @@ namespace {
 /// Loop unroll jam pass. Currently, this just unroll jams the first
 /// outer loop in a Function.
 struct LoopUnrollAndJam : public FunctionPass<LoopUnrollAndJam> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineLoopUnrollAndJam
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   Optional<unsigned> unrollJamFactor;
   static const unsigned kDefaultUnrollJamFactor = 4;
 

diff  --git a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
index 0e657fde4994..fc58b19656fe 100644
--- a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
@@ -28,6 +28,10 @@ namespace {
 /// identity layout ones.
 struct SimplifyAffineStructures
     : public FunctionPass<SimplifyAffineStructures> {
+/// Include the generated pass utilities.
+#define GEN_PASS_SimplifyAffineStructures
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   void runOnFunction() override;
 
   /// Utility to simplify an affine attribute and update its entry in the parent

diff  --git a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
index e7fc36c13608..395945982225 100644
--- a/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/SuperVectorize.cpp
@@ -574,29 +574,14 @@ namespace {
 /// Base state for the vectorize pass.
 /// Command line arguments are preempted by non-empty pass arguments.
 struct Vectorize : public FunctionPass<Vectorize> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineVectorize
+#include "mlir/Dialect/Affine/Passes.h.inc"
+
   Vectorize() = default;
   Vectorize(const Vectorize &) {}
   Vectorize(ArrayRef<int64_t> virtualVectorSize);
   void runOnFunction() override;
-
-  /// The virtual vector size that we vectorize to.
-  ListOption<int64_t> vectorSizes{
-      *this, "virtual-vector-size",
-      llvm::cl::desc("Specify an n-D virtual vector size for vectorization"),
-      llvm::cl::ZeroOrMore, llvm::cl::CommaSeparated};
-  /// Optionally, the fixed mapping from loop to fastest varying MemRef
-  /// dimension for all the MemRefs within a loop pattern:
-  ///   the index represents the loop depth, the value represents the k^th
-  ///   fastest varying memory dimension.
-  /// This is voluntarily restrictive and is meant to precisely target a
-  /// particular loop/op pair, for testing purposes.
-  ListOption<int64_t> fastestVaryingPattern{
-      *this, "test-fastest-varying",
-      llvm::cl::desc(
-          "Specify a 1-D, 2-D or 3-D pattern of fastest varying memory"
-          " dimensions to match. See defaultPatterns in Vectorize.cpp for a"
-          " description and examples. This is used for testing purposes"),
-      llvm::cl::ZeroOrMore, llvm::cl::CommaSeparated};
 };
 
 } // end anonymous namespace

diff  --git a/mlir/lib/Dialect/FxpMathOps/Transforms/LowerUniformRealMath.cpp b/mlir/lib/Dialect/FxpMathOps/Transforms/LowerUniformRealMath.cpp
index 111009bea859..4136566201bd 100644
--- a/mlir/lib/Dialect/FxpMathOps/Transforms/LowerUniformRealMath.cpp
+++ b/mlir/lib/Dialect/FxpMathOps/Transforms/LowerUniformRealMath.cpp
@@ -21,13 +21,20 @@ using namespace mlir::fxpmath::detail;
 using namespace mlir::quant;
 
 namespace {
-
 struct LowerUniformRealMathPass
     : public FunctionPass<LowerUniformRealMathPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_FxpMathLowerUniformRealMath
+#include "mlir/Dialect/FxpMathOps/Passes.h.inc"
+
   void runOnFunction() override;
 };
 
 struct LowerUniformCastsPass : public FunctionPass<LowerUniformCastsPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_FxpMathLowerUniformCasts
+#include "mlir/Dialect/FxpMathOps/Passes.h.inc"
+
   void runOnFunction() override;
 };
 

diff  --git a/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp b/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
index 950eda91d92f..d20f23de78ec 100644
--- a/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
+++ b/mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp
@@ -205,7 +205,6 @@ static void convertToLaunchFuncOp(gpu::LaunchOp launchOp,
 }
 
 namespace {
-
 /// Pass that moves the kernel of each LaunchOp into its separate nested module.
 ///
 /// This pass moves the kernel code of each LaunchOp into a function created
@@ -217,6 +216,10 @@ namespace {
 /// symbol of the cubin accessor function.
 class GpuKernelOutliningPass : public ModulePass<GpuKernelOutliningPass> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_GpuKernelOutlining
+#include "mlir/Dialect/GPU/Passes.h.inc"
+
   void runOnModule() override {
     SymbolTable symbolTable(getModule());
     bool modified = false;

diff  --git a/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp b/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp
index b8a75d571099..663f0c11432b 100644
--- a/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp
+++ b/mlir/lib/Dialect/LLVMIR/Transforms/LegalizeForExport.cpp
@@ -58,6 +58,10 @@ void mlir::LLVM::ensureDistinctSuccessors(Operation *op) {
 
 namespace {
 struct LegalizeForExportPass : public OperationPass<LegalizeForExportPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LLVMLegalizeForExport
+#include "mlir/Dialect/LLVMIR/Transforms/Passes.h.inc"
+
   void runOnOperation() override {
     LLVM::ensureDistinctSuccessors(getOperation());
   }

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
index 81f940c01e28..d3c56851a385 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
@@ -568,6 +568,10 @@ struct FuseGenericTensorOps : public OpRewritePattern<GenericOp> {
 
 /// Pass that fuses generic ops on tensors. Used only for testing.
 struct FusionOfTensorOpsPass : public OperationPass<FusionOfTensorOpsPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgFusionOfTensorOps
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
   void runOnOperation() override {
     OwningRewritePatternList patterns;
     Operation *op = getOperation();
@@ -577,6 +581,10 @@ struct FusionOfTensorOpsPass : public OperationPass<FusionOfTensorOpsPass> {
 };
 
 struct LinalgFusionPass : public FunctionPass<LinalgFusionPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgFusion
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
   void runOnFunction() override { fuseLinalgOpsGreedily(getFunction()); }
 };
 } // namespace

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp b/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp
index e4fe212e742e..4e26080eec53 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/LinalgToLoops.cpp
@@ -640,14 +640,6 @@ void FillRewritePatterns(OwningRewritePatternList &patterns, MLIRContext *ctx) {
                      >::build(patterns, ctx);
 }
 
-namespace {
-template <typename LoopType, typename IndexedValueType>
-struct LowerLinalgToLoopsPass
-    : public FunctionPass<LowerLinalgToLoopsPass<LoopType, IndexedValueType>> {
-  void runOnFunction() override;
-};
-} // namespace
-
 // Local folding pattern for AffineApplyOp that we can apply greedily.
 // This replaces AffineApplyOp by the proper value in cases where the associated
 // map is trivial. A trivial map here is defined as a map with a single result
@@ -687,8 +679,7 @@ struct FoldAffineOp : public RewritePattern {
 } // namespace
 
 template <typename LoopType, typename IndexedValueType>
-void LowerLinalgToLoopsPass<LoopType, IndexedValueType>::runOnFunction() {
-  auto *context = &this->getContext();
+static void lowerLinalgToLoopsImpl(Operation *op, MLIRContext *context) {
   OwningRewritePatternList patterns;
   // Canonicalization and folding patterns applied greedily allow cleaning up
   // the emitted IR on the fly.
@@ -698,24 +689,54 @@ void LowerLinalgToLoopsPass<LoopType, IndexedValueType>::runOnFunction() {
   AffineApplyOp::getCanonicalizationPatterns(patterns, context);
   patterns.insert<FoldAffineOp>(context);
   // Just apply the patterns greedily.
-  applyPatternsGreedily(this->getFunction(), patterns);
+  applyPatternsGreedily(op, patterns);
 }
 
+namespace {
+struct LowerToAffineLoops : public FunctionPass<LowerToAffineLoops> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgLowerToAffineLoops
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
+  void runOnFunction() override {
+    lowerLinalgToLoopsImpl<AffineForOp, AffineIndexedValue>(getFunction(),
+                                                            &getContext());
+  }
+};
+struct LowerToLoops : public FunctionPass<LowerToLoops> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgLowerToLoops
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
+  void runOnFunction() override {
+    lowerLinalgToLoopsImpl<loop::ForOp, StdIndexedValue>(getFunction(),
+                                                         &getContext());
+  }
+};
+struct LowerToParallelLoops : public FunctionPass<LowerToParallelLoops> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgLowerToParallelLoops
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
+  void runOnFunction() override {
+    lowerLinalgToLoopsImpl<loop::ParallelOp, StdIndexedValue>(getFunction(),
+                                                              &getContext());
+  }
+};
+} // namespace
+
 std::unique_ptr<OpPassBase<FuncOp>> mlir::createConvertLinalgToLoopsPass() {
-  return std::make_unique<
-      LowerLinalgToLoopsPass<loop::ForOp, StdIndexedValue>>();
+  return std::make_unique<LowerToLoops>();
 }
 
 std::unique_ptr<OpPassBase<FuncOp>>
 mlir::createConvertLinalgToParallelLoopsPass() {
-  return std::make_unique<
-      LowerLinalgToLoopsPass<loop::ParallelOp, StdIndexedValue>>();
+  return std::make_unique<LowerToParallelLoops>();
 }
 
 std::unique_ptr<OpPassBase<FuncOp>>
 mlir::createConvertLinalgToAffineLoopsPass() {
-  return std::make_unique<
-      LowerLinalgToLoopsPass<AffineForOp, AffineIndexedValue>>();
+  return std::make_unique<LowerToAffineLoops>();
 }
 
 /// Emits a loop nest of `loop.for` with the proper body for `op`.

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
index c009dfeea425..6603507a1cdf 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
@@ -231,6 +231,10 @@ static void promoteSubViews(FuncOp f, bool dynamicBuffers) {
 
 namespace {
 struct LinalgPromotionPass : public FunctionPass<LinalgPromotionPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgPromotion
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
   LinalgPromotionPass() = default;
   LinalgPromotionPass(const LinalgPromotionPass &) {}
   LinalgPromotionPass(bool dynamicBuffers) {
@@ -240,11 +244,6 @@ struct LinalgPromotionPass : public FunctionPass<LinalgPromotionPass> {
   void runOnFunction() override {
     promoteSubViews(getFunction(), dynamicBuffers);
   }
-
-  Option<bool> dynamicBuffers{
-      *this, "test-promote-dynamic",
-      llvm::cl::desc("Test generation of dynamic promoted buffers"),
-      llvm::cl::init(false)};
 };
 } // namespace
 

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
index a1c00dc1e13f..919a7d53f479 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
@@ -507,33 +507,47 @@ static void tileLinalgOps(FuncOp f, ArrayRef<int64_t> tileSizes) {
 }
 
 namespace {
+struct LinalgTilingPass : public FunctionPass<LinalgTilingPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgTiling
+#include "mlir/Dialect/Linalg/Passes.h.inc"
 
-template <typename LoopTy>
-struct LinalgTilingPass : public FunctionPass<LinalgTilingPass<LoopTy>> {
   LinalgTilingPass() = default;
   LinalgTilingPass(const LinalgTilingPass &) {}
   LinalgTilingPass(ArrayRef<int64_t> sizes) {
-    this->tileSizes->assign(sizes.begin(), sizes.end());
+    tileSizes->assign(sizes.begin(), sizes.end());
   }
 
   void runOnFunction() override {
-    tileLinalgOps<LoopTy>(this->getFunction(), tileSizes);
+    tileLinalgOps<loop::ForOp>(getFunction(), tileSizes);
   }
+};
 
-  Pass::ListOption<int64_t> tileSizes{
-      *this, "linalg-tile-sizes",
-      llvm::cl::desc("Tile sizes by which to tile linalg operations"),
-      llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated};
+struct LinalgTilingToParallelLoopsPass
+    : public FunctionPass<LinalgTilingToParallelLoopsPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LinalgTilingToParallelLoops
+#include "mlir/Dialect/Linalg/Passes.h.inc"
+
+  LinalgTilingToParallelLoopsPass() = default;
+  LinalgTilingToParallelLoopsPass(const LinalgTilingToParallelLoopsPass &) {}
+  LinalgTilingToParallelLoopsPass(ArrayRef<int64_t> sizes) {
+    tileSizes->assign(sizes.begin(), sizes.end());
+  }
+
+  void runOnFunction() override {
+    tileLinalgOps<loop::ParallelOp>(getFunction(), tileSizes);
+  }
 };
 
 } // namespace
 
 std::unique_ptr<OpPassBase<FuncOp>>
 mlir::createLinalgTilingPass(ArrayRef<int64_t> tileSizes) {
-  return std::make_unique<LinalgTilingPass<loop::ForOp>>(tileSizes);
+  return std::make_unique<LinalgTilingPass>(tileSizes);
 }
 
 std::unique_ptr<OpPassBase<FuncOp>>
 mlir::createLinalgTilingToParallelLoopsPass(ArrayRef<int64_t> tileSizes) {
-  return std::make_unique<LinalgTilingPass<loop::ParallelOp>>(tileSizes);
+  return std::make_unique<LinalgTilingToParallelLoopsPass>(tileSizes);
 }

diff  --git a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopFusion.cpp b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopFusion.cpp
index db10939c509e..b59f1fc3c8c9 100644
--- a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopFusion.cpp
+++ b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopFusion.cpp
@@ -160,8 +160,11 @@ void mlir::loop::naivelyFuseParallelOps(Region &region) {
 }
 
 namespace {
-
 struct ParallelLoopFusion : public OperationPass<ParallelLoopFusion> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LoopParallelLoopFusion
+#include "mlir/Dialect/LoopOps/Passes.h.inc"
+
   void runOnOperation() override {
     for (Region &region : getOperation()->getRegions())
       naivelyFuseParallelOps(region);

diff  --git a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopSpecialization.cpp b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopSpecialization.cpp
index 28b8d0186bd3..471d5e53e7d0 100644
--- a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopSpecialization.cpp
+++ b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopSpecialization.cpp
@@ -61,6 +61,10 @@ static void specializeLoopForUnrolling(ParallelOp op) {
 namespace {
 struct ParallelLoopSpecialization
     : public FunctionPass<ParallelLoopSpecialization> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LoopParallelLoopSpecialization
+#include "mlir/Dialect/LoopOps/Passes.h.inc"
+
   void runOnFunction() override {
     getFunction().walk([](ParallelOp op) { specializeLoopForUnrolling(op); });
   }

diff  --git a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopTiling.cpp b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopTiling.cpp
index e5a9c32ec2ad..8b63d0090291 100644
--- a/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopTiling.cpp
+++ b/mlir/lib/Dialect/LoopOps/Transforms/ParallelLoopTiling.cpp
@@ -102,8 +102,12 @@ static bool getInnermostNestedLoops(Block *block,
 
 namespace {
 struct ParallelLoopTiling : public FunctionPass<ParallelLoopTiling> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LoopParallelLoopTiling
+#include "mlir/Dialect/LoopOps/Passes.h.inc"
+
   ParallelLoopTiling() = default;
-  ParallelLoopTiling(const ParallelLoopTiling &) {} // tileSize is non-copyable.
+  ParallelLoopTiling(const ParallelLoopTiling &) {}
   explicit ParallelLoopTiling(ArrayRef<int64_t> tileSizes) {
     this->tileSizes = tileSizes;
   }
@@ -117,11 +121,6 @@ struct ParallelLoopTiling : public FunctionPass<ParallelLoopTiling> {
       tileParallelLoop(pLoop, tileSizes);
     }
   }
-
-  ListOption<int64_t> tileSizes{
-      *this, "parallel-loop-tile-sizes",
-      llvm::cl::desc("factors to tile parallel loops by"), llvm::cl::ZeroOrMore,
-      llvm::cl::MiscFlags::CommaSeparated};
 };
 } // namespace
 

diff  --git a/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp b/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp
index ccc9d5c5256e..3017346a9acc 100644
--- a/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp
+++ b/mlir/lib/Dialect/Quant/Transforms/ConvertConst.cpp
@@ -21,9 +21,11 @@ using namespace mlir;
 using namespace mlir::quant;
 
 namespace {
+struct ConvertConstPass : public FunctionPass<ConvertConstPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_QuantConvertConst
+#include "mlir/Dialect/Quant/Passes.h.inc"
 
-class ConvertConstPass : public FunctionPass<ConvertConstPass> {
-public:
   void runOnFunction() override;
 };
 

diff  --git a/mlir/lib/Dialect/Quant/Transforms/ConvertSimQuant.cpp b/mlir/lib/Dialect/Quant/Transforms/ConvertSimQuant.cpp
index 3553b236d318..b76cee6a412c 100644
--- a/mlir/lib/Dialect/Quant/Transforms/ConvertSimQuant.cpp
+++ b/mlir/lib/Dialect/Quant/Transforms/ConvertSimQuant.cpp
@@ -19,10 +19,12 @@ using namespace mlir;
 using namespace mlir::quant;
 
 namespace {
-
-class ConvertSimulatedQuantPass
+struct ConvertSimulatedQuantPass
     : public FunctionPass<ConvertSimulatedQuantPass> {
-public:
+/// Include the generated pass utilities.
+#define GEN_PASS_QuantConvertSimulatedQuant
+#include "mlir/Dialect/Quant/Passes.h.inc"
+
   void runOnFunction() override;
 };
 

diff  --git a/mlir/lib/Quantizer/Transforms/AddDefaultStatsTestPass.cpp b/mlir/lib/Quantizer/Transforms/AddDefaultStatsTestPass.cpp
index 13a09b39a499..238b0e850b88 100644
--- a/mlir/lib/Quantizer/Transforms/AddDefaultStatsTestPass.cpp
+++ b/mlir/lib/Quantizer/Transforms/AddDefaultStatsTestPass.cpp
@@ -29,9 +29,12 @@ using namespace mlir::quantizer;
 using namespace mlir::quant;
 
 namespace {
-
 class AddDefaultStatsPass : public FunctionPass<AddDefaultStatsPass> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_QuantizerAddDefaultStats
+#include "mlir/Quantizer/Transforms/Passes.h.inc"
+
   AddDefaultStatsPass() = default;
   AddDefaultStatsPass(SolverContext &solverContext,
                       const TargetConfiguration &config)

diff  --git a/mlir/lib/Quantizer/Transforms/InferQuantizedTypesPass.cpp b/mlir/lib/Quantizer/Transforms/InferQuantizedTypesPass.cpp
index 1066c15b6333..49d98ef695c0 100644
--- a/mlir/lib/Quantizer/Transforms/InferQuantizedTypesPass.cpp
+++ b/mlir/lib/Quantizer/Transforms/InferQuantizedTypesPass.cpp
@@ -71,13 +71,17 @@ struct DOTGraphTraits<const CAGSlice *>
 } // end namespace llvm
 
 namespace {
-
 class InferQuantizedTypesPass : public ModulePass<InferQuantizedTypesPass> {
 public:
+/// Include the generated pass utilities.
+#define GEN_PASS_QuantizerInferQuantizedTypes
+#include "mlir/Quantizer/Transforms/Passes.h.inc"
+
   InferQuantizedTypesPass() = default;
   InferQuantizedTypesPass(SolverContext &solverContext,
                           const TargetConfiguration &config)
       : explicitSolverContext(&solverContext), explicitConfig(&config) {}
+
   void runOnModule() override;
   void runWithConfig(SolverContext &solverContext,
                      const TargetConfiguration &config);

diff  --git a/mlir/lib/Quantizer/Transforms/RemoveInstrumentationPass.cpp b/mlir/lib/Quantizer/Transforms/RemoveInstrumentationPass.cpp
index d05810733f1b..6c348d392254 100644
--- a/mlir/lib/Quantizer/Transforms/RemoveInstrumentationPass.cpp
+++ b/mlir/lib/Quantizer/Transforms/RemoveInstrumentationPass.cpp
@@ -23,9 +23,12 @@ using namespace mlir::quantizer;
 using namespace mlir::quant;
 
 namespace {
-
 class RemoveInstrumentationPass
     : public FunctionPass<RemoveInstrumentationPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_QuantizerRemoveInstrumentation
+#include "mlir/Quantizer/Transforms/Passes.h.inc"
+
   void runOnFunction() override;
 };
 

diff  --git a/mlir/lib/TableGen/Pass.cpp b/mlir/lib/TableGen/Pass.cpp
index 047cf2312c31..63f31c99bc90 100644
--- a/mlir/lib/TableGen/Pass.cpp
+++ b/mlir/lib/TableGen/Pass.cpp
@@ -12,11 +12,64 @@
 using namespace mlir;
 using namespace mlir::tblgen;
 
+//===----------------------------------------------------------------------===//
+// PassOption
+//===----------------------------------------------------------------------===//
+
+StringRef PassOption::getCppVariableName() const {
+  return def->getValueAsString("cppName");
+}
+
+StringRef PassOption::getArgument() const {
+  return def->getValueAsString("argument");
+}
+
+StringRef PassOption::getType() const { return def->getValueAsString("type"); }
+
+Optional<StringRef> PassOption::getDefaultValue() const {
+  StringRef defaultVal = def->getValueAsString("defaultValue");
+  return defaultVal.empty() ? Optional<StringRef>() : defaultVal;
+}
+
+StringRef PassOption::getDescription() const {
+  return def->getValueAsString("description");
+}
+
+Optional<StringRef> PassOption::getAdditionalFlags() const {
+  StringRef additionalFlags = def->getValueAsString("additionalOptFlags");
+  return additionalFlags.empty() ? Optional<StringRef>() : additionalFlags;
+}
+
+bool PassOption::isListOption() const {
+  return def->isSubClassOf("ListOption");
+}
+
+//===----------------------------------------------------------------------===//
+// PassStatistic
+//===----------------------------------------------------------------------===//
+
+StringRef PassStatistic::getCppVariableName() const {
+  return def->getValueAsString("cppName");
+}
+
+StringRef PassStatistic::getName() const {
+  return def->getValueAsString("name");
+}
+
+StringRef PassStatistic::getDescription() const {
+  return def->getValueAsString("description");
+}
+
 //===----------------------------------------------------------------------===//
 // Pass
 //===----------------------------------------------------------------------===//
 
-Pass::Pass(const llvm::Record *def) : def(def) {}
+Pass::Pass(const llvm::Record *def) : def(def) {
+  for (auto *init : def->getValueAsListOfDefs("options"))
+    options.push_back(PassOption(init));
+  for (auto *init : def->getValueAsListOfDefs("statistics"))
+    statistics.push_back(PassStatistic(init));
+}
 
 StringRef Pass::getArgument() const {
   return def->getValueAsString("argument");
@@ -31,3 +84,7 @@ StringRef Pass::getDescription() const {
 StringRef Pass::getConstructor() const {
   return def->getValueAsString("constructor");
 }
+
+ArrayRef<PassOption> Pass::getOptions() const { return options; }
+
+ArrayRef<PassStatistic> Pass::getStatistics() const { return statistics; }

diff  --git a/mlir/lib/Transforms/CSE.cpp b/mlir/lib/Transforms/CSE.cpp
index a8cb98ced807..67890f63dcd9 100644
--- a/mlir/lib/Transforms/CSE.cpp
+++ b/mlir/lib/Transforms/CSE.cpp
@@ -74,6 +74,10 @@ struct SimpleOperationInfo : public llvm::DenseMapInfo<Operation *> {
 namespace {
 /// Simple common sub-expression elimination.
 struct CSE : public OperationPass<CSE> {
+/// Include the generated pass utilities.
+#define GEN_PASS_CSE
+#include "mlir/Transforms/Passes.h.inc"
+
   CSE() = default;
   CSE(const CSE &) {}
 
@@ -114,10 +118,6 @@ struct CSE : public OperationPass<CSE> {
 private:
   /// Operations marked as dead and to be erased.
   std::vector<Operation *> opsToErase;
-
-  /// Statistics for CSE.
-  Statistic numCSE{this, "num-cse'd", "Number of operations CSE'd"};
-  Statistic numDCE{this, "num-dce'd", "Number of operations trivially DCE'd"};
 };
 } // end anonymous namespace
 

diff  --git a/mlir/lib/Transforms/Canonicalizer.cpp b/mlir/lib/Transforms/Canonicalizer.cpp
index 9848021a3ffe..964fc7f66500 100644
--- a/mlir/lib/Transforms/Canonicalizer.cpp
+++ b/mlir/lib/Transforms/Canonicalizer.cpp
@@ -20,6 +20,10 @@ using namespace mlir;
 namespace {
 /// Canonicalize operations in nested regions.
 struct Canonicalizer : public OperationPass<Canonicalizer> {
+/// Include the generated pass utilities.
+#define GEN_PASS_Canonicalizer
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnOperation() override {
     OwningRewritePatternList patterns;
 

diff  --git a/mlir/lib/Transforms/Inliner.cpp b/mlir/lib/Transforms/Inliner.cpp
index c4c9c8baaa52..04ae30faf2aa 100644
--- a/mlir/lib/Transforms/Inliner.cpp
+++ b/mlir/lib/Transforms/Inliner.cpp
@@ -590,6 +590,10 @@ static void inlineSCC(Inliner &inliner, CGUseList &useList,
 
 namespace {
 struct InlinerPass : public OperationPass<InlinerPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_Inliner
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnOperation() override {
     CallGraph &cg = getAnalysis<CallGraph>();
     auto *context = &getContext();

diff  --git a/mlir/lib/Transforms/LocationSnapshot.cpp b/mlir/lib/Transforms/LocationSnapshot.cpp
index 3ec33466a3e3..4f54e13e76fd 100644
--- a/mlir/lib/Transforms/LocationSnapshot.cpp
+++ b/mlir/lib/Transforms/LocationSnapshot.cpp
@@ -123,8 +123,11 @@ LogicalResult mlir::generateLocationsFromIR(StringRef fileName, StringRef tag,
 }
 
 namespace {
-class LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
-public:
+struct LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LocationSnapshot
+#include "mlir/Transforms/Passes.h.inc"
+
   LocationSnapshotPass() = default;
   LocationSnapshotPass(const LocationSnapshotPass &) {}
   LocationSnapshotPass(OpPrintingFlags flags, StringRef fileName, StringRef tag)
@@ -139,14 +142,6 @@ class LocationSnapshotPass : public OperationPass<LocationSnapshotPass> {
       return signalPassFailure();
   }
 
-  Option<std::string> fileName{
-      *this, "filename",
-      llvm::cl::desc("The filename to print the generated IR.")};
-  Option<std::string> tag{
-      *this, "tag",
-      llvm::cl::desc("A tag to use when fusing the new locations with the "
-                     "original. If unset, the locations are replaced.")};
-
   /// The printing flags to use when creating the snapshot.
   OpPrintingFlags flags;
 };

diff  --git a/mlir/lib/Transforms/LoopCoalescing.cpp b/mlir/lib/Transforms/LoopCoalescing.cpp
index c7882f70eaa4..322b3b92c52c 100644
--- a/mlir/lib/Transforms/LoopCoalescing.cpp
+++ b/mlir/lib/Transforms/LoopCoalescing.cpp
@@ -19,8 +19,11 @@
 using namespace mlir;
 
 namespace {
-class LoopCoalescingPass : public FunctionPass<LoopCoalescingPass> {
-public:
+struct LoopCoalescingPass : public FunctionPass<LoopCoalescingPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_LoopCoalescing
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnFunction() override {
     FuncOp func = getFunction();
 

diff  --git a/mlir/lib/Transforms/LoopFusion.cpp b/mlir/lib/Transforms/LoopFusion.cpp
index 34307698112b..55b45c0595a6 100644
--- a/mlir/lib/Transforms/LoopFusion.cpp
+++ b/mlir/lib/Transforms/LoopFusion.cpp
@@ -68,7 +68,6 @@ static llvm::cl::opt<unsigned long long> clFusionLocalBufThreshold(
     llvm::cl::cat(clOptionsCategory));
 
 namespace {
-
 /// Loop fusion pass. This pass currently supports a greedy fusion policy,
 /// which fuses loop nests with single-writer/single-reader memref dependences
 /// with the goal of improving locality.
@@ -79,6 +78,10 @@ namespace {
 // and add support for more general loop fusion algorithms.
 
 struct LoopFusion : public FunctionPass<LoopFusion> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffineLoopFusion
+#include "mlir/Transforms/Passes.h.inc"
+
   LoopFusion(unsigned fastMemorySpace = 0, uint64_t localBufSizeThreshold = 0,
              bool maximalFusion = false)
       : localBufSizeThreshold(localBufSizeThreshold),

diff  --git a/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp b/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp
index 30922484dae0..7407676d5877 100644
--- a/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp
+++ b/mlir/lib/Transforms/LoopInvariantCodeMotion.cpp
@@ -28,7 +28,10 @@ using namespace mlir;
 namespace {
 /// Loop invariant code motion (LICM) pass.
 struct LoopInvariantCodeMotion : public OperationPass<LoopInvariantCodeMotion> {
-public:
+/// Include the generated pass utilities.
+#define GEN_PASS_LoopInvariantCodeMotion
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnOperation() override;
 };
 } // end anonymous namespace

diff  --git a/mlir/lib/Transforms/MemRefDataFlowOpt.cpp b/mlir/lib/Transforms/MemRefDataFlowOpt.cpp
index fafdfe98fbe6..e251edaf38cb 100644
--- a/mlir/lib/Transforms/MemRefDataFlowOpt.cpp
+++ b/mlir/lib/Transforms/MemRefDataFlowOpt.cpp
@@ -28,7 +28,6 @@
 using namespace mlir;
 
 namespace {
-
 // The store to load forwarding relies on three conditions:
 //
 // 1) they need to have mathematically equivalent affine access functions
@@ -62,6 +61,10 @@ namespace {
 // than dealloc) remain.
 //
 struct MemRefDataFlowOpt : public FunctionPass<MemRefDataFlowOpt> {
+/// Include the generated pass utilities.
+#define GEN_PASS_MemRefDataFlowOpt
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnFunction() override;
 
   void forwardStoreToLoad(AffineLoadOp loadOp);

diff  --git a/mlir/lib/Transforms/OpStats.cpp b/mlir/lib/Transforms/OpStats.cpp
index 149acc3a3069..b7832f580dd4 100644
--- a/mlir/lib/Transforms/OpStats.cpp
+++ b/mlir/lib/Transforms/OpStats.cpp
@@ -19,6 +19,10 @@ using namespace mlir;
 
 namespace {
 struct PrintOpStatsPass : public ModulePass<PrintOpStatsPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_PrintOpStats
+#include "mlir/Transforms/Passes.h.inc"
+
   explicit PrintOpStatsPass(raw_ostream &os = llvm::errs()) : os(os) {}
 
   // Prints the resultant operation statistics post iterating over the module.

diff  --git a/mlir/lib/Transforms/ParallelLoopCollapsing.cpp b/mlir/lib/Transforms/ParallelLoopCollapsing.cpp
index 8d74f551d88b..29aded6465c7 100644
--- a/mlir/lib/Transforms/ParallelLoopCollapsing.cpp
+++ b/mlir/lib/Transforms/ParallelLoopCollapsing.cpp
@@ -21,6 +21,10 @@ using namespace mlir;
 
 namespace {
 struct ParallelLoopCollapsing : public OperationPass<ParallelLoopCollapsing> {
+/// Include the generated pass utilities.
+#define GEN_PASS_ParallelLoopCollapsing
+#include "mlir/Transforms/Passes.h.inc"
+
   ParallelLoopCollapsing() = default;
   ParallelLoopCollapsing(const ParallelLoopCollapsing &) {}
   void runOnOperation() override {
@@ -39,23 +43,6 @@ struct ParallelLoopCollapsing : public OperationPass<ParallelLoopCollapsing> {
       collapseParallelLoops(op, combinedLoops);
     });
   }
-
-  ListOption<unsigned> clCollapsedIndices0{
-      *this, "collapsed-indices-0",
-      llvm::cl::desc("Which loop indices to combine 0th loop index"),
-      llvm::cl::MiscFlags::CommaSeparated};
-
-  ListOption<unsigned> clCollapsedIndices1{
-      *this, "collapsed-indices-1",
-      llvm::cl::desc(
-          "Which loop indices to combine into the position 1 loop index"),
-      llvm::cl::MiscFlags::CommaSeparated};
-
-  ListOption<unsigned> clCollapsedIndices2{
-      *this, "collapsed-indices-2",
-      llvm::cl::desc(
-          "Which loop indices to combine into the position 2 loop index"),
-      llvm::cl::MiscFlags::CommaSeparated};
 };
 
 } // namespace

diff  --git a/mlir/lib/Transforms/PipelineDataTransfer.cpp b/mlir/lib/Transforms/PipelineDataTransfer.cpp
index 01ffd4478f3c..4ca3620b9d28 100644
--- a/mlir/lib/Transforms/PipelineDataTransfer.cpp
+++ b/mlir/lib/Transforms/PipelineDataTransfer.cpp
@@ -28,8 +28,11 @@
 using namespace mlir;
 
 namespace {
-
 struct PipelineDataTransfer : public FunctionPass<PipelineDataTransfer> {
+/// Include the generated pass utilities.
+#define GEN_PASS_AffinePipelineDataTransfer
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnFunction() override;
   void runOnAffineForOp(AffineForOp forOp);
 

diff  --git a/mlir/lib/Transforms/StripDebugInfo.cpp b/mlir/lib/Transforms/StripDebugInfo.cpp
index f9e12cf76d09..d3420cfc35a1 100644
--- a/mlir/lib/Transforms/StripDebugInfo.cpp
+++ b/mlir/lib/Transforms/StripDebugInfo.cpp
@@ -15,6 +15,10 @@ using namespace mlir;
 
 namespace {
 struct StripDebugInfo : public OperationPass<StripDebugInfo> {
+/// Include the generated pass utilities.
+#define GEN_PASS_StripDebugInfo
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnOperation() override;
 };
 } // end anonymous namespace

diff  --git a/mlir/lib/Transforms/SymbolDCE.cpp b/mlir/lib/Transforms/SymbolDCE.cpp
index ea9c252d95f7..7513e34af388 100644
--- a/mlir/lib/Transforms/SymbolDCE.cpp
+++ b/mlir/lib/Transforms/SymbolDCE.cpp
@@ -18,6 +18,10 @@ using namespace mlir;
 
 namespace {
 struct SymbolDCE : public OperationPass<SymbolDCE> {
+/// Include the generated pass utilities.
+#define GEN_PASS_SymbolDCE
+#include "mlir/Transforms/Passes.h.inc"
+
   void runOnOperation() override;
 
   /// Compute the liveness of the symbols within the given symbol table.

diff  --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index c635e90f474f..fcaff9a0b069 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -101,6 +101,10 @@ namespace {
 // Note: this is a module pass only to avoid interleaving on the same ostream
 // due to multi-threading over functions.
 struct PrintOpPass : public ModulePass<PrintOpPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_PrintOpGraph
+#include "mlir/Transforms/Passes.h.inc"
+
   explicit PrintOpPass(raw_ostream &os = llvm::errs(), bool short_names = false,
                        const Twine &title = "")
       : os(os), title(title.str()), short_names(short_names) {}

diff  --git a/mlir/lib/Transforms/ViewRegionGraph.cpp b/mlir/lib/Transforms/ViewRegionGraph.cpp
index e1d19e0df8d4..cf9ff6d8077e 100644
--- a/mlir/lib/Transforms/ViewRegionGraph.cpp
+++ b/mlir/lib/Transforms/ViewRegionGraph.cpp
@@ -61,6 +61,10 @@ void mlir::Region::viewGraph() { viewGraph("region"); }
 
 namespace {
 struct PrintCFGPass : public FunctionPass<PrintCFGPass> {
+/// Include the generated pass utilities.
+#define GEN_PASS_PrintCFG
+#include "mlir/Transforms/Passes.h.inc"
+
   PrintCFGPass(raw_ostream &os = llvm::errs(), bool shortNames = false,
                const Twine &title = "")
       : os(os), shortNames(shortNames), title(title.str()) {}

diff  --git a/mlir/tools/mlir-tblgen/PassGen.cpp b/mlir/tools/mlir-tblgen/PassGen.cpp
index 23b9bfa0f6a8..72ef5a653369 100644
--- a/mlir/tools/mlir-tblgen/PassGen.cpp
+++ b/mlir/tools/mlir-tblgen/PassGen.cpp
@@ -21,6 +21,64 @@
 using namespace mlir;
 using namespace mlir::tblgen;
 
+//===----------------------------------------------------------------------===//
+// GEN: Pass base class generation
+//===----------------------------------------------------------------------===//
+
+/// The code snippet used to generate the start of a pass base class.
+///
+/// {0}: The def name of the pass record.
+/// {1}: The command line argument for the pass.
+const char *const passDeclBegin = R"(
+//===----------------------------------------------------------------------===//
+// {0}
+//===----------------------------------------------------------------------===//
+#ifdef GEN_PASS_{0}
+  /// Returns the command-line argument attached to this pass.
+  static StringRef getPassArgument() { return "{1}"; }
+)";
+
+/// The code snippet used to generate the end of a pass base class.
+///
+/// {0}: The def name of the pass record.
+const char *const passDeclEnd = R"(
+#undef GEN_PASS_{0}
+#endif // GEN_PASS_{0}
+)";
+
+/// Emit the declarations for each of the pass options.
+static void emitPassOptionDecls(const Pass &pass, raw_ostream &os) {
+  for (const PassOption &opt : pass.getOptions()) {
+    os.indent(2) << "Pass::" << (opt.isListOption() ? "ListOption" : "Option");
+
+    os << llvm::formatv("<{0}> {1}{{*this, \"{2}\", llvm::cl::desc(\"{3}\")",
+                        opt.getType(), opt.getCppVariableName(),
+                        opt.getArgument(), opt.getDescription());
+    if (Optional<StringRef> defaultVal = opt.getDefaultValue())
+      os << ", llvm::cl::init(" << defaultVal << ")";
+    if (Optional<StringRef> additionalFlags = opt.getAdditionalFlags())
+      os << ", " << *additionalFlags;
+    os << "};\n";
+  }
+}
+
+/// Emit the declarations for each of the pass statistics.
+static void emitPassStatisticDecls(const Pass &pass, raw_ostream &os) {
+  for (const PassStatistic &stat : pass.getStatistics()) {
+    os << llvm::formatv("  Pass::Statistic {0}{{this, \"{1}\", \"{2}\"};\n",
+                        stat.getCppVariableName(), stat.getName(),
+                        stat.getDescription());
+  }
+}
+
+static void emitPassDecl(const Pass &pass, raw_ostream &os) {
+  StringRef defName = pass.getDef()->getName();
+  os << llvm::formatv(passDeclBegin, defName, pass.getArgument());
+  emitPassOptionDecls(pass, os);
+  emitPassStatisticDecls(pass, os);
+  os << llvm::formatv(passDeclEnd, defName);
+}
+
 //===----------------------------------------------------------------------===//
 // GEN: Pass registration generation
 //===----------------------------------------------------------------------===//
@@ -47,8 +105,11 @@ static void emitDecls(const llvm::RecordKeeper &recordKeeper, raw_ostream &os) {
   os << "/* Autogenerated by mlir-tblgen; don't manually edit */\n";
 
   std::vector<Pass> passes;
-  for (const llvm::Record *def : recordKeeper.getAllDerivedDefinitions("Pass"))
-    passes.push_back(Pass(def));
+  for (const auto *def : recordKeeper.getAllDerivedDefinitions("Pass")) {
+    Pass pass(def);
+    passes.push_back(pass);
+    emitPassDecl(pass, os);
+  }
   emitRegistration(passes, os);
 }
 


        


More information about the Mlir-commits mailing list