MLIR 22.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
23namespace mlir {
24class ValueRange;
25template <typename ValueRangeT>
26class ValueTypeRange;
27class TypeRangeRange;
28template <typename ValueIteratorT>
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> {
44public:
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
61private:
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.
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
90public:
91 using RangeBaseT::RangeBaseT;
92
93 /// Returns the range of types of the values within this range.
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
104private:
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.
119public:
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 = {});
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.
176
177 /// Returns the OpOperand at the given index.
178 OpOperand &operator[](unsigned index) const;
179
180 /// Iterators enumerate OpOperands.
183
184private:
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
217public:
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.
228
229 /// Allow implicit conversion to an OperandRangeRange.
230 operator OperandRangeRange() const;
231
232private:
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.
245class ResultRange final
247 ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
248public:
249 using RangeBaseT::RangeBaseT;
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'.
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.
316 function_ref<bool(OpOperand &)> shouldReplace);
317
318 //===--------------------------------------------------------------------===//
319 // Users
320 //===--------------------------------------------------------------------===//
321
324
325 /// Returns a range of all users.
329
330private:
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> {
351public:
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
365private:
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.
383class ValueRange final
385 ValueRange,
386 PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
387 Value, Value, Value> {
388public:
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)) {}
411 : ValueRange(ArrayRef<Value>(values.data(), values.size())) {}
415
416 /// Returns the types of the values within this range.
421
422private:
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
Operation * getOwner() const
Returns the owning operation.
Definition ValueRange.h:171
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.
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: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:257
This is a value defined by a result of an operation.
Definition Value.h:457
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.
TypeRangeRange getType() const
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
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:49
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition ValueRange.h:48
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:360
OpOperand * operator->() const
Definition ValueRange.h:359
bool operator==(const UseIterator &rhs) const
Definition ValueRange.h:362
This class implements the result iterators for the Operation class.
Definition ValueRange.h:247
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
iterator_range< user_iterator > user_range
Definition ValueRange.h:323
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
ValueTypeRange< ResultRange > type_range
Definition ValueRange.h:258
use_iterator use_begin() const
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition ValueRange.h:257
user_range getUsers()
Returns a range of all users.
ValueUserIterator< use_iterator, OpOperand > user_iterator
Definition ValueRange.h:322
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:268
type_range getType() const
UseIterator use_iterator
Definition ValueRange.h:267
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
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
ValueTypeIterator< iterator > type_iterator
Returns the types of the values within this range.
Definition ValueRange.h:417
ValueRange(ResultRange values)
ValueRange(iterator_range< OperandRange::iterator > values)
Definition ValueRange.h:406
ValueRange(OperandRange values)
PointerUnion< const Value *, OpOperand *, detail::OpResultImpl * > OwnerT
The type representing the owner of a ValueRange.
Definition ValueRange.h:391
ValueRange(iterator_range< ResultRange::iterator > values)
Definition ValueRange.h:408
ValueTypeRange< ValueRange > type_range
Definition ValueRange.h:418
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(const std::initializer_list< Value > &values LLVM_LIFETIME_BOUND)
Definition ValueRange.h:404
ValueRange(Arg &&arg LLVM_LIFETIME_BOUND)
Definition ValueRange.h:400
ValueRange(ArrayRef< Value > values={})
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
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:358
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:152