MLIR 22.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/Sequence.h"
21
22namespace mlir {
23
24//===----------------------------------------------------------------------===//
25// TypeRange
26//===----------------------------------------------------------------------===//
27
28/// This class provides an abstraction over the various different ranges of
29/// value types. In many cases, this prevents the need to explicitly materialize
30/// a SmallVector/std::vector. This class should be used in places that are not
31/// suitable for a more derived type (e.g. ArrayRef) or a template range
32/// parameter.
34 TypeRange,
35 llvm::PointerUnion<const Value *, const Type *,
36 OpOperand *, detail::OpResultImpl *>,
37 Type, Type, Type> {
38public:
39 using RangeBaseT::RangeBaseT;
40 TypeRange(ArrayRef<Type> types = {});
41 explicit TypeRange(OperandRange values);
42 explicit TypeRange(ResultRange values);
43 explicit TypeRange(ValueRange values);
44 template <typename ValueRangeT>
46 : TypeRange(ValueRange(ValueRangeT(values.begin().getCurrent(),
47 values.end().getCurrent()))) {}
48 template <typename Arg, typename = std::enable_if_t<std::is_constructible<
49 ArrayRef<Type>, Arg>::value>>
50 TypeRange(Arg &&arg LLVM_LIFETIME_BOUND)
51 : TypeRange(ArrayRef<Type>(std::forward<Arg>(arg))) {}
52 TypeRange(std::initializer_list<Type> types LLVM_LIFETIME_BOUND)
53 : TypeRange(ArrayRef<Type>(types)) {}
54
55private:
56 /// The owner of the range is either:
57 /// * A pointer to the first element of an array of values.
58 /// * A pointer to the first element of an array of types.
59 /// * A pointer to the first element of an array of operands.
60 /// * A pointer to the first element of an array of results.
61 using OwnerT = llvm::PointerUnion<const Value *, const Type *, OpOperand *,
63
64 /// See `llvm::detail::indexed_accessor_range_base` for details.
65 static OwnerT offset_base(OwnerT object, ptrdiff_t index);
66 /// See `llvm::detail::indexed_accessor_range_base` for details.
67 static Type dereference_iterator(OwnerT object, ptrdiff_t index);
68
69 /// Allow access to `offset_base` and `dereference_iterator`.
70 friend RangeBaseT;
71};
72
73/// Make TypeRange hashable.
74inline ::llvm::hash_code hash_value(TypeRange arg) {
75 return ::llvm::hash_combine_range(arg);
76}
77
78/// Emit a type range to the given output stream.
79inline raw_ostream &operator<<(raw_ostream &os, const TypeRange &types) {
80 llvm::interleaveComma(types, os);
81 return os;
82}
83
84//===----------------------------------------------------------------------===//
85// TypeRangeRange
86//===----------------------------------------------------------------------===//
87
89 llvm::mapped_iterator<llvm::iota_range<unsigned>::iterator,
90 std::function<TypeRange(unsigned)>>;
91
92/// This class provides an abstraction for a range of TypeRange. This is useful
93/// when accessing the types of a range of ranges, such as when using
94/// OperandRangeRange.
95class TypeRangeRange : public llvm::iterator_range<TypeRangeRangeIterator> {
96public:
97 template <typename RangeT>
98 TypeRangeRange(const RangeT &range)
99 : TypeRangeRange(llvm::seq<unsigned>(0, range.size()), range) {}
100
101private:
102 template <typename RangeT>
103 TypeRangeRange(llvm::iota_range<unsigned> sizeRange, const RangeT &range)
105 {sizeRange.begin(), getRangeFn(range)},
106 {sizeRange.end(), nullptr}) {}
107
108 template <typename RangeT>
109 static std::function<TypeRange(unsigned)> getRangeFn(const RangeT &range) {
110 return [=](unsigned index) -> TypeRange { return TypeRange(range[index]); };
111 }
112};
113
114//===----------------------------------------------------------------------===//
115// ValueTypeRange
116//===----------------------------------------------------------------------===//
117
118/// This class implements iteration on the types of a given range of values.
119template <typename ValueIteratorT>
121 : public llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
122 ValueIteratorT, Type> {
123public:
124 using llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
125 ValueIteratorT, Type>::mapped_iterator_base;
126
127 /// Map the element to the iterator result type.
128 Type mapElement(Value value) const { return value.getType(); }
129};
130
131/// This class implements iteration on the types of a given range of values.
132template <typename ValueRangeT>
133class ValueTypeRange final
134 : public llvm::iterator_range<
135 ValueTypeIterator<typename ValueRangeT::iterator>> {
136public:
139 template <typename Container>
140 ValueTypeRange(Container &&c) : ValueTypeRange(c.begin(), c.end()) {}
141
142 /// Return the type at the given index.
143 Type operator[](size_t index) const {
144 assert(index < size() && "invalid index into type range");
145 return *(this->begin() + index);
146 }
147
148 /// Return the size of this range.
149 size_t size() const { return llvm::size(*this); }
150
151 /// Return first type in the range.
152 Type front() { return (*this)[0]; }
153
154 /// Compare this range with another.
155 template <typename OtherT>
156 bool operator==(const OtherT &other) const {
157 return llvm::size(*this) == llvm::size(other) &&
158 std::equal(this->begin(), this->end(), other.begin());
159 }
160 template <typename OtherT>
161 bool operator!=(const OtherT &other) const {
162 return !(*this == other);
163 }
164};
165
166template <typename RangeT>
168 return lhs.size() == static_cast<size_t>(llvm::size(rhs)) &&
169 std::equal(lhs.begin(), lhs.end(), rhs.begin());
170}
171
172//===----------------------------------------------------------------------===//
173// SubElements
174//===----------------------------------------------------------------------===//
175
176/// Enable TypeRange to be introspected for sub-elements.
177template <>
180 walker.walkRange(param);
181 }
184 TypeSubElementReplacements &typeRepls) {
185 return typeRepls.take_front(param.size());
186 }
187};
188
189} // namespace mlir
190
191namespace llvm {
192
193// Provide DenseMapInfo for TypeRange.
194template <>
197 return mlir::TypeRange(getEmptyKeyPointer(), 0);
198 }
199
201 return mlir::TypeRange(getTombstoneKeyPointer(), 0);
202 }
203
204 static unsigned getHashValue(mlir::TypeRange val) { return hash_value(val); }
205
207 if (isEmptyKey(rhs))
208 return isEmptyKey(lhs);
209 if (isTombstoneKey(rhs))
210 return isTombstoneKey(lhs);
211 return lhs == rhs;
212 }
213
214private:
215 static const mlir::Type *getEmptyKeyPointer() {
217 }
218
219 static const mlir::Type *getTombstoneKeyPointer() {
220 return DenseMapInfo<mlir::Type *>::getTombstoneKey();
221 }
222
223 static bool isEmptyKey(mlir::TypeRange range) {
224 if (const auto *type =
225 llvm::dyn_cast_if_present<const mlir::Type *>(range.getBase()))
226 return type == getEmptyKeyPointer();
227 return false;
228 }
229
230 static bool isTombstoneKey(mlir::TypeRange range) {
231 if (const auto *type =
232 llvm::dyn_cast_if_present<const mlir::Type *>(range.getBase()))
233 return type == getTombstoneKeyPointer();
234 return false;
235 }
236};
237
238} // namespace llvm
239
240#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:257
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:43
This class implements the result iterators for the Operation class.
Definition ValueRange.h:247
TypeRangeRange(const RangeT &range)
Definition TypeRange.h:98
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:37
TypeRange(ArrayRef< Type > types={})
Definition TypeRange.cpp:17
TypeRange(ValueTypeRange< ValueRangeT > values)
Definition TypeRange.h:45
TypeRange(Arg &&arg LLVM_LIFETIME_BOUND)
Definition TypeRange.h:50
TypeRange(std::initializer_list< Type > types LLVM_LIFETIME_BOUND)
Definition TypeRange.h:52
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:387
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:122
Type mapElement(Value value) const
Map the element to the iterator result type.
Definition TypeRange.h:128
This class implements iteration on the types of a given range of values.
Definition TypeRange.h:135
size_t size() const
Return the size of this range.
Definition TypeRange.h:149
ValueTypeRange(Container &&c)
Definition TypeRange.h:140
Type operator[](size_t index) const
Return the type at the given index.
Definition TypeRange.h:143
bool operator==(const OtherT &other) const
Compare this range with another.
Definition TypeRange.h:156
bool operator!=(const OtherT &other) const
Definition TypeRange.h:161
Type front()
Return first type in the range.
Definition TypeRange.h:152
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:358
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:88
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:206
static unsigned getHashValue(mlir::TypeRange val)
Definition TypeRange.h:204
static mlir::TypeRange getEmptyKey()
Definition TypeRange.h:196
static mlir::TypeRange getTombstoneKey()
Definition TypeRange.h:200
static void walk(TypeRange param, AttrTypeImmediateSubElementWalker &walker)
Definition TypeRange.h:179
static TypeRange replace(TypeRange param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
Definition TypeRange.h:182
This class provides support for interacting with the SubElementInterfaces for different types of para...