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"
68 template <
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");
116 assert(!t || ConcreteType::getInterfaceFor(t) == conceptImpl);
124 static bool classof(ValueT t) {
return ConcreteType::getInterfaceFor(t); }
136 Concept *conceptImpl;
145 template <
template <
class>
class Pred,
size_t N,
typename... Ts>
147 template <
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> {};
152 template <
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>
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>
195 if constexpr (numInterfaces == 0)
199 (map.insertPotentialInterface<Types>(), ...);
205 template <
typename T>
207 return reinterpret_cast<typename T::Concept *
>(
lookup(T::getInterfaceID()));
214 template <
typename... IfaceModels>
216 (insertModel<IfaceModels>(), ...);
222 template <
typename T>
223 inline void insertPotentialInterface() {
224 if constexpr (detect_get_interface_id<T>::value)
225 insertModel<typename T::ModelT>();
229 template <
typename InterfaceModel>
237 InterfaceModel *model =
238 new (malloc(
sizeof(InterfaceModel))) InterfaceModel();
239 if constexpr (detect_initialize_method<InterfaceModel>::value)
240 model->initializeInterfaceConcept(*
this);
242 insert(InterfaceModel::Interface::getInterfaceID(), model);
246 void insert(TypeID interfaceId,
void *conceptImpl);
249 static bool compare(TypeID lhs, TypeID rhs) {
250 return lhs.getAsOpaquePointer() < rhs.getAsOpaquePointer();
255 void *
lookup(TypeID
id)
const {
257 llvm::lower_bound(interfaces,
id, [](
const auto &it, TypeID
id) {
258 return compare(it.first,
id);
260 return (it != interfaces.end() && it->first == id) ? it->second :
nullptr;
264 SmallVector<std::pair<TypeID, void *>> interfaces;
267 template <
typename ConcreteType,
typename ValueT,
typename Traits,
269 template <
typename,
template <
typename>
class>
class BaseTrait>
273 template <
typename T>
276 template <
typename T>
284 template <
typename T>
285 struct DenseMapInfo<T, std::enable_if_t<mlir::detail::IsInterface<T>::value>> {
288 static T
getEmptyKey() {
return T(ValueTypeInfo::getEmptyKey(),
nullptr); }
291 return T(ValueTypeInfo::getTombstoneKey(),
nullptr);
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.
This class provides an efficient mapping between a given Interface type, and a particular implementat...
void insertModels()
Insert the given interface models.
InterfaceMap(InterfaceMap &&)=default
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.
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)
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
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.
void isInterfaceImpl(Interface< ConcreteType, ValueT, Traits, BaseType, BaseTrait > &)
decltype(isInterfaceImpl(std::declval< T & >())) is_interface_t
llvm::is_detected< is_interface_t, T > IsInterface
Include the generated interface declarations.
static T getTombstoneKey()
static unsigned getHashValue(T val)
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.