diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td --- a/mlir/include/mlir/IR/BuiltinAttributes.td +++ b/mlir/include/mlir/IR/BuiltinAttributes.td @@ -143,6 +143,18 @@ // DenseArrayBaseAttr //===----------------------------------------------------------------------===// +def Builtin_DenseArrayRawDataParameter : ArrayRefParameter< + "char", "64-bit aligned storage for dense array elements"> { + let allocator = [{ + if (!$_self.empty()) { + auto *alloc = static_cast( + $_allocator.allocate($_self.size(), alignof(uint64_t))); + std::uninitialized_copy($_self.begin(), $_self.end(), alloc); + $_dst = ArrayRef(alloc, $_self.size()); + } + }]; +} + def Builtin_DenseArrayBase : Builtin_Attr< "DenseArrayBase", [ElementsAttrInterface, TypedAttrInterface]> { let summary = "A dense array of i8, i16, i32, i64, f32, or f64."; @@ -176,8 +188,8 @@ ``` }]; let parameters = (ins AttributeSelfTypeParameter<"", "ShapedType">:$type, - "DenseArrayBaseAttr::EltType":$eltType, - ArrayRefParameter<"char">:$elements); + "DenseArrayBaseAttr::EltType":$elementType, + Builtin_DenseArrayRawDataParameter:$rawData); let extraClassDeclaration = [{ // All possible supported element type. enum class EltType { I1, I8, I16, I32, I64, F32, F64 }; @@ -198,22 +210,12 @@ const float *value_begin_impl(OverloadToken) const; const double *value_begin_impl(OverloadToken) const; - /// Returns the shaped type, containing the number of elements in the array - /// and the array element type. - ShapedType getType() const; - /// Returns the element type. - EltType getElementType() const; - /// Printer for the short form: will dispatch to the appropriate subclass. void print(AsmPrinter &printer) const; void print(raw_ostream &os) const; /// Print the short form `42, 100, -1` without any braces or prefix. void printWithoutBraces(raw_ostream &os) const; }]; - // Do not generate the storage class, we need to handle custom storage alignment. - let genStorageClass = 0; - let genAccessors = 0; - let skipDefaultBuilders = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp --- a/mlir/lib/IR/BuiltinAttributes.cpp +++ b/mlir/lib/IR/BuiltinAttributes.cpp @@ -686,52 +686,6 @@ // DenseArrayAttr //===----------------------------------------------------------------------===// -/// Custom storage to ensure proper memory alignment for the allocation of -/// DenseArray of any element type. -struct mlir::detail::DenseArrayBaseAttrStorage : public AttributeStorage { - using KeyTy = - std::tuple>; - DenseArrayBaseAttrStorage(ShapedType type, - DenseArrayBaseAttr::EltType eltType, - ArrayRef elements) - : type(type), eltType(eltType), elements(elements) {} - - bool operator==(const KeyTy &key) const { - return (type == std::get<0>(key)) && (eltType == std::get<1>(key)) && - (elements == std::get<2>(key)); - } - - static llvm::hash_code hashKey(const KeyTy &key) { - return llvm::hash_combine(std::get<0>(key), std::get<1>(key), - std::get<2>(key)); - } - - static DenseArrayBaseAttrStorage * - construct(AttributeStorageAllocator &allocator, const KeyTy &key) { - auto type = std::get<0>(key); - auto eltType = std::get<1>(key); - auto elements = std::get<2>(key); - if (!elements.empty()) { - char *alloc = static_cast( - allocator.allocate(elements.size(), alignof(uint64_t))); - std::uninitialized_copy(elements.begin(), elements.end(), alloc); - elements = ArrayRef(alloc, elements.size()); - } - return new (allocator.allocate()) - DenseArrayBaseAttrStorage(type, eltType, elements); - } - - ShapedType type; - DenseArrayBaseAttr::EltType eltType; - ArrayRef elements; -}; - -DenseArrayBaseAttr::EltType DenseArrayBaseAttr::getElementType() const { - return getImpl()->eltType; -} - -ShapedType DenseArrayBaseAttr::getType() const { return getImpl()->type; } - const bool *DenseArrayBaseAttr::value_begin_impl(OverloadToken) const { return cast().asArrayRef().begin(); } @@ -880,7 +834,7 @@ /// Conversion from DenseArrayAttr to ArrayRef. template DenseArrayAttr::operator ArrayRef() const { - ArrayRef raw = getImpl()->elements; + ArrayRef raw = getRawData(); assert((raw.size() % sizeof(T)) == 0); return ArrayRef(reinterpret_cast(raw.data()), raw.size() / sizeof(T));