13#ifndef MLIR_SUPPORT_INTERFACESUPPORT_H
14#define MLIR_SUPPORT_INTERFACESUPPORT_H
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/Support/TypeName.h"
70template <
typename ConcreteType,
typename ValueT,
typename Traits,
72 template <
typename,
template <
typename>
class>
class BaseTrait>
82 template <
typename T,
typename U>
87 template <
typename ConcreteT>
98 conceptImpl(t ? ConcreteType::getInterfaceFor(t) :
nullptr) {
99 assert((!t || conceptImpl) &&
100 "expected value to provide interface instance");
106 template <
typename T,
107 std::enable_if_t<std::is_base_of<Trait<T>, T>::value> * =
nullptr>
110 conceptImpl(t ? ConcreteType::getInterfaceFor(t) :
nullptr) {
111 assert((!t || conceptImpl) &&
112 "expected value to provide interface instance");
117 : BaseType(t), conceptImpl(const_cast<
Concept *>(conceptImpl)) {
118 assert(!t || ConcreteType::getInterfaceFor(t) == conceptImpl);
126 static bool classof(ValueT t) {
return ConcreteType::getInterfaceFor(t); }
138 Concept *conceptImpl;
149 template <
typename T,
typename... Args>
150 using has_get_interface_id =
decltype(T::getInterfaceID());
151 template <
typename T>
152 using detect_get_interface_id = llvm::is_detected<has_get_interface_id, T>;
155 template <
typename T,
typename... Args>
156 using has_initialize_method =
157 decltype(std::declval<T>().initializeInterfaceConcept(
158 std::declval<InterfaceMap &>()));
159 template <
typename T>
160 using detect_initialize_method = llvm::is_detected<has_initialize_method, T>;
165 template <
typename T,
typename =
void>
166 struct IsConstexprGeneratedModel : std::false_type {};
167 template <
typename T>
168 struct IsConstexprGeneratedModel<T, std::void_t<typename T::GeneratedModel>>
169 : std::bool_constant<std::is_same_v<T, typename T::GeneratedModel> &&
170 std::is_trivially_copy_constructible_v<T>> {};
182 template <
typename... Types>
184 constexpr size_t numInterfaces =
185 (
size_t{0} + ... + detect_get_interface_id<Types>::value);
186 if constexpr (numInterfaces == 0) {
192 (map.insertPotentialInterface<std::conditional_t<
193 detect_get_interface_id<Types>::value, Types,
void>>(),
201 template <
typename T>
203 return reinterpret_cast<typename T::Concept *
>(
lookup(T::getInterfaceID()));
210 template <
typename... IfaceModels>
212 (insertModel<IfaceModels>(), ...);
218 template <
typename T>
219 void insertPotentialInterface() {
220 if constexpr (detect_get_interface_id<T>::value)
221 insertModel<typename T::ModelT>();
225 template <
typename InterfaceModel>
234 InterfaceModel *model;
235 if constexpr (IsConstexprGeneratedModel<InterfaceModel>::value) {
236 static constexpr InterfaceModel prototype;
237 model =
new (malloc(
sizeof(InterfaceModel))) InterfaceModel(prototype);
241 model =
new (malloc(
sizeof(InterfaceModel))) InterfaceModel();
245 if constexpr (detect_initialize_method<InterfaceModel>::value)
246 model->initializeInterfaceConcept(*
this);
248 insert(InterfaceModel::Interface::getInterfaceID(), model);
252 void insert(TypeID interfaceId,
void *conceptImpl);
255 static bool compare(TypeID
lhs, TypeID
rhs) {
256 return lhs.getAsOpaquePointer() <
rhs.getAsOpaquePointer();
261 void *
lookup(TypeID
id)
const {
263 llvm::lower_bound(interfaces,
id, [](
const auto &it, TypeID
id) {
264 return compare(it.first,
id);
266 return (it != interfaces.end() && it->first ==
id) ? it->second :
nullptr;
270 SmallVector<std::pair<TypeID, void *>> interfaces;
273template <
typename ConcreteType,
typename ValueT,
typename Traits,
275 template <
typename,
template <
typename>
class>
class BaseTrait>
291struct DenseMapInfo<T, std::enable_if_t<mlir::detail::IsInterface<T>::value>> {
295 return ValueTypeInfo::getHashValue(val);
298 static bool isEqual(T lhs, T rhs) {
return ValueTypeInfo::isEqual(lhs, rhs); }
This class provides an efficient unique identifier for a specific C++ type.
static TypeID get()
Construct a type info object for the given type T.
void insertModels()
Insert the given interface models.
InterfaceMap(InterfaceMap &&)
T::Concept * lookup() const
Returns an instance of the concept object for the given interface if it was registered to this map,...
static InterfaceMap get()
Construct an InterfaceMap with the given set of template types.
bool contains(TypeID interfaceID) const
Returns true if the interface map contains an interface for the given id.
InterfaceMap & operator=(InterfaceMap &&rhs)
This class represents an abstract interface.
static bool classof(ValueT t)
Support 'classof' by checking if the given object defines the concrete interface.
Interface(ValueT t, const Concept *conceptImpl)
Constructor for a known concept.
Interface(std::nullptr_t)
Interface(ValueT t, std::nullptr_t)
Constructor for DenseMapInfo's empty key.
Interface(ValueT t=ValueT())
Construct an interface from an instance of the value type.
static TypeID getInterfaceID()
Define an accessor for the ID of this interface.
typename Traits::template ExternalModel< T, U > ExternalModel
Interface< ConcreteType, Attribute, Traits, Attribute, AttributeTrait::TraitBase > InterfaceBase
typename Traits::template FallbackModel< T > FallbackModel
typename Traits::template Model< T > Model
typename Traits::Concept Concept
const Concept * getImpl() const
Get the raw concept in the correct derived concept type.
Interface(T t)
Construct an interface instance from a type that implements this interface's trait.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
decltype(isInterfaceImpl(std::declval< T & >())) is_interface_t
llvm::is_detected< is_interface_t, T > IsInterface
void isInterfaceImpl(Interface< ConcreteType, ValueT, Traits, BaseType, BaseTrait > &)
Include the generated interface declarations.
static unsigned getHashValue(T val)
llvm::DenseMapInfo< typename T::ValueType > ValueTypeInfo
static bool isEqual(T lhs, T rhs)
This is a special trait that registers a given interface with an object.
static TypeID getInterfaceID()
Define an accessor for the ID of this interface.
Model< ConcreteT > ModelT