MLIR  22.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"
20 #include "mlir/IR/PatternMatch.h"
22 
23 namespace mlir {
24 class Operation;
25 class Value;
26 
27 //===--------------------------------------------------------------------===//
28 // OperationFolder
29 //===--------------------------------------------------------------------===//
30 
31 /// A utility class for folding operations, and unifying duplicated constants
32 /// generated along the way.
34 public:
35  OperationFolder(MLIRContext *ctx, OpBuilder::Listener *listener = nullptr)
36  : erasedFoldedLocation(UnknownLoc::get(ctx)), interfaces(ctx),
37  rewriter(ctx, listener) {}
38 
39  /// Tries to perform folding on the given `op`, including unifying
40  /// deduplicated constants. If successful, replaces `op`'s uses with
41  /// folded results, and returns success. If the op was completely folded it is
42  /// erased. If it is just updated in place, `inPlaceUpdate` is set to true.
43  /// On success() and when in-place, the folder is invoked until
44  /// `maxIterations` is reached (default INT_MAX).
45  LogicalResult tryToFold(Operation *op, bool *inPlaceUpdate = nullptr,
46  int maxIterations = INT_MAX);
47 
48  /// Tries to fold a pre-existing constant operation. `constValue` represents
49  /// the value of the constant, and can be optionally passed if the value is
50  /// already known (e.g. if the constant was discovered by m_Constant). This is
51  /// purely an optimization opportunity for callers that already know the value
52  /// of the constant. Returns false if an existing constant for `op` already
53  /// exists in the folder, in which case `op` is replaced and erased.
54  /// Otherwise, returns true and `op` is inserted into the folder (and
55  /// hoisted if necessary).
56  bool insertKnownConstant(Operation *op, Attribute constValue = {});
57 
58  /// Notifies that the given constant `op` should be remove from this
59  /// OperationFolder's internal bookkeeping.
60  ///
61  /// Note: this method must be called if a constant op is to be deleted
62  /// externally to this OperationFolder. `op` must be a constant op.
63  void notifyRemoval(Operation *op);
64 
65  /// Clear out any constants cached inside of the folder.
66  void clear();
67 
68  /// Get or create a constant for use in the specified block. The constant may
69  /// be created in a parent block. On success this returns the constant
70  /// operation, nullptr otherwise.
71  Value getOrCreateConstant(Block *block, Dialect *dialect, Attribute value,
72  Type type);
73 
74 private:
75  /// This map keeps track of uniqued constants by dialect, attribute, and type.
76  /// A constant operation materializes an attribute with a type. Dialects may
77  /// generate different constants with the same input attribute and type, so we
78  /// also need to track per-dialect.
79  using ConstantMap =
80  DenseMap<std::tuple<Dialect *, Attribute, Type>, Operation *>;
81 
82  /// Returns true if the given operation is an already folded constant that is
83  /// owned by this folder.
84  bool isFolderOwnedConstant(Operation *op) const;
85 
86  /// Tries to perform folding on the given `op`. If successful, populates
87  /// `results` with the results of the folding.
88  /// On success() and when in-place, the folder is invoked until
89  /// `maxIterations` is reached (default INT_MAX).
90  LogicalResult tryToFold(Operation *op, SmallVectorImpl<Value> &results,
91  int maxIterations = INT_MAX);
92 
93  /// Try to process a set of fold results. Populates `results` on success,
94  /// otherwise leaves it unchanged.
95  LogicalResult processFoldResults(Operation *op,
96  SmallVectorImpl<Value> &results,
97  ArrayRef<OpFoldResult> foldResults);
98 
99  /// Try to get or create a new constant entry. On success this returns the
100  /// constant operation, nullptr otherwise.
101  Operation *tryGetOrCreateConstant(ConstantMap &uniquedConstants,
102  Dialect *dialect, Attribute value,
103  Type type, Location loc);
104 
105  /// The location to overwrite with for folder-owned constants.
106  UnknownLoc erasedFoldedLocation;
107 
108  /// A mapping between an insertion region and the constants that have been
109  /// created within it.
110  DenseMap<Region *, ConstantMap> foldScopes;
111 
112  /// This map tracks all of the dialects that an operation is referenced by;
113  /// given that many dialects may generate the same constant.
114  DenseMap<Operation *, SmallVector<Dialect *, 2>> referencedDialects;
115 
116  /// A collection of dialect folder interfaces.
117  DialectInterfaceCollection<DialectFoldInterface> interfaces;
118 
119  /// A rewriter that performs all IR modifications.
120  IRRewriter rewriter;
121 };
122 
123 } // namespace mlir
124 
125 #endif // MLIR_TRANSFORMS_FOLDUTILS_H
Attributes are known-constant values of operations.
Definition: Attributes.h:25
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:63
A utility class for folding operations, and unifying duplicated constants generated along the way.
Definition: FoldUtils.h:33
Value getOrCreateConstant(Block *block, Dialect *dialect, Attribute value, Type type)
Get or create a constant for use in the specified block.
Definition: FoldUtils.cpp:207
void clear()
Clear out any constants cached inside of the folder.
Definition: FoldUtils.cpp:200
LogicalResult tryToFold(Operation *op, bool *inPlaceUpdate=nullptr, int maxIterations=INT_MAX)
Tries to perform folding on the given op, including unifying deduplicated constants.
Definition: FoldUtils.cpp:71
void notifyRemoval(Operation *op)
Notifies that the given constant op should be remove from this OperationFolder's internal bookkeeping...
Definition: FoldUtils.cpp:176
bool insertKnownConstant(Operation *op, Attribute constValue={})
Tries to fold a pre-existing constant operation.
Definition: FoldUtils.cpp:113
OperationFolder(MLIRContext *ctx, OpBuilder::Listener *listener=nullptr)
Definition: FoldUtils.h:35
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
This class represents a listener that may be used to hook into various actions within an OpBuilder.
Definition: Builders.h:285