MLIR  15.0.0git
OneShotAnalysis.h
Go to the documentation of this file.
1 //===- OneShotAnalysis.h - One-Shot (Single Pass) Analysis ------*- 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 #ifndef MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_ONESHOTANALYSIS_H
10 #define MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_ONESHOTANALYSIS_H
11 
13 #include "mlir/IR/BuiltinOps.h"
14 #include "llvm/ADT/EquivalenceClasses.h"
15 
16 namespace mlir {
17 namespace bufferization {
18 
19 struct OneShotBufferizationOptions;
20 class BufferizationAliasInfo;
21 class OneShotAnalysisState;
22 
23 /// PostAnalysisStepFns can be registered with `BufferizationOptions` and are
24 /// executed after the analysis, but before bufferization. They can be used to
25 /// implement custom dialect-specific optimizations. They may modify the IR, but
26 /// must keep `aliasInfo` consistent. Newly created operations and operations
27 /// that should be re-analyzed must be added to `newOps`.
28 using PostAnalysisStepFn = std::function<LogicalResult(
29  Operation *, AnalysisState &, BufferizationAliasInfo &,
31 
33 
34 /// Options for analysis-enabled bufferization.
36  OneShotBufferizationOptions() = default;
37 
38  /// Register a "post analysis" step. Such steps are executed after the
39  /// analysis, but before bufferization.
41  postAnalysisSteps.push_back(fn);
42  }
43 
44  /// Registered post analysis steps.
46 
47  /// Specifies whether returning newly allocated memrefs should be allowed.
48  /// Otherwise, a pass failure is triggered.
49  bool allowReturnAllocs = false;
50 
51  /// Specifies whether buffer return values that are equivalent to a FuncOp
52  /// bbArg should be dropped.
54 };
55 
56 /// The BufferizationAliasInfo class maintains a list of buffer aliases and
57 /// equivalence classes to support bufferization.
59 public:
60  explicit BufferizationAliasInfo(Operation *rootOp);
61 
62  // BufferizationAliasInfo should be passed as a reference.
64 
65  /// Add a new entry for `v` in the `aliasInfo` and `equivalentInfo`. In the
66  /// beginning the alias and equivalence sets only contain `v` itself.
67  void createAliasInfoEntry(Value v);
68 
69  /// Insert an info entry for `newValue` and merge its alias set with that of
70  /// `alias`.
71  void insertNewBufferAlias(Value newValue, Value alias);
72 
73  /// Insert an info entry for `newValue` and merge its alias set with that of
74  /// `alias`. Additionally, merge their equivalence classes.
75  void insertNewBufferEquivalence(Value newValue, Value alias);
76 
77  /// Set the inPlace bufferization spec to true.
78  /// Merge result's and operand's aliasing sets and iterate to a fixed point.
79  void bufferizeInPlace(OpOperand &operand, AnalysisState &state);
80 
81  /// Set the inPlace bufferization spec to false.
82  void bufferizeOutOfPlace(OpOperand &operand);
83 
84  /// Return true if `v1` and `v2` may bufferize to aliasing buffers.
86  return aliasInfo.isEquivalent(v1, v2);
87  }
88 
89  /// Return true if `v1` and `v2` bufferize to equivalent buffers.
91  return equivalentInfo.isEquivalent(v1, v2);
92  }
93 
94  /// Union the alias sets of `v1` and `v2`.
95  void unionAliasSets(Value v1, Value v2) { aliasInfo.unionSets(v1, v2); }
96 
97  /// Union the equivalence classes of `v1` and `v2`.
99  equivalentInfo.unionSets(v1, v2);
100  }
101 
102  /// Apply `fun` to all the members of the equivalence class of `v`.
103  void applyOnEquivalenceClass(Value v, function_ref<void(Value)> fun) const;
104 
105  /// Apply `fun` to all aliases of `v`.
106  void applyOnAliases(Value v, function_ref<void(Value)> fun) const;
107 
108  /// Mark a value as in-place bufferized.
109  void markInPlace(OpOperand &o) { inplaceBufferized.insert(&o); }
110 
111  /// Return `true` if a value was marked as in-place bufferized.
112  bool isInPlace(OpOperand &opOperand) const;
113 
114 private:
115  /// llvm::EquivalenceClasses wants comparable elements. This comparator uses
116  /// uses pointer comparison on the defining op. This is a poor man's
117  /// comparison but it's not like UnionFind needs ordering anyway.
118  struct ValueComparator {
119  bool operator()(const Value &lhs, const Value &rhs) const {
120  return lhs.getImpl() < rhs.getImpl();
121  }
122  };
123 
125  llvm::EquivalenceClasses<Value, ValueComparator>::member_iterator>;
126  /// Check that aliasInfo for `v` exists and return a reference to it.
127  EquivalenceClassRangeType getAliases(Value v) const;
128 
129  /// Set of all OpResults that were decided to bufferize in-place.
130  llvm::DenseSet<OpOperand *> inplaceBufferized;
131 
132  /// Auxiliary structure to store all the values a given value may alias with.
133  /// Alias information is "may be" conservative: In the presence of branches, a
134  /// value may alias with one of multiple other values. The concrete aliasing
135  /// value may not even be known at compile time. All such values are
136  /// considered to be aliases.
137  llvm::EquivalenceClasses<Value, ValueComparator> aliasInfo;
138 
139  /// Auxiliary structure to store all the equivalent buffer classes. Equivalent
140  /// buffer information is "must be" conservative: Only if two values are
141  /// guaranteed to be equivalent at runtime, they said to be equivalent. It is
142  /// possible that, in the presence of branches, it cannot be determined
143  /// statically if two values are equivalent. In that case, the values are
144  /// considered to be not equivalent.
145  llvm::EquivalenceClasses<Value, ValueComparator> equivalentInfo;
146 };
147 
148 /// State for analysis-enabled bufferization. This class keeps track of alias
149 /// (via BufferizationAliasInfo) to decide if tensor OpOperands should bufferize
150 /// in-place.
152 public:
155 
156  OneShotAnalysisState(const OneShotAnalysisState &) = delete;
157 
158  virtual ~OneShotAnalysisState() = default;
159 
160  /// Return a reference to the BufferizationAliasInfo.
161  BufferizationAliasInfo &getAliasInfo() { return aliasInfo; }
162 
163  /// Return `true` if the given OpResult has been decided to bufferize inplace.
164  bool isInPlace(OpOperand &opOperand) const override;
165 
166  /// Return true if `v1` and `v2` bufferize to equivalent buffers.
167  bool areEquivalentBufferizedValues(Value v1, Value v2) const override;
168 
169  /// Return `true` if the given tensor has undefined contents.
170  bool hasUndefinedContents(OpOperand *opOperand) const override;
171 
172  /// Return true if the given tensor (or an aliasing tensor) is yielded from
173  /// the containing block. Also include all aliasing tensors in the same block.
174  bool isTensorYielded(Value tensor) const override;
175 
176  /// Find all tensor values in the given operation that have undefined contents
177  /// and store them in `undefinedTensorUses`.
178  void gatherUndefinedTensorUses(Operation *op);
179 
180  /// Find all tensors that are yielded/returned from a block and store them in
181  /// `yieldedTensors`. Also include all aliasing tensors in the same block.
182  void gatherYieldedTensors(Operation *op);
183 
184 private:
185  /// `aliasInfo` keeps track of aliasing and equivalent values. Only internal
186  /// functions and `runOneShotBufferize` may access this object.
187  BufferizationAliasInfo aliasInfo;
188 
189  /// A set of all tensors (and maybe aliasing tensors) that yielded from a
190  /// block.
191  DenseSet<Value> yieldedTensors;
192 
193  /// A set of uses of tensors that have undefined contents.
194  DenseSet<OpOperand *> undefinedTensorUses;
195 };
196 
197 /// Analyze `op` and its nested ops. Bufferization decisions are stored in
198 /// `state`.
200 
201 /// Run One-Shot Bufferize on the given op: Analysis + Bufferization
204 
205 } // namespace bufferization
206 } // namespace mlir
207 
208 #endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_ONESHOTANALYSIS_H
Include the generated interface declarations.
LogicalResult analyzeOp(Operation *op, OneShotAnalysisState &state)
Analyze op and its nested ops.
bool dropEquivalentFuncResults
Specifies whether buffer return values that are equivalent to a FuncOp bbArg should be dropped...
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
bool allowReturnAllocs
Specifies whether returning newly allocated memrefs should be allowed.
bool areEquivalentBufferizedValues(Value v1, Value v2) const
Return true if v1 and v2 bufferize to equivalent buffers.
void unionEquivalenceClasses(Value v1, Value v2)
Union the equivalence classes of v1 and v2.
The BufferizationAliasInfo class maintains a list of buffer aliases and equivalence classes to suppor...
PostAnalysisStepList postAnalysisSteps
Registered post analysis steps.
AnalysisState provides a variety of helper functions for dealing with tensor values.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
bool areAliasingBufferizedValues(Value v1, Value v2) const
Return true if v1 and v2 may bufferize to aliasing buffers.
void addPostAnalysisStep(PostAnalysisStepFn fn)
Register a "post analysis" step.
std::function< LogicalResult(Operation *, AnalysisState &, BufferizationAliasInfo &, SmallVector< Operation * > &)> PostAnalysisStepFn
PostAnalysisStepFns can be registered with BufferizationOptions and are executed after the analysis...
Options for BufferizableOpInterface-based bufferization.
void markInPlace(OpOperand &o)
Mark a value as in-place bufferized.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
static llvm::ManagedStatic< PassManagerOptions > options
LogicalResult runOneShotBufferize(Operation *op, const OneShotBufferizationOptions &options)
Run One-Shot Bufferize on the given op: Analysis + Bufferization.
static bool isInPlace(Value val)
Returns true if tensor has an in-place annotation.
State for analysis-enabled bufferization.
void unionAliasSets(Value v1, Value v2)
Union the alias sets of v1 and v2.
This class represents an operand of an operation.
Definition: Value.h:251
BufferizationAliasInfo & getAliasInfo()
Return a reference to the BufferizationAliasInfo.
detail::ValueImpl * getImpl() const
Definition: Value.h:231
Options for analysis-enabled bufferization.