Simplify TypeUniquer/AttributeUniquer to not require multiple overloads when constructing a new storage.

--

PiperOrigin-RevId: 246356767
This commit is contained in:
River Riddle 2019-05-02 11:27:58 -07:00 committed by Mehdi Amini
parent dd726ea99d
commit 920b8a9bda
3 changed files with 27 additions and 67 deletions

View File

@ -104,34 +104,14 @@ namespace detail {
// MLIRContext. This class manages all creation and uniquing of types.
class TypeUniquer {
public:
/// Get an uniqued instance of a type T. This overload is used for derived
/// types that have complex storage or uniquing constraints.
/// Get an uniqued instance of a type T.
template <typename T, typename... Args>
static typename std::enable_if<
!std::is_same<typename T::ImplType, DefaultTypeStorage>::value, T>::type
get(MLIRContext *ctx, unsigned kind, Args &&... args) {
// Lookup an instance of this complex storage type.
using ImplType = typename T::ImplType;
return ctx->getTypeUniquer().getComplex<ImplType>(
[&](ImplType *storage) {
storage->initializeDialect(lookupDialectForType<T>(ctx));
},
kind, std::forward<Args>(args)...);
}
/// Get an uniqued instance of a type T. This overload is used for derived
/// types that use the DefaultTypeStorage and thus need no additional storage
/// or uniquing.
template <typename T, typename... Args>
static typename std::enable_if<
std::is_same<typename T::ImplType, DefaultTypeStorage>::value, T>::type
get(MLIRContext *ctx, unsigned kind) {
// Lookup an instance of this simple storage type.
return ctx->getTypeUniquer().getSimple<TypeStorage>(
static T get(MLIRContext *ctx, unsigned kind, Args &&... args) {
return ctx->getTypeUniquer().get<typename T::ImplType>(
[&](TypeStorage *storage) {
storage->initializeDialect(lookupDialectForType<T>(ctx));
},
kind);
kind, std::forward<Args>(args)...);
}
private:

View File

@ -122,11 +122,12 @@ public:
/// that can be used to initialize a newly inserted storage instance. This
/// function is used for derived types that have complex storage or uniquing
/// constraints.
template <typename Storage, typename... Args>
Storage *getComplex(std::function<void(Storage *)> initFn, unsigned kind,
Args &&... args) {
template <typename Storage, typename Arg, typename... Args>
Storage *get(std::function<void(Storage *)> initFn, unsigned kind, Arg &&arg,
Args &&... args) {
// Construct a value of the derived key type.
auto derivedKey = getKey<Storage>(args...);
auto derivedKey =
getKey<Storage>(std::forward<Arg>(arg), std::forward<Args>(args)...);
// Create a hash of the kind and the derived key.
unsigned hashValue = getHash<Storage>(kind, derivedKey);
@ -155,7 +156,7 @@ public:
/// function is used for derived types that use no additional storage or
/// uniquing outside of the kind.
template <typename Storage>
Storage *getSimple(std::function<void(Storage *)> initFn, unsigned kind) {
Storage *get(std::function<void(Storage *)> initFn, unsigned kind) {
auto ctorFn = [&](StorageAllocator &allocator) {
auto *storage = new (allocator.allocate<Storage>()) Storage();
if (initFn)
@ -167,10 +168,11 @@ public:
/// Erases a uniqued instance of 'Storage'. This function is used for derived
/// types that have complex storage or uniquing constraints.
template <typename Storage, typename... Args>
void eraseComplex(unsigned kind, Args &&... args) {
template <typename Storage, typename Arg, typename... Args>
void erase(unsigned kind, Arg &&arg, Args &&... args) {
// Construct a value of the derived key type.
auto derivedKey = getKey<Storage>(args...);
auto derivedKey =
getKey<Storage>(std::forward<Arg>(arg), std::forward<Args>(args)...);
// Create a hash of the kind and the derived key.
unsigned hashValue = getHash<Storage>(kind, derivedKey);

View File

@ -67,45 +67,23 @@ struct AttributeStorage : public StorageUniquer::BaseStorage {
// MLIRContext. This class manages all creation and uniquing of attributes.
class AttributeUniquer {
public:
/// Get an uniqued instance of attribute T. This overload is used for
/// derived attributes that have complex storage or uniquing constraints.
/// Get an uniqued instance of attribute T.
template <typename T, typename... Args>
static typename std::enable_if<
!std::is_same<typename T::ImplType, AttributeStorage>::value, T>::type
get(MLIRContext *ctx, Attribute::Kind kind, Args &&... args) {
return ctx->getAttributeUniquer().getComplex<typename T::ImplType>(
getInitFn(ctx), static_cast<unsigned>(kind),
std::forward<Args>(args)...);
}
/// Get an uniqued instance of attribute T. This overload is used for
/// derived attributes that use the AttributeStorage directly and thus need no
/// additional storage or uniquing.
template <typename T, typename... Args>
static typename std::enable_if<
std::is_same<typename T::ImplType, AttributeStorage>::value, T>::type
get(MLIRContext *ctx, Attribute::Kind kind) {
return ctx->getAttributeUniquer().getSimple<AttributeStorage>(
getInitFn(ctx), static_cast<unsigned>(kind));
}
/// Erase a uniqued instance of attribute T. This overload is used for
/// derived attributes that have complex storage or uniquing constraints.
template <typename T, typename... Args>
static typename std::enable_if<
!std::is_same<typename T::ImplType, AttributeStorage>::value>::type
erase(MLIRContext *ctx, Attribute::Kind kind, Args &&... args) {
return ctx->getAttributeUniquer().eraseComplex<typename T::ImplType>(
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)...);
}
/// Generate a functor to initialize a new attribute storage instance.
static std::function<void(AttributeStorage *)> 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));
};
/// 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)...);
}
};