//===- DialectInterface.h - IR Dialect Interfaces ---------------*- 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 // //===----------------------------------------------------------------------===// #ifndef MLIR_IR_DIALECTINTERFACE_H #define MLIR_IR_DIALECTINTERFACE_H #include "mlir/Support/TypeID.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include namespace mlir { class Dialect; class MLIRContext; class Operation; //===----------------------------------------------------------------------===// // DialectInterface //===----------------------------------------------------------------------===// namespace detail { /// The base class used for all derived interface types. This class provides /// utilities necessary for registration. template class DialectInterfaceBase : public BaseT { public: using Base = DialectInterfaceBase; /// Get a unique id for the derived interface type. static TypeID getInterfaceID() { return TypeID::get(); } protected: DialectInterfaceBase(Dialect *dialect) : BaseT(dialect, getInterfaceID()) {} }; } // namespace detail /// This class represents an interface overridden for a single dialect. class DialectInterface { public: virtual ~DialectInterface(); /// The base class used for all derived interface types. This class provides /// utilities necessary for registration. template using Base = detail::DialectInterfaceBase; /// Return the dialect that this interface represents. Dialect *getDialect() const { return dialect; } /// Return the context that holds the parent dialect of this interface. MLIRContext *getContext() const; /// Return the derived interface id. TypeID getID() const { return interfaceID; } protected: DialectInterface(Dialect *dialect, TypeID id) : dialect(dialect), interfaceID(id) {} private: /// The dialect that represents this interface. Dialect *dialect; /// The unique identifier for the derived interface type. TypeID interfaceID; }; //===----------------------------------------------------------------------===// // DialectInterfaceCollection //===----------------------------------------------------------------------===// namespace detail { /// This class is the base class for a collection of instances for a specific /// interface kind. class DialectInterfaceCollectionBase { /// DenseMap info for dialect interfaces that allows lookup by the dialect. struct InterfaceKeyInfo : public DenseMapInfo { using DenseMapInfo::isEqual; static unsigned getHashValue(Dialect *key) { return llvm::hash_value(key); } static unsigned getHashValue(const DialectInterface *key) { return getHashValue(key->getDialect()); } static bool isEqual(Dialect *lhs, const DialectInterface *rhs) { return lhs == rhs->getDialect(); } }; /// A set of registered dialect interface instances. using InterfaceSetT = DenseSet; using InterfaceVectorT = std::vector; public: DialectInterfaceCollectionBase(MLIRContext *ctx, TypeID interfaceKind, StringRef interfaceName); virtual ~DialectInterfaceCollectionBase(); protected: /// Get the interface for the dialect of given operation, or null if one /// is not registered. const DialectInterface *getInterfaceFor(Operation *op) const; /// Get the interface for the given dialect. const DialectInterface *getInterfaceFor(Dialect *dialect) const { auto it = interfaces.find_as(dialect); return it == interfaces.end() ? nullptr : *it; } /// An iterator class that iterates the held interface objects of the given /// derived interface type. template struct iterator : public llvm::mapped_iterator_base, InterfaceVectorT::const_iterator, const InterfaceT &> { using llvm::mapped_iterator_base, InterfaceVectorT::const_iterator, const InterfaceT &>::mapped_iterator_base; /// Map the element to the iterator result type. const InterfaceT &mapElement(const DialectInterface *interface) const { return *static_cast(interface); } }; /// Iterator access to the held interfaces. template iterator interface_begin() const { return iterator(orderedInterfaces.begin()); } template iterator interface_end() const { return iterator(orderedInterfaces.end()); } private: /// A set of registered dialect interface instances. InterfaceSetT interfaces; /// An ordered list of the registered interface instances, necessary for /// deterministic iteration. // NOTE: SetVector does not provide find access, so it can't be used here. InterfaceVectorT orderedInterfaces; }; } // namespace detail /// A collection of dialect interfaces within a context, for a given concrete /// interface type. template class DialectInterfaceCollection : public detail::DialectInterfaceCollectionBase { public: using Base = DialectInterfaceCollection; /// Collect the registered dialect interfaces within the provided context. DialectInterfaceCollection(MLIRContext *ctx) : detail::DialectInterfaceCollectionBase( ctx, InterfaceType::getInterfaceID(), llvm::getTypeName()) {} /// Get the interface for a given object, or null if one is not registered. /// The object may be a dialect or an operation instance. template const InterfaceType *getInterfaceFor(Object *obj) const { return static_cast( detail::DialectInterfaceCollectionBase::getInterfaceFor(obj)); } /// Iterator access to the held interfaces. using iterator = detail::DialectInterfaceCollectionBase::iterator; iterator begin() const { return interface_begin(); } iterator end() const { return interface_end(); } private: using detail::DialectInterfaceCollectionBase::interface_begin; using detail::DialectInterfaceCollectionBase::interface_end; }; } // namespace mlir #endif