MLIR  21.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 
22 namespace 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> {
38 public:
39  using RangeBaseT::RangeBaseT;
40  TypeRange(ArrayRef<Type> types = std::nullopt);
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 
55 private:
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.
74 inline ::llvm::hash_code hash_value(TypeRange arg) {
75  return ::llvm::hash_combine_range(arg.begin(), arg.end());
76 }
77 
78 /// Emit a type range to the given output stream.
79 inline 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.
95 class TypeRangeRange : public llvm::iterator_range<TypeRangeRangeIterator> {
96 public:
97  template <typename RangeT>
98  TypeRangeRange(const RangeT &range)
99  : TypeRangeRange(llvm::seq<unsigned>(0, range.size()), range) {}
100 
101 private:
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.
119 template <typename ValueIteratorT>
120 class ValueTypeIterator final
121  : public llvm::mapped_iterator_base<ValueTypeIterator<ValueIteratorT>,
122  ValueIteratorT, Type> {
123 public:
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.
132 template <typename ValueRangeT>
133 class ValueTypeRange final
134  : public llvm::iterator_range<
135  ValueTypeIterator<typename ValueRangeT::iterator>> {
136 public:
137  using llvm::iterator_range<
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 
166 template <typename RangeT>
167 inline bool operator==(ArrayRef<Type> lhs, const ValueTypeRange<RangeT> &rhs) {
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.
177 template <>
179  static void walk(TypeRange param, AttrTypeImmediateSubElementWalker &walker) {
180  walker.walkRange(param);
181  }
183  AttrSubElementReplacements &attrRepls,
184  TypeSubElementReplacements &typeRepls) {
185  return typeRepls.take_front(param.size());
186  }
187 };
188 
189 } // namespace mlir
190 
191 namespace llvm {
192 
193 // Provide DenseMapInfo for TypeRange.
194 template <>
195 struct DenseMapInfo<mlir::TypeRange> {
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 
206  static bool isEqual(mlir::TypeRange lhs, mlir::TypeRange rhs) {
207  if (isEmptyKey(rhs))
208  return isEmptyKey(lhs);
209  if (isTombstoneKey(rhs))
210  return isTombstoneKey(lhs);
211  return lhs == rhs;
212  }
213 
214 private:
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
void walkRange(RangeT &&elements)
Walk a range of attributes or types.
This class is used by AttrTypeSubElementHandler instances to process sub element replacements.
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:243
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
This class provides an abstraction for a range of TypeRange.
Definition: TypeRange.h:95
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(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
TypeRange(ArrayRef< Type > types=std::nullopt)
Definition: TypeRange.cpp:18
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:344
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
Include the generated interface declarations.
llvm::mapped_iterator< llvm::iota_range< unsigned >::iterator, std::function< TypeRange(unsigned)> > TypeRangeRangeIterator
Definition: TypeRange.h:90
bool operator==(StringAttr lhs, std::nullptr_t)
Define comparisons for StringAttr against nullptr and itself to avoid the StringRef overloads from be...
inline ::llvm::hash_code hash_value(TypeRange arg)
Make TypeRange hashable.
Definition: TypeRange.h:74
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:247
raw_ostream & operator<<(raw_ostream &os, const AliasResult &result)
Definition: AliasAnalysis.h:78
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...