MLIR  18.0.0git
TransformInterpreterPassBase.h
Go to the documentation of this file.
1 //===- TransformInterpreterPassBase.h ---------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Base class with shared implementation for transform dialect interpreter
10 // passes.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_TRANSFORM_TRANSFORMS_TRANSFORMINTERPRETERPASSBASE_H
15 #define MLIR_DIALECT_TRANSFORM_TRANSFORMS_TRANSFORMINTERPRETERPASSBASE_H
16 
18 #include "mlir/Pass/Pass.h"
19 #include "mlir/Support/LLVM.h"
20 #include <memory>
21 
22 namespace mlir {
23 struct LogicalResult;
24 class MLIRContext;
25 class ModuleOp;
26 class Operation;
27 template <typename>
28 class OwningOpRef;
29 class Region;
30 
31 namespace transform {
32 namespace detail {
33 /// Template-free implementation of TransformInterpreterPassBase::initialize.
34 LogicalResult interpreterBaseInitializeImpl(
35  MLIRContext *context, StringRef transformFileName,
36  ArrayRef<std::string> transformLibraryPaths,
37  std::shared_ptr<OwningOpRef<ModuleOp>> &module,
38  std::shared_ptr<OwningOpRef<ModuleOp>> &libraryModule,
39  function_ref<std::optional<LogicalResult>(OpBuilder &, Location)>
40  moduleBuilder = nullptr);
41 
42 /// Template-free implementation of
43 /// TransformInterpreterPassBase::runOnOperation.
45  Operation *target, StringRef passName,
46  const std::shared_ptr<OwningOpRef<ModuleOp>> &sharedTransformModule,
47  const std::shared_ptr<OwningOpRef<ModuleOp>> &libraryModule,
48  const RaggedArray<MappedValue> &extraMappings,
49  const TransformOptions &options,
50  const Pass::Option<std::string> &transformFileName,
51  const Pass::ListOption<std::string> &transformLibraryPaths,
52  const Pass::Option<std::string> &debugPayloadRootTag,
53  const Pass::Option<std::string> &debugTransformRootTag,
54  StringRef binaryName);
55 } // namespace detail
56 
57 /// Base class for transform dialect interpreter passes that can consume and
58 /// dump transform dialect scripts in separate files. The pass is controlled by
59 /// three string options:
60 ///
61 /// - transformFileName: if non-empty, the name of the file containing the
62 /// transform script. If empty, `debugTransformRootTag` is considered or the
63 /// pass root operation must contain a single top-level transform op that
64 /// will be interpreted.
65 /// - transformLibraryPaths: if non-empty, the modules in these files will be
66 /// merged into the main transform script run by the interpreter before
67 /// execution. This allows to provide definitions for external functions
68 /// used in the main script. Other public symbols in the library modules may
69 /// lead to collisions with public symbols in the main script and among each
70 /// other.
71 /// - debugPayloadRootTag: if non-empty, the value of the attribute named
72 /// `kTransformDialectTagAttrName` indicating the single op that is
73 /// considered the payload root of the transform interpreter; otherwise, the
74 /// root operation of the pass is used.
75 /// - debugTransformRootTag: if non-empty, the value of the attribute named
76 /// `kTransformDialectTagAttrName` indicating the single top-level transform
77 /// op contained in the payload root to be used as the entry point by the
78 /// transform interpreter; mutually exclusive with `transformFileName`.
79 ///
80 /// The pass runs the transform dialect interpreter as directed by the options.
81 /// It also provides the mechanism to dump reproducers into stderr
82 /// (-debug-only=transform-dialect-dump-repro) or into a temporary file
83 /// (-debug-only=transform-dialect-save-repro) that can be used with this
84 /// pass in a standalone mode.
85 ///
86 /// Concrete passes must derive from this class instead of their generated base
87 /// class (or PassWrapper), and supply themselves and the generated base class
88 /// as template arguments. They are *not* expected to to implement `initialize`
89 /// or `runOnOperation`. They *are* expected to call the copy constructor of
90 /// this class in their copy constructors, short of which the file-based
91 /// transform dialect script injection facility will become non-operational.
92 ///
93 /// Concrete passes may implement the `runBeforeInterpreter` and
94 /// `runAfterInterpreter` to customize the behavior of the pass.
95 template <typename Concrete, template <typename> typename GeneratedBase>
96 class TransformInterpreterPassBase : public GeneratedBase<Concrete> {
97 public:
100  : options(options) {}
101 
103  sharedTransformModule = pass.sharedTransformModule;
104  transformLibraryModule = pass.transformLibraryModule;
105  options = pass.options;
106  }
107 
108  static StringLiteral getBinaryName() { return "mlir-opt"; }
109 
110  LogicalResult initialize(MLIRContext *context) override {
111 
112 #define REQUIRE_PASS_OPTION(NAME) \
113  static_assert( \
114  std::is_same_v< \
115  std::remove_reference_t<decltype(std::declval<Concrete &>().NAME)>, \
116  Pass::Option<std::string>>, \
117  "required " #NAME " string pass option is missing")
118 
119  REQUIRE_PASS_OPTION(transformFileName);
120  REQUIRE_PASS_OPTION(debugPayloadRootTag);
121  REQUIRE_PASS_OPTION(debugTransformRootTag);
122 
123 #undef REQUIRE_PASS_OPTION
124 
125 #define REQUIRE_PASS_LIST_OPTION(NAME) \
126  static_assert( \
127  std::is_same_v< \
128  std::remove_reference_t<decltype(std::declval<Concrete &>().NAME)>, \
129  Pass::ListOption<std::string>>, \
130  "required " #NAME " string pass option is missing")
131 
132  REQUIRE_PASS_LIST_OPTION(transformLibraryPaths);
133 
134 #undef REQUIRE_PASS_LIST_OPTION
135 
136  StringRef transformFileName =
137  static_cast<Concrete *>(this)->transformFileName;
138  ArrayRef<std::string> transformLibraryPaths =
139  static_cast<Concrete *>(this)->transformLibraryPaths;
141  context, transformFileName, transformLibraryPaths,
142  sharedTransformModule, transformLibraryModule,
143  [this](OpBuilder &builder, Location loc) {
144  return static_cast<Concrete *>(this)->constructTransformModule(
145  builder, loc);
146  });
147  }
148 
149  /// Hook for passes to run additional logic in the pass before the
150  /// interpreter. If failure is returned, the pass fails and the interpreter is
151  /// not run.
153 
154  /// Hook for passes to run additional logic in the pass after the interpreter.
155  /// Only runs if everything succeeded before. If failure is returned, the pass
156  /// fails.
158 
159  /// Hook for passes to run custom logic to construct the transform module.
160  /// This will run during initialization. If the external script is provided,
161  /// it overrides the construction, which will not be called.
162  std::optional<LogicalResult> constructTransformModule(OpBuilder &builder,
163  Location loc) {
164  return std::nullopt;
165  }
166 
167  void runOnOperation() override {
168  auto *pass = static_cast<Concrete *>(this);
169  Operation *op = pass->getOperation();
170  StringRef binaryName = Concrete::getBinaryName();
171  if (failed(pass->runBeforeInterpreter(op)) ||
173  op, pass->getArgument(), sharedTransformModule,
174  transformLibraryModule,
175  /*extraMappings=*/{}, options, pass->transformFileName,
176  pass->transformLibraryPaths, pass->debugPayloadRootTag,
177  pass->debugTransformRootTag, binaryName)) ||
178  failed(pass->runAfterInterpreter(op))) {
179  return pass->signalPassFailure();
180  }
181  }
182 
183 protected:
184  /// Transform interpreter options.
186 
187  /// Returns a read-only reference to shared transform module.
188  const std::shared_ptr<OwningOpRef<ModuleOp>> &
190  return sharedTransformModule;
191  }
192 
193  /// Returns a read-only reference to the transform library module.
194  const std::shared_ptr<OwningOpRef<ModuleOp>> &
196  return transformLibraryModule;
197  }
198 
199 private:
200  /// The separate transform module to be used for transformations, shared
201  /// across multiple instances of the pass if it is applied in parallel to
202  /// avoid potentially expensive cloning. MUST NOT be modified after the pass
203  /// has been initialized.
204  std::shared_ptr<OwningOpRef<ModuleOp>> sharedTransformModule = nullptr;
205 
206  /// The transform module containing symbol definitions that become available
207  /// in the transform scripts. Similar to dynamic linking for binaries. This is
208  /// shared across multiple instances of the pass and therefore MUST NOT be
209  /// modified after the pass has been initialized.
210  std::shared_ptr<OwningOpRef<ModuleOp>> transformLibraryModule = nullptr;
211 };
212 
213 } // namespace transform
214 } // namespace mlir
215 
216 #endif // MLIR_DIALECT_TRANSFORM_TRANSFORMS_TRANSFORMINTERPRETERPASSBASE_H
static llvm::ManagedStatic< PassManagerOptions > options
#define REQUIRE_PASS_OPTION(NAME)
#define REQUIRE_PASS_LIST_OPTION(NAME)
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
This class helps build Operations.
Definition: Builders.h:206
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Base class for transform dialect interpreter passes that can consume and dump transform dialect scrip...
LogicalResult runAfterInterpreter(Operation *)
Hook for passes to run additional logic in the pass after the interpreter.
const std::shared_ptr< OwningOpRef< ModuleOp > > & getTransformLibraryModule() const
Returns a read-only reference to the transform library module.
TransformInterpreterPassBase(const TransformOptions &options=TransformOptions())
std::optional< LogicalResult > constructTransformModule(OpBuilder &builder, Location loc)
Hook for passes to run custom logic to construct the transform module.
LogicalResult initialize(MLIRContext *context) override
TransformOptions options
Transform interpreter options.
TransformInterpreterPassBase(const TransformInterpreterPassBase &pass)
const std::shared_ptr< OwningOpRef< ModuleOp > > & getSharedTransformModule() const
Returns a read-only reference to shared transform module.
LogicalResult runBeforeInterpreter(Operation *)
Hook for passes to run additional logic in the pass before the interpreter.
Options controlling the application of transform operations by the TransformState.
LogicalResult interpreterBaseInitializeImpl(MLIRContext *context, StringRef transformFileName, ArrayRef< std::string > transformLibraryPaths, std::shared_ptr< OwningOpRef< ModuleOp >> &module, std::shared_ptr< OwningOpRef< ModuleOp >> &libraryModule, function_ref< std::optional< LogicalResult >(OpBuilder &, Location)> moduleBuilder=nullptr)
Template-free implementation of TransformInterpreterPassBase::initialize.
LogicalResult interpreterBaseRunOnOperationImpl(Operation *target, StringRef passName, const std::shared_ptr< OwningOpRef< ModuleOp >> &sharedTransformModule, const std::shared_ptr< OwningOpRef< ModuleOp >> &libraryModule, const RaggedArray< MappedValue > &extraMappings, const TransformOptions &options, const Pass::Option< std::string > &transformFileName, const Pass::ListOption< std::string > &transformLibraryPaths, const Pass::Option< std::string > &debugPayloadRootTag, const Pass::Option< std::string > &debugTransformRootTag, StringRef binaryName)
Template-free implementation of TransformInterpreterPassBase::runOnOperation.
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref
Definition: LLVM.h:147
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26