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