MLIR  19.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  /// Construct a new mutable range for the given OpOperand.
130  MutableOperandRange(OpOperand &opOperand);
131 
132  /// Slice this range into a sub range, with the additional operand segment.
134  slice(unsigned subStart, unsigned subLen,
135  std::optional<OperandSegment> segment = std::nullopt) const;
136 
137  /// Append the given values to the range.
138  void append(ValueRange values);
139 
140  /// Assign this range to the given values.
141  void assign(ValueRange values);
142 
143  /// Assign the range to the given value.
144  void assign(Value value);
145 
146  /// Erase the operands within the given sub-range.
147  void erase(unsigned subStart, unsigned subLen = 1);
148 
149  /// Clear this range and erase all of the operands.
150  void clear();
151 
152  /// Returns the current size of the range.
153  unsigned size() const { return length; }
154 
155  /// Returns if the current range is empty.
156  bool empty() const { return size() == 0; }
157 
158  /// Allow implicit conversion to an OperandRange.
159  operator OperandRange() const;
160 
161  /// Allow implicit conversion to a MutableArrayRef.
162  operator MutableArrayRef<OpOperand>() const;
163 
164  /// Returns the owning operation.
165  Operation *getOwner() const { return owner; }
166 
167  /// Split this range into a set of contiguous subranges using the given
168  /// elements attribute, which contains the sizes of the sub ranges.
169  MutableOperandRangeRange split(NamedAttribute segmentSizes) const;
170 
171  /// Returns the OpOperand at the given index.
172  OpOperand &operator[](unsigned index) const;
173 
174  /// Iterators enumerate OpOperands.
177 
178 private:
179  /// Update the length of this range to the one provided.
180  void updateLength(unsigned newLength);
181 
182  /// The owning operation of this range.
183  Operation *owner;
184 
185  /// The start index of the operand range within the owner operand list, and
186  /// the length starting from `start`.
187  unsigned start, length;
188 
189  /// Optional set of operand segments that should be updated when mutating the
190  /// length of this range.
191  SmallVector<OperandSegment, 1> operandSegments;
192 };
193 
194 //===----------------------------------------------------------------------===//
195 // MutableOperandRangeRange
196 
197 /// This class represents a contiguous range of mutable operand ranges, e.g.
198 /// from a VariadicOfVariadic operand group.
200  : public llvm::indexed_accessor_range<
201  MutableOperandRangeRange,
202  std::pair<MutableOperandRange, NamedAttribute>, MutableOperandRange,
203  MutableOperandRange, MutableOperandRange> {
204  using OwnerT = std::pair<MutableOperandRange, NamedAttribute>;
205  using RangeBaseT =
206  llvm::indexed_accessor_range<MutableOperandRangeRange, OwnerT,
209 
210 public:
211  using RangeBaseT::RangeBaseT;
212 
213  /// Construct a range given a parent set of operands, and an I32 tensor
214  /// elements attribute containing the sizes of the sub ranges.
216  NamedAttribute operandSegmentAttr);
217 
218  /// Flatten all of the sub ranges into a single contiguous mutable operand
219  /// range.
220  MutableOperandRange join() const;
221 
222  /// Allow implicit conversion to an OperandRangeRange.
223  operator OperandRangeRange() const;
224 
225 private:
226  /// See `llvm::indexed_accessor_range` for details.
227  static MutableOperandRange dereference(const OwnerT &object, ptrdiff_t index);
228 
229  /// Allow access to `dereference_iterator`.
230  friend RangeBaseT;
231 };
232 
233 //===----------------------------------------------------------------------===//
234 // ResultRange
235 
236 /// This class implements the result iterators for the Operation class.
237 class ResultRange final
239  ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
240 public:
241  using RangeBaseT::RangeBaseT;
242  ResultRange(OpResult result);
243 
244  //===--------------------------------------------------------------------===//
245  // Types
246  //===--------------------------------------------------------------------===//
247 
248  /// Returns the types of the values within this range.
251  type_range getTypes() const;
252  type_range getType() const;
253 
254  //===--------------------------------------------------------------------===//
255  // Uses
256  //===--------------------------------------------------------------------===//
257 
258  class UseIterator;
261 
262  /// Returns a range of all uses of results within this range, which is useful
263  /// for iterating over all uses.
264  use_range getUses() const;
265  use_iterator use_begin() const;
266  use_iterator use_end() const;
267 
268  /// Returns true if no results in this range have uses.
269  bool use_empty() const {
270  return llvm::all_of(*this,
271  [](OpResult result) { return result.use_empty(); });
272  }
273 
274  /// Replace all uses of results of this range with the provided 'values'. The
275  /// size of `values` must match the size of this range.
276  template <typename ValuesT>
277  std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
278  replaceAllUsesWith(ValuesT &&values) {
279  assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
280  size() &&
281  "expected 'values' to correspond 1-1 with the number of results");
282 
283  for (auto it : llvm::zip(*this, values))
284  std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
285  }
286 
287  /// Replace all uses of results of this range with results of 'op'.
288  void replaceAllUsesWith(Operation *op);
289 
290  /// Replace uses of results of this range with the provided 'values' if the
291  /// given callback returns true. The size of `values` must match the size of
292  /// this range.
293  template <typename ValuesT>
294  std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
295  replaceUsesWithIf(ValuesT &&values,
296  function_ref<bool(OpOperand &)> shouldReplace) {
297  assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
298  size() &&
299  "expected 'values' to correspond 1-1 with the number of results");
300 
301  for (auto it : llvm::zip(*this, values))
302  std::get<0>(it).replaceUsesWithIf(std::get<1>(it), shouldReplace);
303  }
304 
305  /// Replace uses of results of this range with results of `op` if the given
306  /// callback returns true.
307  void replaceUsesWithIf(Operation *op,
308  function_ref<bool(OpOperand &)> shouldReplace);
309 
310  //===--------------------------------------------------------------------===//
311  // Users
312  //===--------------------------------------------------------------------===//
313 
316 
317  /// Returns a range of all users.
321 
322 private:
323  /// See `llvm::detail::indexed_accessor_range_base` for details.
324  static detail::OpResultImpl *offset_base(detail::OpResultImpl *object,
325  ptrdiff_t index) {
326  return object->getNextResultAtOffset(index);
327  }
328  /// See `llvm::detail::indexed_accessor_range_base` for details.
329  static OpResult dereference_iterator(detail::OpResultImpl *object,
330  ptrdiff_t index) {
331  return offset_base(object, index);
332  }
333 
334  /// Allow access to `offset_base` and `dereference_iterator`.
335  friend RangeBaseT;
336 };
337 
338 /// This class implements a use iterator for a range of operation results.
339 /// This iterates over all uses of all results within the given result range.
341  : public llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
342  OpOperand> {
343 public:
344  /// Initialize the UseIterator. Specify `end` to return iterator to last
345  /// use, otherwise this is an iterator to the first use.
346  explicit UseIterator(ResultRange results, bool end = false);
347 
348  using llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
349  OpOperand>::operator++;
351  OpOperand *operator->() const { return use.getOperand(); }
352  OpOperand &operator*() const { return *use.getOperand(); }
353 
354  bool operator==(const UseIterator &rhs) const { return use == rhs.use; }
355  bool operator!=(const UseIterator &rhs) const { return !(*this == rhs); }
356 
357 private:
358  void skipOverResultsWithNoUsers();
359 
360  /// The range of results being iterated over.
361  ResultRange::iterator it, endIt;
362  /// The use of the result.
364 };
365 
366 //===----------------------------------------------------------------------===//
367 // ValueRange
368 
369 /// This class provides an abstraction over the different types of ranges over
370 /// Values. In many cases, this prevents the need to explicitly materialize a
371 /// SmallVector/std::vector. This class should be used in places that are not
372 /// suitable for a more derived type (e.g. ArrayRef) or a template range
373 /// parameter.
374 class ValueRange final
376  ValueRange,
377  PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
378  Value, Value, Value> {
379 public:
380  /// The type representing the owner of a ValueRange. This is either a list of
381  /// values, operands, or results.
382  using OwnerT =
384 
385  using RangeBaseT::RangeBaseT;
386 
387  template <typename Arg,
388  typename = std::enable_if_t<
389  std::is_constructible<ArrayRef<Value>, Arg>::value &&
390  !std::is_convertible<Arg, Value>::value>>
391  ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
392  ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
393  ValueRange(const std::initializer_list<Value> &values)
394  : ValueRange(ArrayRef<Value>(values)) {}
396  : ValueRange(OperandRange(values)) {}
398  : ValueRange(ResultRange(values)) {}
400  : ValueRange(ArrayRef<Value>(values.data(), values.size())) {}
401  ValueRange(ArrayRef<Value> values = std::nullopt);
404 
405  /// Returns the types of the values within this range.
410 
411 private:
412  /// See `llvm::detail::indexed_accessor_range_base` for details.
413  static OwnerT offset_base(const OwnerT &owner, ptrdiff_t index);
414  /// See `llvm::detail::indexed_accessor_range_base` for details.
415  static Value dereference_iterator(const OwnerT &owner, ptrdiff_t index);
416 
417  /// Allow access to `offset_base` and `dereference_iterator`.
418  friend RangeBaseT;
419 };
420 
421 } // namespace mlir
422 
423 #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:203
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:153
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:156
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:165
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:202
This class represents an operand of an operation.
Definition: Value.h:263
This is a value defined by a result of an operation.
Definition: Value.h:453
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:342
bool operator!=(const UseIterator &rhs) const
Definition: ValueRange.h:355
UseIterator(ResultRange results, bool end=false)
Initialize the UseIterator.
OpOperand * operator->() const
Definition: ValueRange.h:351
bool operator==(const UseIterator &rhs) const
Definition: ValueRange.h:354
OpOperand & operator*() const
Definition: ValueRange.h:352
This class implements the result iterators for the Operation class.
Definition: ValueRange.h:239
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:269
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:295
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:278
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:378
ValueRange(ResultRange values)
ValueRange(iterator_range< OperandRange::iterator > values)
Definition: ValueRange.h:395
ValueRange(OperandRange values)
ValueRange(Arg &&arg)
Definition: ValueRange.h:391
ValueRange(iterator_range< ResultRange::iterator > values)
Definition: ValueRange.h:397
ValueRange(ArrayRef< BlockArgument > values)
Definition: ValueRange.h:399
type_range getType() const
type_range getTypes() const
ValueRange(ArrayRef< Value > values=std::nullopt)
ValueRange(const std::initializer_list< Value > &values)
Definition: ValueRange.h:393
ValueRange(const Value &value)
Definition: ValueRange.h:392
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:314
An iterator over the users of an IRObject.
Definition: UseDefLists.h:344
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
bool use_empty() const
Returns true if this value has no uses.
Definition: Value.h:214
This class provides the implementation for an operation result.
Definition: Value.h:364
OpResultImpl * getNextResultAtOffset(intptr_t offset)
Returns the next operation result at offset after this result.
Definition: Value.cpp:134
Include the generated interface declarations.