MLIR  18.0.0git
ValueRange.h
Go to the documentation of this file.
1 //===- ValueRange.h - Indexed Value-Iterators Range Classes -----*- 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 file defines the ValueRange related classes.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_IR_VALUERANGE_H
14 #define MLIR_IR_VALUERANGE_H
15 
17 #include "mlir/IR/Types.h"
18 #include "mlir/IR/Value.h"
19 #include "llvm/ADT/PointerUnion.h"
20 #include "llvm/ADT/Sequence.h"
21 #include <optional>
22 
23 namespace mlir {
24 class ValueRange;
25 template <typename ValueRangeT>
26 class ValueTypeRange;
27 class TypeRangeRange;
28 template <typename ValueIteratorT>
29 class ValueTypeIterator;
30 class OperandRangeRange;
31 class MutableOperandRangeRange;
32 
33 //===----------------------------------------------------------------------===//
34 // Operation Value-Iterators
35 //===----------------------------------------------------------------------===//
36 
37 //===----------------------------------------------------------------------===//
38 // OperandRange
39 
40 /// This class implements the operand iterators for the Operation class.
42  OperandRange, OpOperand *, Value, Value, Value> {
43 public:
44  using RangeBaseT::RangeBaseT;
45 
46  /// Returns the types of the values within this range.
49  type_range getTypes() const;
50  type_range getType() const;
51 
52  /// Return the operand index of the first element of this range. The range
53  /// must not be empty.
54  unsigned getBeginOperandIndex() const;
55 
56  /// Split this range into a set of contiguous subranges using the given
57  /// elements attribute, which contains the sizes of the sub ranges.
58  OperandRangeRange split(DenseI32ArrayAttr segmentSizes) const;
59 
60 private:
61  /// See `llvm::detail::indexed_accessor_range_base` for details.
62  static OpOperand *offset_base(OpOperand *object, ptrdiff_t index) {
63  return object + index;
64  }
65  /// See `llvm::detail::indexed_accessor_range_base` for details.
66  static Value dereference_iterator(OpOperand *object, ptrdiff_t index) {
67  return object[index].get();
68  }
69 
70  /// Allow access to `offset_base` and `dereference_iterator`.
71  friend RangeBaseT;
72 };
73 
74 //===----------------------------------------------------------------------===//
75 // OperandRangeRange
76 
77 /// This class represents a contiguous range of operand ranges, e.g. from a
78 /// VariadicOfVariadic operand group.
79 class OperandRangeRange final
80  : public llvm::indexed_accessor_range<
81  OperandRangeRange, std::pair<OpOperand *, Attribute>, OperandRange,
82  OperandRange, OperandRange> {
83  using OwnerT = std::pair<OpOperand *, Attribute>;
84  using RangeBaseT =
85  llvm::indexed_accessor_range<OperandRangeRange, OwnerT, OperandRange,
87 
88 public:
89  using RangeBaseT::RangeBaseT;
90 
91  /// Returns the range of types of the values within this range.
92  TypeRangeRange getTypes() const;
93  TypeRangeRange getType() const;
94 
95  /// Construct a range given a parent set of operands, and an I32 elements
96  /// attribute containing the sizes of the sub ranges.
97  OperandRangeRange(OperandRange operands, Attribute operandSegments);
98 
99  /// Flatten all of the sub ranges into a single contiguous operand range.
100  OperandRange join() const;
101 
102 private:
103  /// See `llvm::indexed_accessor_range` for details.
104  static OperandRange dereference(const OwnerT &object, ptrdiff_t index);
105 
106  /// Allow access to `dereference_iterator`.
107  friend RangeBaseT;
108 };
109 
110 //===----------------------------------------------------------------------===//
111 // MutableOperandRange
112 
113 /// This class provides a mutable adaptor for a range of operands. It allows for
114 /// setting, inserting, and erasing operands from the given range.
116 public:
117  /// A pair of a named attribute corresponding to an operand segment attribute,
118  /// and the index within that attribute. The attribute should correspond to a
119  /// dense i32 array attr.
120  using OperandSegment = std::pair<unsigned, NamedAttribute>;
121 
122  /// Construct a new mutable range from the given operand, operand start index,
123  /// and range length. `operandSegments` is an optional set of operand segments
124  /// to be updated when mutating the operand list.
125  MutableOperandRange(Operation *owner, unsigned start, unsigned length,
126  ArrayRef<OperandSegment> operandSegments = std::nullopt);
128 
129  /// Slice this range into a sub range, with the additional operand segment.
131  slice(unsigned subStart, unsigned subLen,
132  std::optional<OperandSegment> segment = std::nullopt) const;
133 
134  /// Append the given values to the range.
135  void append(ValueRange values);
136 
137  /// Assign this range to the given values.
138  void assign(ValueRange values);
139 
140  /// Assign the range to the given value.
141  void assign(Value value);
142 
143  /// Erase the operands within the given sub-range.
144  void erase(unsigned subStart, unsigned subLen = 1);
145 
146  /// Clear this range and erase all of the operands.
147  void clear();
148 
149  /// Returns the current size of the range.
150  unsigned size() const { return length; }
151 
152  /// Returns if the current range is empty.
153  bool empty() const { return size() == 0; }
154 
155  /// Allow implicit conversion to an OperandRange.
156  operator OperandRange() const;
157 
158  /// Returns the owning operation.
159  Operation *getOwner() const { return owner; }
160 
161  /// Split this range into a set of contiguous subranges using the given
162  /// elements attribute, which contains the sizes of the sub ranges.
163  MutableOperandRangeRange split(NamedAttribute segmentSizes) const;
164 
165  /// Returns the OpOperand at the given index.
166  OpOperand &operator[](unsigned index) const;
167 
168  /// Iterators enumerate OpOperands.
171 
172 private:
173  /// Update the length of this range to the one provided.
174  void updateLength(unsigned newLength);
175 
176  /// The owning operation of this range.
177  Operation *owner;
178 
179  /// The start index of the operand range within the owner operand list, and
180  /// the length starting from `start`.
181  unsigned start, length;
182 
183  /// Optional set of operand segments that should be updated when mutating the
184  /// length of this range.
185  SmallVector<OperandSegment, 1> operandSegments;
186 };
187 
188 //===----------------------------------------------------------------------===//
189 // MutableOperandRangeRange
190 
191 /// This class represents a contiguous range of mutable operand ranges, e.g.
192 /// from a VariadicOfVariadic operand group.
194  : public llvm::indexed_accessor_range<
195  MutableOperandRangeRange,
196  std::pair<MutableOperandRange, NamedAttribute>, MutableOperandRange,
197  MutableOperandRange, MutableOperandRange> {
198  using OwnerT = std::pair<MutableOperandRange, NamedAttribute>;
199  using RangeBaseT =
200  llvm::indexed_accessor_range<MutableOperandRangeRange, OwnerT,
203 
204 public:
205  using RangeBaseT::RangeBaseT;
206 
207  /// Construct a range given a parent set of operands, and an I32 tensor
208  /// elements attribute containing the sizes of the sub ranges.
210  NamedAttribute operandSegmentAttr);
211 
212  /// Flatten all of the sub ranges into a single contiguous mutable operand
213  /// range.
214  MutableOperandRange join() const;
215 
216  /// Allow implicit conversion to an OperandRangeRange.
217  operator OperandRangeRange() const;
218 
219 private:
220  /// See `llvm::indexed_accessor_range` for details.
221  static MutableOperandRange dereference(const OwnerT &object, ptrdiff_t index);
222 
223  /// Allow access to `dereference_iterator`.
224  friend RangeBaseT;
225 };
226 
227 //===----------------------------------------------------------------------===//
228 // ResultRange
229 
230 /// This class implements the result iterators for the Operation class.
231 class ResultRange final
233  ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
234 public:
235  using RangeBaseT::RangeBaseT;
236  ResultRange(OpResult result);
237 
238  //===--------------------------------------------------------------------===//
239  // Types
240  //===--------------------------------------------------------------------===//
241 
242  /// Returns the types of the values within this range.
245  type_range getTypes() const;
246  type_range getType() const;
247 
248  //===--------------------------------------------------------------------===//
249  // Uses
250  //===--------------------------------------------------------------------===//
251 
252  class UseIterator;
255 
256  /// Returns a range of all uses of results within this range, which is useful
257  /// for iterating over all uses.
258  use_range getUses() const;
259  use_iterator use_begin() const;
260  use_iterator use_end() const;
261 
262  /// Returns true if no results in this range have uses.
263  bool use_empty() const {
264  return llvm::all_of(*this,
265  [](OpResult result) { return result.use_empty(); });
266  }
267 
268  /// Replace all uses of results of this range with the provided 'values'. The
269  /// size of `values` must match the size of this range.
270  template <typename ValuesT>
271  std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
272  replaceAllUsesWith(ValuesT &&values) {
273  assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
274  size() &&
275  "expected 'values' to correspond 1-1 with the number of results");
276 
277  for (auto it : llvm::zip(*this, values))
278  std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
279  }
280 
281  /// Replace all uses of results of this range with results of 'op'.
282  void replaceAllUsesWith(Operation *op);
283 
284  /// Replace uses of results of this range with the provided 'values' if the
285  /// given callback returns true. The size of `values` must match the size of
286  /// this range.
287  template <typename ValuesT>
288  std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
289  replaceUsesWithIf(ValuesT &&values,
290  function_ref<bool(OpOperand &)> shouldReplace) {
291  assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
292  size() &&
293  "expected 'values' to correspond 1-1 with the number of results");
294 
295  for (auto it : llvm::zip(*this, values))
296  std::get<0>(it).replaceUsesWithIf(std::get<1>(it), shouldReplace);
297  }
298 
299  /// Replace uses of results of this range with results of `op` if the given
300  /// callback returns true.
301  void replaceUsesWithIf(Operation *op,
302  function_ref<bool(OpOperand &)> shouldReplace);
303 
304  //===--------------------------------------------------------------------===//
305  // Users
306  //===--------------------------------------------------------------------===//
307 
310 
311  /// Returns a range of all users.
315 
316 private:
317  /// See `llvm::detail::indexed_accessor_range_base` for details.
318  static detail::OpResultImpl *offset_base(detail::OpResultImpl *object,
319  ptrdiff_t index) {
320  return object->getNextResultAtOffset(index);
321  }
322  /// See `llvm::detail::indexed_accessor_range_base` for details.
323  static OpResult dereference_iterator(detail::OpResultImpl *object,
324  ptrdiff_t index) {
325  return offset_base(object, index);
326  }
327 
328  /// Allow access to `offset_base` and `dereference_iterator`.
329  friend RangeBaseT;
330 };
331 
332 /// This class implements a use iterator for a range of operation results.
333 /// This iterates over all uses of all results within the given result range.
335  : public llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
336  OpOperand> {
337 public:
338  /// Initialize the UseIterator. Specify `end` to return iterator to last
339  /// use, otherwise this is an iterator to the first use.
340  explicit UseIterator(ResultRange results, bool end = false);
341 
342  using llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
343  OpOperand>::operator++;
345  OpOperand *operator->() const { return use.getOperand(); }
346  OpOperand &operator*() const { return *use.getOperand(); }
347 
348  bool operator==(const UseIterator &rhs) const { return use == rhs.use; }
349  bool operator!=(const UseIterator &rhs) const { return !(*this == rhs); }
350 
351 private:
352  void skipOverResultsWithNoUsers();
353 
354  /// The range of results being iterated over.
355  ResultRange::iterator it, endIt;
356  /// The use of the result.
358 };
359 
360 //===----------------------------------------------------------------------===//
361 // ValueRange
362 
363 /// This class provides an abstraction over the different types of ranges over
364 /// Values. In many cases, this prevents the need to explicitly materialize a
365 /// SmallVector/std::vector. This class should be used in places that are not
366 /// suitable for a more derived type (e.g. ArrayRef) or a template range
367 /// parameter.
368 class ValueRange final
370  ValueRange,
371  PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
372  Value, Value, Value> {
373 public:
374  /// The type representing the owner of a ValueRange. This is either a list of
375  /// values, operands, or results.
376  using OwnerT =
378 
379  using RangeBaseT::RangeBaseT;
380 
381  template <typename Arg,
382  typename = std::enable_if_t<
383  std::is_constructible<ArrayRef<Value>, Arg>::value &&
384  !std::is_convertible<Arg, Value>::value>>
385  ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
386  ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
387  ValueRange(const std::initializer_list<Value> &values)
388  : ValueRange(ArrayRef<Value>(values)) {}
390  : ValueRange(OperandRange(values)) {}
392  : ValueRange(ResultRange(values)) {}
394  : ValueRange(ArrayRef<Value>(values.data(), values.size())) {}
395  ValueRange(ArrayRef<Value> values = std::nullopt);
398 
399  /// Returns the types of the values within this range.
404 
405 private:
406  /// See `llvm::detail::indexed_accessor_range_base` for details.
407  static OwnerT offset_base(const OwnerT &owner, ptrdiff_t index);
408  /// See `llvm::detail::indexed_accessor_range_base` for details.
409  static Value dereference_iterator(const OwnerT &owner, ptrdiff_t index);
410 
411  /// Allow access to `offset_base` and `dereference_iterator`.
412  friend RangeBaseT;
413 };
414 
415 } // namespace mlir
416 
417 #endif // MLIR_IR_VALUERANGE_H
Attributes are known-constant values of operations.
Definition: Attributes.h:25
This class represents a contiguous range of mutable operand ranges, e.g.
Definition: ValueRange.h:197
MutableOperandRange join() const
Flatten all of the sub ranges into a single contiguous mutable operand range.
MutableOperandRangeRange(const MutableOperandRange &operands, NamedAttribute operandSegmentAttr)
Construct a range given a parent set of operands, and an I32 tensor elements attribute containing the...
This class provides a mutable adaptor for a range of operands.
Definition: ValueRange.h:115
unsigned size() const
Returns the current size of the range.
Definition: ValueRange.h:150
void assign(ValueRange values)
Assign this range to the given values.
MutableOperandRange slice(unsigned subStart, unsigned subLen, std::optional< OperandSegment > segment=std::nullopt) const
Slice this range into a sub range, with the additional operand segment.
MutableArrayRef< OpOperand >::iterator end() const
void erase(unsigned subStart, unsigned subLen=1)
Erase the operands within the given sub-range.
void append(ValueRange values)
Append the given values to the range.
bool empty() const
Returns if the current range is empty.
Definition: ValueRange.h:153
void clear()
Clear this range and erase all of the operands.
MutableOperandRange(Operation *owner, unsigned start, unsigned length, ArrayRef< OperandSegment > operandSegments=std::nullopt)
Construct a new mutable range from the given operand, operand start index, and range length.
MutableArrayRef< OpOperand >::iterator begin() const
Iterators enumerate OpOperands.
Operation * getOwner() const
Returns the owning operation.
Definition: ValueRange.h:159
std::pair< unsigned, NamedAttribute > OperandSegment
A pair of a named attribute corresponding to an operand segment attribute, and the index within that ...
Definition: ValueRange.h:120
MutableOperandRangeRange split(NamedAttribute segmentSizes) const
Split this range into a set of contiguous subranges using the given elements attribute,...
OpOperand & operator[](unsigned index) const
Returns the OpOperand at the given index.
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:198
This class represents an operand of an operation.
Definition: Value.h:261
This is a value defined by a result of an operation.
Definition: Value.h:448
This class represents a contiguous range of operand ranges, e.g.
Definition: ValueRange.h:82
OperandRangeRange(OperandRange operands, Attribute operandSegments)
Construct a range given a parent set of operands, and an I32 elements attribute containing the sizes ...
OperandRange join() const
Flatten all of the sub ranges into a single contiguous operand range.
TypeRangeRange getTypes() const
Returns the range of types of the values within this range.
Definition: ValueRange.cpp:17
TypeRangeRange getType() const
Definition: ValueRange.cpp:21
This class implements the operand iterators for the Operation class.
Definition: ValueRange.h:42
unsigned getBeginOperandIndex() const
Return the operand index of the first element of this range.
type_range getType() const
Definition: ValueRange.cpp:30
type_range getTypes() const
Definition: ValueRange.cpp:26
OperandRangeRange split(DenseI32ArrayAttr segmentSizes) const
Split this range into a set of contiguous subranges using the given elements attribute,...
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class implements a use iterator for a range of operation results.
Definition: ValueRange.h:336
bool operator!=(const UseIterator &rhs) const
Definition: ValueRange.h:349
UseIterator(ResultRange results, bool end=false)
Initialize the UseIterator.
OpOperand * operator->() const
Definition: ValueRange.h:345
bool operator==(const UseIterator &rhs) const
Definition: ValueRange.h:348
OpOperand & operator*() const
Definition: ValueRange.h:346
This class implements the result iterators for the Operation class.
Definition: ValueRange.h:233
use_range getUses() const
Returns a range of all uses of results within this range, which is useful for iterating over all uses...
bool use_empty() const
Returns true if no results in this range have uses.
Definition: ValueRange.h:263
use_iterator use_begin() const
user_range getUsers()
Returns a range of all users.
ResultRange(OpResult result)
use_iterator use_end() const
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceUsesWithIf(ValuesT &&values, function_ref< bool(OpOperand &)> shouldReplace)
Replace uses of results of this range with the provided 'values' if the given callback returns true.
Definition: ValueRange.h:289
type_range getTypes() const
Definition: ValueRange.cpp:35
user_iterator user_end()
std::enable_if_t<!std::is_convertible< ValuesT, Operation * >::value > replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this range with the provided 'values'.
Definition: ValueRange.h:272
user_iterator user_begin()
type_range getType() const
Definition: ValueRange.cpp:39
This class provides an abstraction for a range of TypeRange.
Definition: TypeRange.h:92
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:372
ValueRange(ResultRange values)
ValueRange(iterator_range< OperandRange::iterator > values)
Definition: ValueRange.h:389
ValueRange(OperandRange values)
ValueRange(Arg &&arg)
Definition: ValueRange.h:385
ValueRange(iterator_range< ResultRange::iterator > values)
Definition: ValueRange.h:391
ValueRange(ArrayRef< BlockArgument > values)
Definition: ValueRange.h:393
type_range getType() const
type_range getTypes() const
ValueRange(ArrayRef< Value > values=std::nullopt)
ValueRange(const std::initializer_list< Value > &values)
Definition: ValueRange.h:387
ValueRange(const Value &value)
Definition: ValueRange.h:386
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:118
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:131
OperandType * getOperand() const
Returns the current operands.
Definition: UseDefLists.h:304
An iterator over the users of an IRObject.
Definition: UseDefLists.h:334
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:93
bool use_empty() const
Returns true if this value has no uses.
Definition: Value.h:212
This class provides the implementation for an operation result.
Definition: Value.h:359
OpResultImpl * getNextResultAtOffset(intptr_t offset)
Returns the next operation result at offset after this result.
Definition: Value.cpp:135
This header declares functions that assist transformations in the MemRef dialect.