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"
68template <
typename ConcreteType,
typename ValueT,
typename Traits,
70 template <
typename,
template <
typename>
class>
class BaseTrait>
80 template <
typename T,
typename U>
85 template <
typename ConcreteT>
96 conceptImpl(t ? ConcreteType::getInterfaceFor(t) :
nullptr) {
97 assert((!t || conceptImpl) &&
98 "expected value to provide interface instance");
104 template <
typename T,
105 std::enable_if_t<std::is_base_of<Trait<T>, T>::value> * =
nullptr>
108 conceptImpl(t ? ConcreteType::getInterfaceFor(t) :
nullptr) {
109 assert((!t || conceptImpl) &&
110 "expected value to provide interface instance");
115 : BaseType(t), conceptImpl(const_cast<
Concept *>(conceptImpl)) {
116 assert(!t || ConcreteType::getInterfaceFor(t) == conceptImpl);
124 static bool classof(ValueT t) {
return ConcreteType::getInterfaceFor(t); }
136 Concept *conceptImpl;
145template <
template <
class>
class Pred,
size_t N,
typename... Ts>
147template <
template <
class>
class Pred,
size_t N,
typename T,
typename... Us>
149 :
public std::integral_constant<
151 count_if_t_impl<Pred, N + (Pred<T>::value ? 1 : 0), Us...>::value> {};
152template <
template <
class>
class Pred,
typename... Ts>
159 template <
typename T,
typename... Args>
160 using has_get_interface_id =
decltype(T::getInterfaceID());
161 template <
typename T>
162 using detect_get_interface_id = llvm::is_detected<has_get_interface_id, T>;
163 template <
typename... Types>
164 using num_interface_types_t =
count_if_t<detect_get_interface_id, Types...>;
167 template <
typename T,
typename... Args>
168 using has_initialize_method =
169 decltype(std::declval<T>().initializeInterfaceConcept(
170 std::declval<InterfaceMap &>()));
171 template <
typename T>
172 using detect_initialize_method = llvm::is_detected<has_initialize_method, T>;
178 for (
auto &it : interfaces)
180 interfaces = std::move(
rhs.interfaces);
184 for (
auto &it : interfaces)
192 template <
typename... Types>
194 constexpr size_t numInterfaces = num_interface_types_t<Types...>::value;
195 if constexpr (numInterfaces == 0) {
199 map.insertPotentialInterfaces<Types...>();
206 template <
typename T>
208 return reinterpret_cast<typename T::Concept *
>(
lookup(T::getInterfaceID()));
215 template <
typename... IfaceModels>
217 (insertModel<IfaceModels>(), ...);
223 template <
typename T>
224 void insertPotentialInterfaces() {
225 insertPotentialInterface<T>();
227 template <
typename T,
typename T2,
typename... Rest>
228 void insertPotentialInterfaces() {
229 insertPotentialInterface<T>();
230 insertPotentialInterfaces<T2, Rest...>();
235 template <
typename T>
236 inline void insertPotentialInterface() {
237 if constexpr (detect_get_interface_id<T>::value)
238 insertModel<typename T::ModelT>();
242 template <
typename InterfaceModel>
250 InterfaceModel *model =
251 new (malloc(
sizeof(InterfaceModel))) InterfaceModel();
252 if constexpr (detect_initialize_method<InterfaceModel>::value)
253 model->initializeInterfaceConcept(*
this);
255 insert(InterfaceModel::Interface::getInterfaceID(), model);
259 void insert(TypeID interfaceId,
void *conceptImpl);
262 static bool compare(TypeID
lhs, TypeID
rhs) {
263 return lhs.getAsOpaquePointer() <
rhs.getAsOpaquePointer();
268 void *
lookup(TypeID
id)
const {
270 llvm::lower_bound(interfaces,
id, [](
const auto &it, TypeID
id) {
271 return compare(it.first,
id);
273 return (it != interfaces.end() && it->first ==
id) ? it->second :
nullptr;
277 SmallVector<std::pair<TypeID, void *>> interfaces;
280template <
typename ConcreteType,
typename ValueT,
typename Traits,
282 template <
typename,
template <
typename>
class>
class BaseTrait>
298struct DenseMapInfo<T, std::enable_if_t<mlir::detail::IsInterface<T>::value>> {
301 static T
getEmptyKey() {
return T(ValueTypeInfo::getEmptyKey(),
nullptr); }
304 return T(ValueTypeInfo::getTombstoneKey(),
nullptr);
308 return ValueTypeInfo::getHashValue(val);
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 &&)=default
T::Concept * lookup() const
Returns an instance of the concept object for the given interface if it was registered to this map,...
InterfaceMap & operator=(InterfaceMap &&rhs)
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.
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 and tombstone 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 > &)
count_if_t_impl< Pred, 0, Ts... > count_if_t
Include the generated interface declarations.
static T getTombstoneKey()
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
Template utility that computes the number of elements within T that satisfy the given predicate.