MLIR  16.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 "llvm/ADT/EquivalenceClasses.h"
14 
15 namespace mlir {
16 namespace bufferization {
17 
18 struct OneShotBufferizationOptions;
19 class BufferizationAliasInfo;
20 class OneShotAnalysisState;
21 
22 /// Options for analysis-enabled bufferization.
24  OneShotBufferizationOptions() = default;
25 
26  /// Specifies whether returning newly allocated memrefs should be allowed.
27  /// Otherwise, a pass failure is triggered.
28  bool allowReturnAllocs = false;
29 };
30 
31 /// The BufferizationAliasInfo class maintains a list of buffer aliases and
32 /// equivalence classes to support bufferization.
34 public:
35  explicit BufferizationAliasInfo(Operation *rootOp);
36 
37  // BufferizationAliasInfo should be passed as a reference.
39 
40  /// Add a new entry for `v` in the `aliasInfo` and `equivalentInfo`. In the
41  /// beginning the alias and equivalence sets only contain `v` itself.
42  void createAliasInfoEntry(Value v);
43 
44  /// Insert an info entry for `newValue` and merge its alias set with that of
45  /// `alias`.
46  void insertNewBufferAlias(Value newValue, Value alias);
47 
48  /// Insert an info entry for `newValue` and merge its alias set with that of
49  /// `alias`. Additionally, merge their equivalence classes.
50  void insertNewBufferEquivalence(Value newValue, Value alias);
51 
52  /// Set the inPlace bufferization spec to true.
53  /// Merge result's and operand's aliasing sets and iterate to a fixed point.
54  void bufferizeInPlace(OpOperand &operand, AnalysisState &state);
55 
56  /// Set the inPlace bufferization spec to false.
57  void bufferizeOutOfPlace(OpOperand &operand);
58 
59  /// Return true if `v1` and `v2` may bufferize to aliasing buffers.
61  return aliasInfo.isEquivalent(v1, v2);
62  }
63 
64  /// Return true if `v1` and `v2` bufferize to equivalent buffers.
66  return equivalentInfo.isEquivalent(v1, v2);
67  }
68 
69  /// Union the alias sets of `v1` and `v2`.
70  void unionAliasSets(Value v1, Value v2) { aliasInfo.unionSets(v1, v2); }
71 
72  /// Union the equivalence classes of `v1` and `v2`.
74  equivalentInfo.unionSets(v1, v2);
75  }
76 
77  /// Apply `fun` to all the members of the equivalence class of `v`.
78  void applyOnEquivalenceClass(Value v, function_ref<void(Value)> fun) const;
79 
80  /// Apply `fun` to all aliases of `v`.
81  void applyOnAliases(Value v, function_ref<void(Value)> fun) const;
82 
83  /// Mark a value as in-place bufferized.
84  void markInPlace(OpOperand &o) { inplaceBufferized.insert(&o); }
85 
86  /// Return `true` if a value was marked as in-place bufferized.
87  bool isInPlace(OpOperand &opOperand) const;
88 
89 private:
90  /// llvm::EquivalenceClasses wants comparable elements. This comparator uses
91  /// uses pointer comparison on the defining op. This is a poor man's
92  /// comparison but it's not like UnionFind needs ordering anyway.
93  struct ValueComparator {
94  bool operator()(const Value &lhs, const Value &rhs) const {
95  return lhs.getImpl() < rhs.getImpl();
96  }
97  };
98 
100  llvm::EquivalenceClasses<Value, ValueComparator>::member_iterator>;
101  /// Check that aliasInfo for `v` exists and return a reference to it.
102  EquivalenceClassRangeType getAliases(Value v) const;
103 
104  /// Set of all OpResults that were decided to bufferize in-place.
105  llvm::DenseSet<OpOperand *> inplaceBufferized;
106 
107  /// Auxiliary structure to store all the values a given value may alias with.
108  /// Alias information is "may be" conservative: In the presence of branches, a
109  /// value may alias with one of multiple other values. The concrete aliasing
110  /// value may not even be known at compile time. All such values are
111  /// considered to be aliases.
112  llvm::EquivalenceClasses<Value, ValueComparator> aliasInfo;
113 
114  /// Auxiliary structure to store all the equivalent buffer classes. Equivalent
115  /// buffer information is "must be" conservative: Only if two values are
116  /// guaranteed to be equivalent at runtime, they said to be equivalent. It is
117  /// possible that, in the presence of branches, it cannot be determined
118  /// statically if two values are equivalent. In that case, the values are
119  /// considered to be not equivalent.
120  llvm::EquivalenceClasses<Value, ValueComparator> equivalentInfo;
121 };
122 
123 /// State for analysis-enabled bufferization. This class keeps track of alias
124 /// (via BufferizationAliasInfo) to decide if tensor OpOperands should bufferize
125 /// in-place.
127 public:
130 
131  OneShotAnalysisState(const OneShotAnalysisState &) = delete;
132 
133  ~OneShotAnalysisState() override = default;
134 
135  /// Return a reference to the BufferizationAliasInfo.
136  BufferizationAliasInfo &getAliasInfo() { return aliasInfo; }
137 
138  /// Return `true` if the given OpResult has been decided to bufferize inplace.
139  bool isInPlace(OpOperand &opOperand) const override;
140 
141  /// Return true if `v1` and `v2` bufferize to equivalent buffers.
142  bool areEquivalentBufferizedValues(Value v1, Value v2) const override;
143 
144  /// Return true if `v1` and `v2` may bufferize to aliasing buffers.
145  bool areAliasingBufferizedValues(Value v1, Value v2) const override;
146 
147  /// Return `true` if the given tensor has undefined contents.
148  bool hasUndefinedContents(OpOperand *opOperand) const override;
149 
150  /// Return true if the given tensor (or an aliasing tensor) is yielded from
151  /// the containing block. Also include all aliasing tensors in the same block.
152  bool isTensorYielded(Value tensor) const override;
153 
154  /// Find all tensor values in the given operation that have undefined contents
155  /// and store them in `undefinedTensorUses`.
156  void gatherUndefinedTensorUses(Operation *op);
157 
158  /// Find all tensors that are yielded/returned from a block and store them in
159  /// `yieldedTensors`. Also include all aliasing tensors in the same block.
160  void gatherYieldedTensors(Operation *op);
161 
162  /// Return true if the buffer of the given tensor value is written to. Must
163  /// not be called for values inside not yet analyzed functions.
164  bool isValueWritten(Value value) const;
165 
166  /// Return true if the buffer of the given tensor value is writable.
167  bool isWritable(Value value) const;
168 
169 private:
170  /// `aliasInfo` keeps track of aliasing and equivalent values. Only internal
171  /// functions and `runOneShotBufferize` may access this object.
172  BufferizationAliasInfo aliasInfo;
173 
174  /// A set of all tensors (and maybe aliasing tensors) that yielded from a
175  /// block.
176  DenseSet<Value> yieldedTensors;
177 
178  /// A set of uses of tensors that have undefined contents.
179  DenseSet<OpOperand *> undefinedTensorUses;
180 };
181 
182 /// Analyze `op` and its nested ops. Bufferization decisions are stored in
183 /// `state`.
185 
186 /// Run One-Shot Bufferize on the given op: Analysis + Bufferization
189 
190 } // namespace bufferization
191 } // namespace mlir
192 
193 #endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_ONESHOTANALYSIS_H
Include the generated interface declarations.
LogicalResult analyzeOp(Operation *op, OneShotAnalysisState &state)
Analyze op and its nested ops.
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...
static constexpr const bool value
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.
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.
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.