9#ifndef MLIR_IR_BUILTINATTRIBUTEINTERFACES_H
10#define MLIR_IR_BUILTINATTRIBUTEINTERFACES_H
15#include "llvm/Support/raw_ostream.h"
37 : isContiguous(rhs.isContiguous), isSplat(rhs.isSplat) {
41 new (&
nonConState) NonContiguousState(std::move(rhs.nonConState));
44 : isContiguous(rhs.isContiguous), isSplat(rhs.isSplat) {
48 new (&
nonConState) NonContiguousState(rhs.nonConState);
58 template <
typename IteratorT>
62 NonContiguousState(std::forward<IteratorT>(iterator));
72 new (&indexer.
conState) ContiguousState(firstEltPtr);
90 class ContiguousState {
92 ContiguousState(
const void *firstEltPtr) : firstEltPtr(firstEltPtr) {}
96 const T &at(uint64_t index)
const {
97 return *(
reinterpret_cast<const T *
>(firstEltPtr) + index);
101 const void *firstEltPtr;
106 class NonContiguousState {
111 struct OpaqueIteratorBase {
112 virtual ~OpaqueIteratorBase() =
default;
113 virtual std::unique_ptr<OpaqueIteratorBase> clone()
const = 0;
118 template <
typename T>
119 struct OpaqueIteratorValueBase :
public OpaqueIteratorBase {
120 virtual T at(uint64_t index) = 0;
124 template <
typename IteratorT,
typename T>
125 struct OpaqueIterator :
public OpaqueIteratorValueBase<T> {
126 template <
typename ItTy,
typename FuncTy,
typename FuncReturnTy>
127 static void isMappedIteratorTestFn(
128 llvm::mapped_iterator<ItTy, FuncTy, FuncReturnTy>) {}
129 template <
typename U,
typename... Args>
130 using is_mapped_iterator =
131 decltype(isMappedIteratorTestFn(std::declval<U>()));
132 template <
typename U>
133 using detect_is_mapped_iterator =
134 llvm::is_detected<is_mapped_iterator, U>;
137 template <
typename ItT>
138 static std::enable_if_t<!detect_is_mapped_iterator<ItT>::value, T>
139 atImpl(ItT &&it, uint64_t index) {
140 return *std::next(it, index);
142 template <
typename ItT>
143 static std::enable_if_t<detect_is_mapped_iterator<ItT>::value, T>
144 atImpl(ItT &&it, uint64_t index) {
146 return it.getFunction()(*std::next(it.getCurrent(), index));
150 template <
typename U>
151 OpaqueIterator(U &&iterator) : iterator(std::forward<U>(iterator)) {}
152 std::unique_ptr<OpaqueIteratorBase> clone() const final {
153 return std::make_unique<OpaqueIterator<IteratorT, T>>(iterator);
157 T at(uint64_t index)
final {
return atImpl(iterator, index); }
165 template <
typename IteratorT,
typename T =
typename llvm::remove_cvref_t<
166 decltype(*std::declval<IteratorT>())>>
167 NonContiguousState(IteratorT iterator)
168 : iterator(std::make_unique<OpaqueIterator<IteratorT, T>>(iterator)) {}
169 NonContiguousState(
const NonContiguousState &other)
170 : iterator(other.iterator->
clone()) {}
171 NonContiguousState(NonContiguousState &&other) =
default;
174 template <
typename T>
175 T at(uint64_t index)
const {
176 auto *valueIt =
static_cast<OpaqueIteratorValueBase<T> *
>(iterator.get());
177 return valueIt->at(index);
181 std::unique_ptr<OpaqueIteratorBase> iterator;
198 :
public llvm::iterator_facade_base<ElementsAttrIterator<T>,
199 std::random_access_iterator_tag, T,
200 std::ptrdiff_t, T, T> {
203 : indexer(std::move(indexer)), index(dataIndex) {}
207 return index - rhs.index;
210 return index == rhs.index;
213 return index < rhs.index;
233template <
typename IteratorT>
247 return *std::next(this->begin(),
index);
251 size_t size()
const {
return llvm::size(*
this); }
255 ShapedType shapeType;
269verifyAffineMapAsLayout(AffineMap m, ArrayRef<int64_t> shape,
270 function_ref<InFlightDiagnostic()> emitError);
274LogicalResult getAffineMapStridesAndOffset(AffineMap map,
275 ArrayRef<int64_t> shape,
276 SmallVectorImpl<int64_t> &strides,
286#include "mlir/IR/BuiltinAttributeInterfaces.h.inc"
287#include "mlir/IR/OpAsmAttrInterface.h.inc"
296template <
typename IteratorT>
300 return (*
this)[ElementsAttr::getFlattenedIndex(shapeType,
index)];
306auto ElementsAttr::value_begin() const -> DefaultValueCheckT<T, iterator<T>> {
307 if (std::optional<iterator<T>> iterator = try_value_begin<T>())
308 return std::move(*iterator);
310 <<
"ElementsAttr does not provide iteration facilities for type `"
311 << llvm::getTypeName<T>() <<
"`, see attribute: " << *
this <<
"\n";
312 llvm_unreachable(
"invalid `T` for ElementsAttr::getValues");
315auto ElementsAttr::try_value_begin() const
316 -> DefaultValueCheckT<T, std::optional<iterator<T>>> {
317 FailureOr<detail::ElementsAttrIndexer> indexer =
321 return iterator<T>(std::move(*indexer), 0);
true
Given two iterators into the same block, return "true" if a is before `b.
static TypeID get()
Construct a type info object for the given type T.
ptrdiff_t operator-(const ElementsAttrIterator &rhs) const
T operator*() const
Return the value at the current iterator position.
bool operator<(const ElementsAttrIterator &rhs) const
ElementsAttrIterator(ElementsAttrIndexer indexer, size_t dataIndex)
ElementsAttrIterator & operator-=(ptrdiff_t offset)
ElementsAttrIterator & operator+=(ptrdiff_t offset)
bool operator==(const ElementsAttrIterator &rhs) const
typename IteratorT::reference reference
reference operator[](ArrayRef< uint64_t > index) const
Return the value at the given index.
size_t size() const
Return the size of this range.
reference operator[](uint64_t index) const
ElementsAttrRange(ShapedType shapeType, IteratorT beginIt, IteratorT endIt)
ElementsAttrRange(ShapedType shapeType, const llvm::iterator_range< IteratorT > &range)
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Include the generated interface declarations.
Operation * clone(OpBuilder &b, Operation *op, TypeRange newResultTypes, ValueRange newOperands)
This class provides support for indexing into the element range of an ElementsAttr.
static ElementsAttrIndexer contiguous(bool isSplat, const T *firstEltPtr)
static ElementsAttrIndexer nonContiguous(bool isSplat, IteratorT &&iterator)
Construct an indexer for a non-contiguous range starting at the given iterator.
T at(uint64_t index) const
Access the element at the given index.
NonContiguousState nonConState
ElementsAttrIndexer(const ElementsAttrIndexer &rhs)
ElementsAttrIndexer(ElementsAttrIndexer &&rhs)