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