MLIR  14.0.0git
FoldUtils.h
Go to the documentation of this file.
1 //===- FoldUtils.h - Operation Fold Utilities -------------------*- 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 // This header file declares various operation folding utilities. These
10 // utilities are intended to be used by passes to unify and simply their logic.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TRANSFORMS_FOLDUTILS_H
15 #define MLIR_TRANSFORMS_FOLDUTILS_H
16 
17 #include "mlir/IR/Builders.h"
18 #include "mlir/IR/Dialect.h"
21 
22 namespace mlir {
23 class Operation;
24 class Value;
25 
26 //===--------------------------------------------------------------------===//
27 // OperationFolder
28 //===--------------------------------------------------------------------===//
29 
30 /// A utility class for folding operations, and unifying duplicated constants
31 /// generated along the way.
33 public:
34  OperationFolder(MLIRContext *ctx) : interfaces(ctx) {}
35 
36  /// Tries to perform folding on the given `op`, including unifying
37  /// deduplicated constants. If successful, replaces `op`'s uses with
38  /// folded results, and returns success. `preReplaceAction` is invoked on `op`
39  /// before it is replaced. 'processGeneratedConstants' is invoked for any new
40  /// operations generated when folding. If the op was completely folded it is
41  /// erased. If it is just updated in place, `inPlaceUpdate` is set to true.
43  tryToFold(Operation *op,
44  function_ref<void(Operation *)> processGeneratedConstants = nullptr,
45  function_ref<void(Operation *)> preReplaceAction = nullptr,
46  bool *inPlaceUpdate = nullptr);
47 
48  /// Notifies that the given constant `op` should be remove from this
49  /// OperationFolder's internal bookkeeping.
50  ///
51  /// Note: this method must be called if a constant op is to be deleted
52  /// externally to this OperationFolder. `op` must be a constant op.
53  void notifyRemoval(Operation *op);
54 
55  /// Create an operation of specific op type with the given builder,
56  /// and immediately try to fold it. This function populates 'results' with
57  /// the results after folding the operation.
58  template <typename OpTy, typename... Args>
59  void create(OpBuilder &builder, SmallVectorImpl<Value> &results,
60  Location location, Args &&... args) {
61  // The op needs to be inserted only if the fold (below) fails, or the number
62  // of results produced by the successful folding is zero (which is treated
63  // as an in-place fold). Using create methods of the builder will insert the
64  // op, so not using it here.
65  OperationState state(location, OpTy::getOperationName());
66  OpTy::build(builder, state, std::forward<Args>(args)...);
67  Operation *op = Operation::create(state);
68 
69  if (failed(tryToFold(builder, op, results)) || results.empty()) {
70  builder.insert(op);
71  results.assign(op->result_begin(), op->result_end());
72  return;
73  }
74  op->destroy();
75  }
76 
77  /// Overload to create or fold a single result operation.
78  template <typename OpTy, typename... Args>
79  typename std::enable_if<OpTy::template hasTrait<OpTrait::OneResult>(),
80  Value>::type
81  create(OpBuilder &builder, Location location, Args &&... args) {
82  SmallVector<Value, 1> results;
83  create<OpTy>(builder, results, location, std::forward<Args>(args)...);
84  return results.front();
85  }
86 
87  /// Overload to create or fold a zero result operation.
88  template <typename OpTy, typename... Args>
89  typename std::enable_if<OpTy::template hasTrait<OpTrait::ZeroResult>(),
90  OpTy>::type
91  create(OpBuilder &builder, Location location, Args &&... args) {
92  auto op = builder.create<OpTy>(location, std::forward<Args>(args)...);
93  SmallVector<Value, 0> unused;
94  (void)tryToFold(op.getOperation(), unused);
95 
96  // Folding cannot remove a zero-result operation, so for convenience we
97  // continue to return it.
98  return op;
99  }
100 
101  /// Clear out any constants cached inside of the folder.
102  void clear();
103 
104  /// Get or create a constant using the given builder. On success this returns
105  /// the constant operation, nullptr otherwise.
106  Value getOrCreateConstant(OpBuilder &builder, Dialect *dialect,
107  Attribute value, Type type, Location loc);
108 
109 private:
110  /// This map keeps track of uniqued constants by dialect, attribute, and type.
111  /// A constant operation materializes an attribute with a type. Dialects may
112  /// generate different constants with the same input attribute and type, so we
113  /// also need to track per-dialect.
114  using ConstantMap =
116 
117  /// Tries to perform folding on the given `op`. If successful, populates
118  /// `results` with the results of the folding.
120  OpBuilder &builder, Operation *op, SmallVectorImpl<Value> &results,
121  function_ref<void(Operation *)> processGeneratedConstants = nullptr);
122 
123  /// Try to get or create a new constant entry. On success this returns the
124  /// constant operation, nullptr otherwise.
125  Operation *tryGetOrCreateConstant(ConstantMap &uniquedConstants,
126  Dialect *dialect, OpBuilder &builder,
127  Attribute value, Type type, Location loc);
128 
129  /// A mapping between an insertion region and the constants that have been
130  /// created within it.
132 
133  /// This map tracks all of the dialects that an operation is referenced by;
134  /// given that many dialects may generate the same constant.
136 
137  /// A collection of dialect folder interfaces.
139 };
140 
141 } // namespace mlir
142 
143 #endif // MLIR_TRANSFORMS_FOLDUTILS_H
Include the generated interface declarations.
OperationFolder(MLIRContext *ctx)
Definition: FoldUtils.h:34
OpTy create(Location location, Args &&...args)
Create an operation of specific op type at the current insertion point.
Definition: Builders.h:430
static Operation * create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, ArrayRef< NamedAttribute > attributes, BlockRange successors, unsigned numRegions)
Create a new Operation with the specific fields.
Definition: Operation.cpp:27
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
void create(OpBuilder &builder, SmallVectorImpl< Value > &results, Location location, Args &&... args)
Create an operation of specific op type with the given builder, and immediately try to fold it...
Definition: FoldUtils.h:59
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
Definition: LogicalResult.h:72
A collection of dialect interfaces within a context, for a given concrete interface type...
void destroy()
Destroys this operation and its subclass data.
Definition: Operation.cpp:171
std::enable_if< OpTy::template hasTrait< OpTrait::ZeroResult >), OpTy >::type create(OpBuilder &builder, Location location, Args &&... args)
Overload to create or fold a zero result operation.
Definition: FoldUtils.h:91
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
Operation * insert(Operation *op)
Insert the given operation at the current insertion point and return it.
Definition: Builders.cpp:344
Value getOrCreateConstant(OpBuilder &builder, Dialect *dialect, Attribute value, Type type, Location loc)
Get or create a constant using the given builder.
Definition: FoldUtils.cpp:140
Attributes are known-constant values of operations.
Definition: Attributes.h:24
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:42
This represents an operation in an abstracted form, suitable for use with the builder APIs...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
A utility class for folding operations, and unifying duplicated constants generated along the way...
Definition: FoldUtils.h:32
result_iterator result_end()
Definition: Operation.h:283
std::enable_if< OpTy::template hasTrait< OpTrait::OneResult >), Value >::type create(OpBuilder &builder, Location location, Args &&... args)
Overload to create or fold a single result operation.
Definition: FoldUtils.h:81
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:55
void notifyRemoval(Operation *op)
Notifies that the given constant op should be remove from this OperationFolder&#39;s internal bookkeeping...
Definition: FoldUtils.cpp:109
This class helps build Operations.
Definition: Builders.h:177
void clear()
Clear out any constants cached inside of the folder.
Definition: FoldUtils.cpp:133
result_iterator result_begin()
Definition: Operation.h:282
LogicalResult tryToFold(Operation *op, function_ref< void(Operation *)> processGeneratedConstants=nullptr, function_ref< void(Operation *)> preReplaceAction=nullptr, bool *inPlaceUpdate=nullptr)
Tries to perform folding on the given op, including unifying deduplicated constants.
Definition: FoldUtils.cpp:70