MLIR 23.0.0git
TypeRange.h
Go to the documentation of this file.
1//===- TypeRange.h ----------------------------------------------*- 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 TypeRange and ValueTypeRange classes.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_IR_TYPERANGE_H
14#define MLIR_IR_TYPERANGE_H
15
16#include "mlir/IR/Types.h"
17#include "mlir/IR/Value.h"
18#include "mlir/IR/ValueRange.h"
19#include "llvm/ADT/PointerUnion.h"
20#include "llvm/ADT/Repeated.h"
21#include "llvm/ADT/Sequence.h"
22
23namespace mlir {
24
25//===----------------------------------------------------------------------===//
26// TypeRange
27//===----------------------------------------------------------------------===//
28
29/// This class provides an abstraction over the various different ranges of
30/// value types. In many cases, this prevents the need to explicitly materialize
31/// a SmallVector/std::vector. This class should be used in places that are not
32/// suitable for a more derived type (e.g. ArrayRef) or a template range
33/// parameter.
36 TypeRange,
37 llvm::PointerUnion<const Value *, const Type *, OpOperand *,
38 detail::OpResultImpl *, const Repeated<Type> *,
39 const Repeated<Value> *>,
40 Type, Type, Type> {
41public:
42 using RangeBaseT::RangeBaseT;
43 TypeRange(ArrayRef<Type> types = {});
44 explicit TypeRange(OperandRange values);
45 explicit TypeRange(ResultRange values);
46 explicit TypeRange(ValueRange values);
47 template <typename ValueRangeT>
49 : TypeRange(ValueRange(ValueRangeT(values.begin().getCurrent(),
50 values.end().getCurrent()))) {}
51 template <typename Arg, typename = std::enable_if_t<std::is_constructible<
52 ArrayRef<Type>, Arg>::value>>
53 TypeRange(Arg &&arg LLVM_LIFETIME_BOUND)
54 : TypeRange(ArrayRef<Type>(std::forward<Arg>(arg))) {}
55 TypeRange(std::initializer_list<Type> types LLVM_LIFETIME_BOUND)
56 : TypeRange(ArrayRef<Type>(types)) {}
57 /// Constructs a range from a repeated type. The Repeated object must outlive
58 /// this range.
59 TypeRange(const Repeated<Type> &repeatedValue LLVM_LIFETIME_BOUND)
60 : RangeBaseT(&repeatedValue, repeatedValue.count) {}
61
62private:
63 /// The owner of the range is either:
64 /// * A pointer to the first element of an array of values.
65 /// * A pointer to the first element of an array of types.
66 /// * A pointer to the first element of an array of operands.
67 /// * A pointer to the first element of an array of results.
68 /// * A pointer to a Repeated<Type> (single type repeated N times).
69 /// * A pointer to a Repeated<Value> (single value repeated N times,
70 /// dereferenced via getType()).
71 using OwnerT =
72 llvm::PointerUnion<const Value *, const Type *, OpOperand *,
74 const Repeated<Value> *>;
75
76 /// See `llvm::detail::indexed_accessor_range_base` for details.
77 static OwnerT offset_base(OwnerT object, ptrdiff_t index);
78 /// See `llvm::detail::indexed_accessor_range_base` for details.
79 static Type dereference_iterator(OwnerT object, ptrdiff_t index);
80
81 /// Allow access to `offset_base` and `dereference_iterator`.
82 friend RangeBaseT;
83};
84
85/// Make TypeRange hashable.
86inline ::llvm::hash_code hash_value(TypeRange arg) {
87 return ::llvm::hash_combine_range(arg);
88}
89
90/// Emit a type range to the given output stream.
91inline raw_ostream &operator<<(raw_ostream &os, const TypeRange &types) {
92 llvm::interleaveComma(types, os);
93 return os;
94}
95
96//===----------------------------------------------------------------------===//
97// TypeRangeRange
98//===----------------------------------------------------------------------===//
99
101 llvm::mapped_iterator<llvm::iota_range<unsigned>::iterator,
102 std::function<TypeRange(unsigned)>>;
103
104/// This class provides an abstraction for a range of TypeRange. This is useful
105/// when accessing the types of a range of ranges, such as when using
106/// OperandRangeRange.
107class TypeRangeRange : public llvm::iterator_range<TypeRangeRangeIterator> {
108public:
109 template <typename RangeT>
110 TypeRangeRange(const RangeT &range)
111 : TypeRangeRange(llvm::seq<unsigned>(0, range.size()), range) {}
112
113private:
114 template <typename RangeT>
115 TypeRangeRange(llvm::iota_range<unsigned> sizeRange, const RangeT &range)
117 {sizeRange.begin(), getRangeFn(range)},
118 {sizeRange.end(), nullptr}) {}
119
120 template <typename RangeT>
121 static std::function<TypeRange(unsigned)> getRangeFn(const RangeT &range) {
122 return [=](unsigned index) -> TypeRange { return TypeRange(range[index]); };
123 }
124};
125
126//===----------------------------------------------------------------------===//
127// ValueTypeRange
128//===----------------------------------------------------------------------===//
129
130/// This class implements iteration on the types of a given range of values.
131template <typename ValueIteratorT>
133 : public llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
134 ValueIteratorT, Type> {
135public:
136 using llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
137 ValueIteratorT, Type>::mapped_iterator_base;
138
139 /// Map the element to the iterator result type.
140 Type mapElement(Value value) const { return value.getType(); }
141};
142
143/// This class implements iteration on the types of a given range of values.
144template <typename ValueRangeT>
145class ValueTypeRange final
146 : public llvm::iterator_range<
147 ValueTypeIterator<typename ValueRangeT::iterator>> {
148public:
151 template <typename Container>
152 ValueTypeRange(Container &&c) : ValueTypeRange(c.begin(), c.end()) {}
153
154 /// Return the type at the given index.
155 Type operator[](size_t index) const {
156 assert(index < size() && "invalid index into type range");
157 return *(this->begin() + index);
158 }
159
160 /// Return the size of this range.
161 size_t size() const { return llvm::size(*this); }
162
163 /// Return first type in the range.
164 Type front() { return (*this)[0]; }
165
166 /// Compare this range with another.
167 template <typename OtherT>
168 bool operator==(const OtherT &other) const {
169 return llvm::size(*this) == llvm::size(other) &&
170 std::equal(this->begin(), this->end(), other.begin());
171 }
172 template <typename OtherT>
173 bool operator!=(const OtherT &other) const {
174 return !(*this == other);
175 }
176};
177
178template <typename RangeT>
180 return lhs.size() == static_cast<size_t>(llvm::size(rhs)) &&
181 std::equal(lhs.begin(), lhs.end(), rhs.begin());
182}
183
184//===----------------------------------------------------------------------===//
185// SubElements
186//===----------------------------------------------------------------------===//
187
188/// Enable TypeRange to be introspected for sub-elements.
189template <>
192 walker.walkRange(param);
193 }
196 TypeSubElementReplacements &typeRepls) {
197 return typeRepls.take_front(param.size());
198 }
199};
200
201} // namespace mlir
202
203namespace llvm {
204
205// Provide DenseMapInfo for TypeRange.
206template <>
209 return mlir::TypeRange(getEmptyKeyPointer(), 0);
210 }
211
213 return mlir::TypeRange(getTombstoneKeyPointer(), 0);
214 }
215
216 static unsigned getHashValue(mlir::TypeRange val) { return hash_value(val); }
217
219 if (isEmptyKey(rhs))
220 return isEmptyKey(lhs);
221 if (isTombstoneKey(rhs))
222 return isTombstoneKey(lhs);
223 return lhs == rhs;
224 }
225
226private:
227 static const mlir::Type *getEmptyKeyPointer() {
229 }
230
231 static const mlir::Type *getTombstoneKeyPointer() {
232 return DenseMapInfo<mlir::Type *>::getTombstoneKey();
233 }
234
235 static bool isEmptyKey(mlir::TypeRange range) {
236 if (const auto *type =
237 llvm::dyn_cast_if_present<const mlir::Type *>(range.getBase()))
238 return type == getEmptyKeyPointer();
239 return false;
240 }
241
242 static bool isTombstoneKey(mlir::TypeRange range) {
243 if (const auto *type =
244 llvm::dyn_cast_if_present<const mlir::Type *>(range.getBase()))
245 return type == getTombstoneKeyPointer();
246 return false;
247 }
248};
249
250} // namespace llvm
251
252#endif // MLIR_IR_TYPERANGE_H
lhs
void walkRange(RangeT &&elements)
Walk a range of attributes or types.
ArrayRef< T > take_front(unsigned n)
Take the first N replacements as an ArrayRef, dropping them from this replacement list.
This class represents an operand of an operation.
Definition Value.h:254
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:44
This class implements the result iterators for the Operation class.
Definition ValueRange.h:248
TypeRangeRange(const RangeT &range)
Definition TypeRange.h:110
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:40
TypeRange(ArrayRef< Type > types={})
Definition TypeRange.cpp:17
TypeRange(ValueTypeRange< ValueRangeT > values)
Definition TypeRange.h:48
TypeRange(Arg &&arg LLVM_LIFETIME_BOUND)
Definition TypeRange.h:53
TypeRange(const Repeated< Type > &repeatedValue LLVM_LIFETIME_BOUND)
Constructs a range from a repeated type.
Definition TypeRange.h:59
TypeRange(std::initializer_list< Type > types LLVM_LIFETIME_BOUND)
Definition TypeRange.h:55
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:134
Type mapElement(Value value) const
Map the element to the iterator result type.
Definition TypeRange.h:140
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:147
size_t size() const
Return the size of this range.
Definition TypeRange.h:161
ValueTypeRange(Container &&c)
Definition TypeRange.h:152
Type operator[](size_t index) const
Return the type at the given index.
Definition TypeRange.h:155
bool operator==(const OtherT &other) const
Compare this range with another.
Definition TypeRange.h:168
bool operator!=(const OtherT &other) const
Definition TypeRange.h:173
Type front()
Return first type in the range.
Definition TypeRange.h:164
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Type getType() const
Return the type of this value.
Definition Value.h:105
This class provides the implementation for an operation result.
Definition Value.h:355
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition CallGraph.h:229
Include the generated interface declarations.
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
llvm::mapped_iterator< llvm::iota_range< unsigned >::iterator, std::function< TypeRange(unsigned)> > TypeRangeRangeIterator
Definition TypeRange.h:100
AttrTypeSubElementReplacements< Attribute > AttrSubElementReplacements
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition AffineExpr.h:247
AttrTypeSubElementReplacements< Type > TypeSubElementReplacements
static bool isEqual(mlir::TypeRange lhs, mlir::TypeRange rhs)
Definition TypeRange.h:218
static unsigned getHashValue(mlir::TypeRange val)
Definition TypeRange.h:216
static mlir::TypeRange getEmptyKey()
Definition TypeRange.h:208
static mlir::TypeRange getTombstoneKey()
Definition TypeRange.h:212
static void walk(TypeRange param, AttrTypeImmediateSubElementWalker &walker)
Definition TypeRange.h:191
static TypeRange replace(TypeRange param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
Definition TypeRange.h:194
This class provides support for interacting with the SubElementInterfaces for different types of para...