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