MLIR  15.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 "llvm/ADT/PointerUnion.h"
19 #include "llvm/ADT/Sequence.h"
20 
21 namespace mlir {
22 class OperandRange;
23 class ResultRange;
24 class Type;
25 class Value;
26 class ValueRange;
27 template <typename ValueRangeT>
28 class ValueTypeRange;
29 
30 //===----------------------------------------------------------------------===//
31 // TypeRange
32 
33 /// This class provides an abstraction over the various different ranges of
34 /// value types. In many cases, this prevents the need to explicitly materialize
35 /// a SmallVector/std::vector. This class should be used in places that are not
36 /// suitable for a more derived type (e.g. ArrayRef) or a template range
37 /// parameter.
39  TypeRange,
40  llvm::PointerUnion<const Value *, const Type *,
41  OpOperand *, detail::OpResultImpl *>,
42  Type, Type, Type> {
43 public:
44  using RangeBaseT::RangeBaseT;
45  TypeRange(ArrayRef<Type> types = llvm::None);
46  explicit TypeRange(OperandRange values);
47  explicit TypeRange(ResultRange values);
48  explicit TypeRange(ValueRange values);
49  explicit TypeRange(ArrayRef<Value> values);
51  : TypeRange(ArrayRef<Value>(values.data(), values.size())) {}
52  template <typename ValueRangeT>
54  : TypeRange(ValueRangeT(values.begin().getCurrent(),
55  values.end().getCurrent())) {}
56  template <typename Arg,
57  typename = typename std::enable_if_t<
58  std::is_constructible<ArrayRef<Type>, Arg>::value>>
59  TypeRange(Arg &&arg) : TypeRange(ArrayRef<Type>(std::forward<Arg>(arg))) {}
60  TypeRange(std::initializer_list<Type> types)
61  : TypeRange(ArrayRef<Type>(types)) {}
62 
63 private:
64  /// The owner of the range is either:
65  /// * A pointer to the first element of an array of values.
66  /// * A pointer to the first element of an array of types.
67  /// * A pointer to the first element of an array of operands.
68  /// * A pointer to the first element of an array of results.
69  using OwnerT = llvm::PointerUnion<const Value *, const Type *, OpOperand *,
71 
72  /// See `llvm::detail::indexed_accessor_range_base` for details.
73  static OwnerT offset_base(OwnerT object, ptrdiff_t index);
74  /// See `llvm::detail::indexed_accessor_range_base` for details.
75  static Type dereference_iterator(OwnerT object, ptrdiff_t index);
76 
77  /// Allow access to `offset_base` and `dereference_iterator`.
78  friend RangeBaseT;
79 };
80 
81 /// Make TypeRange hashable.
82 inline ::llvm::hash_code hash_value(TypeRange arg) {
83  return ::llvm::hash_combine_range(arg.begin(), arg.end());
84 }
85 
86 /// Emit a type range to the given output stream.
87 inline raw_ostream &operator<<(raw_ostream &os, const TypeRange &types) {
88  llvm::interleaveComma(types, os);
89  return os;
90 }
91 
92 //===----------------------------------------------------------------------===//
93 // TypeRangeRange
94 
96  llvm::mapped_iterator<llvm::iota_range<unsigned>::iterator,
97  std::function<TypeRange(unsigned)>>;
98 
99 /// This class provides an abstraction for a range of TypeRange. This is useful
100 /// when accessing the types of a range of ranges, such as when using
101 /// OperandRangeRange.
102 class TypeRangeRange : public llvm::iterator_range<TypeRangeRangeIterator> {
103 public:
104  template <typename RangeT>
105  TypeRangeRange(const RangeT &range)
106  : TypeRangeRange(llvm::seq<unsigned>(0, range.size()), range) {}
107 
108 private:
109  template <typename RangeT>
110  TypeRangeRange(llvm::iota_range<unsigned> sizeRange, const RangeT &range)
112  {sizeRange.begin(), getRangeFn(range)},
113  {sizeRange.end(), nullptr}) {}
114 
115  template <typename RangeT>
116  static std::function<TypeRange(unsigned)> getRangeFn(const RangeT &range) {
117  return [=](unsigned index) -> TypeRange { return TypeRange(range[index]); };
118  }
119 };
120 
121 //===----------------------------------------------------------------------===//
122 // ValueTypeRange
123 
124 /// This class implements iteration on the types of a given range of values.
125 template <typename ValueIteratorT>
126 class ValueTypeIterator final
127  : public llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
128  ValueIteratorT, Type> {
129 public:
130  using llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
131  ValueIteratorT, Type>::mapped_iterator_base;
132 
133  /// Map the element to the iterator result type.
134  Type mapElement(Value value) const { return value.getType(); }
135 };
136 
137 /// This class implements iteration on the types of a given range of values.
138 template <typename ValueRangeT>
139 class ValueTypeRange final
140  : public llvm::iterator_range<
141  ValueTypeIterator<typename ValueRangeT::iterator>> {
142 public:
143  using llvm::iterator_range<
145  template <typename Container>
146  ValueTypeRange(Container &&c) : ValueTypeRange(c.begin(), c.end()) {}
147 
148  /// Return the type at the given index.
149  Type operator[](size_t index) const {
150  assert(index < size() && "invalid index into type range");
151  return *(this->begin() + index);
152  }
153 
154  /// Return the size of this range.
155  size_t size() const { return llvm::size(*this); }
156 
157  /// Return first type in the range.
158  Type front() { return (*this)[0]; }
159 
160  /// Compare this range with another.
161  template <typename OtherT>
162  bool operator==(const OtherT &other) const {
163  return llvm::size(*this) == llvm::size(other) &&
164  std::equal(this->begin(), this->end(), other.begin());
165  }
166  template <typename OtherT>
167  bool operator!=(const OtherT &other) const {
168  return !(*this == other);
169  }
170 };
171 
172 template <typename RangeT>
173 inline bool operator==(ArrayRef<Type> lhs, const ValueTypeRange<RangeT> &rhs) {
174  return lhs.size() == static_cast<size_t>(llvm::size(rhs)) &&
175  std::equal(lhs.begin(), lhs.end(), rhs.begin());
176 }
177 
178 } // namespace mlir
179 
180 namespace llvm {
181 
182 // Provide DenseMapInfo for TypeRange.
183 template <>
186  return mlir::TypeRange(getEmptyKeyPointer(), 0);
187  }
188 
190  return mlir::TypeRange(getTombstoneKeyPointer(), 0);
191  }
192 
193  static unsigned getHashValue(mlir::TypeRange val) { return hash_value(val); }
194 
195  static bool isEqual(mlir::TypeRange lhs, mlir::TypeRange rhs) {
196  if (isEmptyKey(rhs))
197  return isEmptyKey(lhs);
198  if (isTombstoneKey(rhs))
199  return isTombstoneKey(lhs);
200  return lhs == rhs;
201  }
202 
203 private:
204  static const mlir::Type *getEmptyKeyPointer() {
206  }
207 
208  static const mlir::Type *getTombstoneKeyPointer() {
210  }
211 
212  static bool isEmptyKey(mlir::TypeRange range) {
213  if (const auto *type = range.getBase().dyn_cast<const mlir::Type *>())
214  return type == getEmptyKeyPointer();
215  return false;
216  }
217 
218  static bool isTombstoneKey(mlir::TypeRange range) {
219  if (const auto *type = range.getBase().dyn_cast<const mlir::Type *>())
220  return type == getTombstoneKeyPointer();
221  return false;
222  }
223 };
224 
225 } // namespace llvm
226 
227 #endif // MLIR_IR_TYPERANGE_H
size_t size() const
Return the size of this range.
Definition: TypeRange.h:155
Include the generated interface declarations.
This class provides an abstraction for a range of TypeRange.
Definition: TypeRange.h:102
Type mapElement(Value value) const
Map the element to the iterator result type.
Definition: TypeRange.h:134
Explicitly register a set of "builtin" types.
Definition: CallGraph.h:221
static bool isEqual(mlir::TypeRange lhs, mlir::TypeRange rhs)
Definition: TypeRange.h:195
TypeRange(std::initializer_list< Type > types)
Definition: TypeRange.h:60
static mlir::TypeRange getTombstoneKey()
Definition: TypeRange.h:189
TypeRangeRange(const RangeT &range)
Definition: TypeRange.h:105
This class implements the result iterators for the Operation class.
ValueTypeRange(Container &&c)
Definition: TypeRange.h:146
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
static constexpr const bool value
This class implements iteration on the types of a given range of values.
Definition: TypeRange.h:126
TypeRange(ArrayRef< Type > types=llvm::None)
Definition: TypeRange.cpp:17
bool operator!=(const OtherT &other) const
Definition: TypeRange.h:167
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:38
static unsigned getHashValue(mlir::TypeRange val)
Definition: TypeRange.h:193
bool operator==(const OtherT &other) const
Compare this range with another.
Definition: TypeRange.h:162
llvm::mapped_iterator< llvm::iota_range< unsigned >::iterator, std::function< TypeRange(unsigned)> > TypeRangeRangeIterator
Definition: TypeRange.h:97
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:240
This class implements iteration on the types of a given range of values.
Definition: Block.h:26
static mlir::TypeRange getEmptyKey()
Definition: TypeRange.h:185
Type front()
Return first type in the range.
Definition: TypeRange.h:158
Type getType() const
Return the type of this value.
Definition: Value.h:118
Type operator[](size_t index) const
Return the type at the given index.
Definition: TypeRange.h:149
This class represents an operand of an operation.
Definition: Value.h:251
This class implements the operand iterators for the Operation class.
This class provides the implementation for an operation result.
Definition: Value.h:349
This class provides an abstraction over the different types of ranges over Values.
TypeRange(ArrayRef< BlockArgument > values)
Definition: TypeRange.h:50
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
TypeRange(Arg &&arg)
Definition: TypeRange.h:59
TypeRange(ValueTypeRange< ValueRangeT > values)
Definition: TypeRange.h:53