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