[Mlir-commits] [mlir] [mlir] Add support for recursive elements in DICompositeTypeAttr. (PR #74948)
Tobias Gysi
llvmlistbot at llvm.org
Mon Dec 11 02:40:19 PST 2023
================
@@ -0,0 +1,136 @@
+//===- AttrDetail.h - Details of MLIR LLVM dialect attributes --------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains implementation details, such as storage structures, of
+// MLIR LLVM dialect attributes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef DIALECT_LLVMIR_IR_ATTRDETAIL_H
+#define DIALECT_LLVMIR_IR_ATTRDETAIL_H
+
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/IR/Types.h"
+
+namespace mlir {
+namespace LLVM {
+namespace detail {
+
+//===----------------------------------------------------------------------===//
+// DICompositeTypeAttrStorage
+//===----------------------------------------------------------------------===//
+
+struct DICompositeTypeAttrStorage : public ::mlir::AttributeStorage {
+ using KeyTy = std::tuple<unsigned, StringAttr, DIFileAttr, uint32_t,
+ DIScopeAttr, DITypeAttr, DIFlags, uint64_t, uint64_t,
+ ArrayRef<DINodeAttr>, DistinctAttr>;
+
+ DICompositeTypeAttrStorage(unsigned tag, StringAttr name, DIFileAttr file,
+ uint32_t line, DIScopeAttr scope,
+ DITypeAttr baseType, DIFlags flags,
+ uint64_t sizeInBits, uint64_t alignInBits,
+ ArrayRef<DINodeAttr> elements,
+ DistinctAttr identifier = DistinctAttr())
+ : tag(tag), name(name), file(file), line(line), scope(scope),
+ baseType(baseType), flags(flags), sizeInBits(sizeInBits),
+ alignInBits(alignInBits), elements(elements), identifier(identifier) {}
+
+ unsigned getTag() const { return tag; }
+ StringAttr getName() const { return name; }
+ DIFileAttr getFile() const { return file; }
+ uint32_t getLine() const { return line; }
+ DIScopeAttr getScope() const { return scope; }
+ DITypeAttr getBaseType() const { return baseType; }
+ DIFlags getFlags() const { return flags; }
+ uint64_t getSizeInBits() const { return sizeInBits; }
+ uint64_t getAlignInBits() const { return alignInBits; }
+ ArrayRef<DINodeAttr> getElements() const { return elements; }
+ DistinctAttr getIdentifier() const { return identifier; }
+
+ /// Returns true if this attribute is identified.
+ bool isIdentified() const {
+ return !(!identifier);
+ }
+
+ /// Returns the respective key for this attribute.
+ KeyTy getAsKey() const {
+ if (isIdentified())
+ return KeyTy(tag, name, file, line, scope, baseType, flags, sizeInBits,
+ alignInBits, elements, identifier);
+
+ return KeyTy(tag, name, file, line, scope, baseType, flags, sizeInBits,
+ alignInBits, elements, DistinctAttr());
+ }
+
+ /// Compares two keys.
+ bool operator==(const KeyTy &other) const {
+ if (isIdentified())
+ // Just compare against the identifier.
+ return identifier == std::get<10>(other);
+
+ // Otherwise, compare the entire tuple.
+ return other == getAsKey();
+ }
+
+ /// Returns the hash value of the key.
+ static llvm::hash_code hashKey(const KeyTy &key) {
+ const auto &[tag, name, file, line, scope, baseType, flags, sizeInBits,
+ alignInBits, elements, identifier] = key;
+
+ if (identifier)
+ // Only the identifier participates in the hash id.
+ return hash_value(identifier);
+
+ // Otherwise, everything else is included in the hash.
+ return hash_combine(tag, name, file, line, scope, baseType, flags,
+ sizeInBits, alignInBits, elements);
+ }
+
+ /// Constructs new storage for an attribute.
+ static DICompositeTypeAttrStorage *
+ construct(AttributeStorageAllocator &allocator, const KeyTy &key) {
+ auto [tag, name, file, line, scope, baseType, flags, sizeInBits,
+ alignInBits, elements, identifier] = key;
+ elements = allocator.copyInto(elements);
+ if (identifier) {
+ return new (allocator.allocate<DICompositeTypeAttrStorage>())
+ DICompositeTypeAttrStorage(tag, name, file, line, scope, baseType,
+ flags, sizeInBits, alignInBits, elements,
+ identifier);
+ }
+ return new (allocator.allocate<DICompositeTypeAttrStorage>())
+ DICompositeTypeAttrStorage(tag, name, file, line, scope, baseType,
+ flags, sizeInBits, alignInBits, elements);
+ }
+
+ LogicalResult mutate(AttributeStorageAllocator &allocator,
+ const ArrayRef<DINodeAttr>& elements) {
+ // Replace the elements.
----------------
gysit wrote:
As far as I remember, most mutable upstream attributes implement a check here to ensure the elements can only be set once (or if set repeatedly they need to be set to the same value). I think such a check would be helpful here since that is presumably an error in our case (e.g. if the import sets the elements to two different values this probably indicates a collision of different LLVM DICompositeTypes to a single attribute in MLIR).
https://github.com/llvm/llvm-project/pull/74948
More information about the Mlir-commits
mailing list