--- /dev/null
+//===- AttributeSupport.h ---------------------------------------*- C++ -*-===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// This file defines support types for registering dialect extended attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_IR_ATTRIBUTESUPPORT_H
+#define MLIR_IR_ATTRIBUTESUPPORT_H
+
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/Support/StorageUniquer.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace mlir {
+class MLIRContext;
+class Type;
+
+//===----------------------------------------------------------------------===//
+// AttributeStorage
+//===----------------------------------------------------------------------===//
+
+namespace detail {
+class AttributeUniquer;
+} // end namespace detail
+
+/// Base storage class appearing in an attribute. Derived storage classes should
+/// only be constructed within the context of the AttributeUniquer.
+class AttributeStorage : public StorageUniquer::BaseStorage {
+ friend detail::AttributeUniquer;
+ friend StorageUniquer;
+
+public:
+ /// Returns if the derived attribute is or contains a function pointer.
+ bool isOrContainsFunctionCache() const {
+ return typeAndContainsFunctionAttrPair.getInt();
+ }
+
+ /// Get the type of this attribute.
+ Type getType() const;
+
+protected:
+ /// Construct a new attribute storage instance with the given type and a
+ /// boolean that signals if the derived attribute is or contains a function
+ /// pointer.
+ /// Note: All attributes require a valid type. If no type is provided here,
+ /// the type of the attribute will automatically default to NoneType
+ /// upon initialization in the uniquer.
+ AttributeStorage(Type type, bool isOrContainsFunctionCache = false);
+ AttributeStorage(bool isOrContainsFunctionCache);
+ AttributeStorage();
+
+ /// Set the type of this attribute.
+ void setType(Type type);
+
+private:
+ /// This field is a pair of:
+ /// - The type of the attribute value.
+ /// - A boolean that is true if this is, or contains, a function attribute.
+ llvm::PointerIntPair<const void *, 1, bool> typeAndContainsFunctionAttrPair;
+};
+
+/// Default storage type for attributes that require no additional
+/// initialization or storage.
+using DefaultAttributeStorage = AttributeStorage;
+
+//===----------------------------------------------------------------------===//
+// AttributeStorageAllocator
+//===----------------------------------------------------------------------===//
+
+// This is a utility allocator used to allocate memory for instances of derived
+// Attributes.
+using AttributeStorageAllocator = StorageUniquer::StorageAllocator;
+
+//===----------------------------------------------------------------------===//
+// AttributeUniquer
+//===----------------------------------------------------------------------===//
+namespace detail {
+// A utility class to get, or create, unique instances of attributes within an
+// MLIRContext. This class manages all creation and uniquing of attributes.
+class AttributeUniquer {
+public:
+ /// Get an uniqued instance of attribute T.
+ template <typename T, typename Kind, typename... Args>
+ static T get(MLIRContext *ctx, Kind kind, Args &&... args) {
+ return ctx->getAttributeUniquer().get<typename T::ImplType>(
+ getInitFn(ctx), static_cast<unsigned>(kind),
+ std::forward<Args>(args)...);
+ }
+
+ /// Erase a uniqued instance of attribute T.
+ template <typename T, typename Kind, typename... Args>
+ static void erase(MLIRContext *ctx, Kind kind, Args &&... args) {
+ return ctx->getAttributeUniquer().erase<typename T::ImplType>(
+ static_cast<unsigned>(kind), std::forward<Args>(args)...);
+ }
+
+private:
+ /// Returns a functor used to initialize new attribute storage instances.
+ static std::function<void(AttributeStorage *)> getInitFn(MLIRContext *ctx);
+};
+} // namespace detail
+
+} // end namespace mlir
+
+#endif
#ifndef MLIR_IR_ATTRIBUTES_H
#define MLIR_IR_ATTRIBUTES_H
+#include "mlir/IR/AttributeSupport.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/DenseMap.h"
namespace detail {
-struct AttributeStorage;
struct BoolAttributeStorage;
struct IntegerAttributeStorage;
struct FloatAttributeStorage;
FIRST_ELEMENTS_ATTR = SplatElements,
LAST_ELEMENTS_ATTR = SparseElements,
- FIRST_KIND = Bool,
+ FIRST_KIND = Unit,
LAST_KIND = SparseElements,
};
- using ImplType = detail::AttributeStorage;
+ using ImplType = AttributeStorage;
using ValueType = void;
Attribute() : attr(nullptr) {}
namespace mlir {
namespace detail {
-/// Base storage class appearing in an attribute. Derived storage classes should
-/// only be constructed within the context of the AttributeUniquer.
-struct AttributeStorage : public StorageUniquer::BaseStorage {
- /// Construct a new attribute storage instance with the given type and a
- /// boolean that signals if the derived attribute is or contains a function
- /// pointer.
- /// Note: All attributes require a valid type. If a null type is provided
- /// here, the type of the attribute will automatically default to
- /// NoneType upon initialization in the uniquer.
- AttributeStorage(Type type = {}, bool isOrContainsFunctionCache = false)
- : typeAndContainsFunctionAttrPair(type, isOrContainsFunctionCache) {}
- AttributeStorage(bool isOrContainsFunctionCache)
- : AttributeStorage(/*type=*/{}, isOrContainsFunctionCache) {}
-
- bool isOrContainsFunctionCache() const {
- return typeAndContainsFunctionAttrPair.getInt();
- }
-
- Type getType() const { return typeAndContainsFunctionAttrPair.getPointer(); }
- void setType(Type type) { typeAndContainsFunctionAttrPair.setPointer(type); }
-
- /// This field is a pair of:
- /// - The type of the attribute value.
- /// - A boolean that is true if this is, or contains, a function attribute.
- llvm::PointerIntPair<Type, 1, bool> typeAndContainsFunctionAttrPair;
-};
-
-// A utility class to get, or create, unique instances of attributes within an
-// MLIRContext. This class manages all creation and uniquing of attributes.
-class AttributeUniquer {
-public:
- /// Get an uniqued instance of attribute T.
- template <typename T, typename... Args>
- static T get(MLIRContext *ctx, Attribute::Kind kind, Args &&... args) {
- return ctx->getAttributeUniquer().get<typename T::ImplType>(
- [ctx](AttributeStorage *storage) {
- // If the attribute did not provide a type, then default to NoneType.
- if (!storage->getType())
- storage->setType(NoneType::get(ctx));
- },
- static_cast<unsigned>(kind), std::forward<Args>(args)...);
- }
-
- /// Erase a uniqued instance of attribute T.
- template <typename T, typename... Args>
- static void erase(MLIRContext *ctx, Attribute::Kind kind, Args &&... args) {
- return ctx->getAttributeUniquer().erase<typename T::ImplType>(
- static_cast<unsigned>(kind), std::forward<Args>(args)...);
- }
-};
-
-using AttributeStorageAllocator = StorageUniquer::StorageAllocator;
-
/// An attribute representing a boolean value.
struct BoolAttributeStorage : public AttributeStorage {
using KeyTy = std::pair<MLIRContext *, bool>;
using namespace mlir;
using namespace mlir::detail;
+//===----------------------------------------------------------------------===//
+// AttributeStorage
+//===----------------------------------------------------------------------===//
+
+AttributeStorage::AttributeStorage(Type type, bool isOrContainsFunctionCache)
+ : typeAndContainsFunctionAttrPair(type.getAsOpaquePointer(),
+ isOrContainsFunctionCache) {}
+AttributeStorage::AttributeStorage(bool isOrContainsFunctionCache)
+ : AttributeStorage(/*type=*/nullptr, isOrContainsFunctionCache) {}
+AttributeStorage::AttributeStorage()
+ : AttributeStorage(/*type=*/nullptr, /*isOrContainsFunctionCache=*/false) {}
+
+Type AttributeStorage::getType() const {
+ return Type::getFromOpaquePointer(
+ typeAndContainsFunctionAttrPair.getPointer());
+}
+void AttributeStorage::setType(Type type) {
+ typeAndContainsFunctionAttrPair.setPointer(type.getAsOpaquePointer());
+}
+
+/// Returns a functor used to initialize new attribute storage instances.
+std::function<void(AttributeStorage *)>
+AttributeUniquer::getInitFn(MLIRContext *ctx) {
+ return [ctx](AttributeStorage *storage) {
+ // If the attribute did not provide a type, then default to NoneType.
+ if (!storage->getType())
+ storage->setType(NoneType::get(ctx));
+ };
+}
+
+//===----------------------------------------------------------------------===//
+// Attribute
+//===----------------------------------------------------------------------===//
+
Attribute::Kind Attribute::getKind() const {
return static_cast<Kind>(attr->getKind());
}