13 #ifndef MLIR_IR_DIALECT_H
14 #define MLIR_IR_DIALECT_H
21 class DialectAsmParser;
22 class DialectAsmPrinter;
23 class DialectInterface;
100 llvm_unreachable(
"dialect has no registered attribute printing hook");
108 llvm_unreachable(
"dialect has no registered type printing hook");
115 virtual std::optional<ParseOpHook>
133 unsigned regionIndex,
142 unsigned regionIndex,
143 unsigned resultIndex,
163 auto it = registeredInterfaces.find(interfaceID);
164 return it != registeredInterfaces.end() ? it->getSecond().get() :
nullptr;
166 template <
typename InterfaceT>
170 InterfaceT::getInterfaceID(),
171 llvm::getTypeName<InterfaceT>());
174 return static_cast<InterfaceT *
>(
184 template <
typename InterfaceT>
185 typename InterfaceT::Concept *
187 return static_cast<typename InterfaceT::Concept *
>(
192 void addInterface(std::unique_ptr<DialectInterface> interface);
195 template <
typename... Args>
199 template <
typename InterfaceT,
typename... Args>
201 InterfaceT *
interface = new InterfaceT(this, std::forward<Args>(args)...);
202 addInterface(std::unique_ptr<DialectInterface>(interface));
210 template <typename InterfaceT, typename ConcreteT>
212 unresolvedPromisedInterfaces.insert(
213 {TypeID::get<ConcreteT>(), InterfaceT::getInterfaceID()});
219 template <
typename InterfaceT,
typename... ConcreteT>
221 (declarePromisedInterface<InterfaceT, ConcreteT>(), ...);
230 StringRef interfaceName =
"") {
231 if (unresolvedPromisedInterfaces.count(
232 {interfaceRequestorID, interfaceID})) {
233 llvm::report_fatal_error(
234 "checking for an interface (`" + interfaceName +
236 "' but never implemented. This is generally an indication "
237 "that the dialect extension implementing the interface was never "
247 unresolvedPromisedInterfaces.erase({interfaceRequestorID, interfaceID});
252 TypeID interfaceID)
const {
253 return unresolvedPromisedInterfaces.count(
254 {interfaceRequestorID, interfaceID});
258 template <
typename ConcreteT,
typename InterfaceT>
261 InterfaceT::getInterfaceID());
276 template <
typename... Args>
282 (void)std::initializer_list<int>{
283 0, (RegisteredOperationName::insert<Args>(*
this), 0)...};
287 template <
typename... Args>
293 (void)std::initializer_list<int>{0, (addType<Args>(), 0)...};
302 template <
typename... Args>
308 (void)std::initializer_list<int>{0, (addAttribute<Args>(), 0)...};
324 void operator=(
Dialect &) =
delete;
327 template <
typename T>
328 void addAttribute() {
330 addAttribute(T::getTypeID(), AbstractAttribute::get<T>(*
this));
331 detail::AttributeUniquer::registerAttribute<T>(context);
335 template <
typename T>
338 addType(T::getTypeID(), AbstractType::get<T>(*
this));
339 detail::TypeUniquer::registerType<T>(context);
355 bool unknownOpsAllowed =
false;
360 bool unknownTypesAllowed =
false;
363 DenseMap<TypeID, std::unique_ptr<DialectInterface>> registeredInterfaces;
368 DenseSet<std::pair<TypeID, TypeID>> unresolvedPromisedInterfaces;
379 template <
typename T>
381 std::enable_if_t<std::is_base_of<::mlir::Dialect, T>::value>> {
382 static inline bool doit(const ::mlir::Dialect &dialect) {
383 return mlir::TypeID::get<T>() == dialect.getTypeID();
386 template <
typename T>
389 std::enable_if_t<std::is_base_of<::mlir::DialectInterface, T>::value>> {
390 static inline bool doit(const ::mlir::Dialect &dialect) {
391 return const_cast<::
mlir::Dialect &
>(dialect).getRegisteredInterface<T>();
394 template <
typename T>
398 template <
typename T>
403 template <
typename T>
405 template <
typename To>
406 static std::enable_if_t<std::is_base_of<::mlir::Dialect, To>::value, To &>
408 return static_cast<To &
>(dialect);
410 template <
typename To>
411 static std::enable_if_t<std::is_base_of<::mlir::DialectInterface, To>::value,
This class contains all of the static information common to all instances of a registered Attribute.
This class contains all of the static information common to all instances of a registered Type.
Attributes are known-constant values of operations.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class represents an interface overridden for a single dialect.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
void addAttributes()
Register a set of attribute classes with this dialect.
void addInterfaces()
Register a set of dialect interfaces with this dialect instance.
virtual void * getRegisteredInterfaceForOp(TypeID interfaceID, OperationName opName)
Lookup an op interface for the given ID if one is registered, otherwise nullptr.
virtual Type parseType(DialectAsmParser &parser) const
Parse a type registered to this dialect.
virtual std::optional< ParseOpHook > getParseOperationHook(StringRef opName) const
Return the hook to parse an operation registered to this dialect, if any.
void handleUseOfUndefinedPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID, StringRef interfaceName="")
Checks if the given interface, which is attempting to be used, is a promised interface of this dialec...
StringRef getNamespace() const
static bool isValidNamespace(StringRef str)
Utility function that returns if the given string is a valid dialect namespace.
virtual LogicalResult verifyRegionResultAttribute(Operation *, unsigned regionIndex, unsigned resultIndex, NamedAttribute)
Verify an attribute from this dialect on the result at 'resultIndex' for the region at 'regionIndex' ...
DialectInterface * getRegisteredInterface(TypeID interfaceID)
Lookup an interface for the given ID if one is registered, otherwise nullptr.
InterfaceT::Concept * getRegisteredInterfaceForOp(OperationName opName)
virtual LogicalResult verifyRegionArgAttribute(Operation *, unsigned regionIndex, unsigned argIndex, NamedAttribute)
Verify an attribute from this dialect on the argument at 'argIndex' for the region at 'regionIndex' o...
void addOperations()
This method is used by derived classes to add their operations to the set.
bool hasPromisedInterface() const
Checks if a promise has been made for the interface/requestor pair.
InterfaceT * getRegisteredInterface()
void declarePromisedInterface()
Declare that the given interface will be implemented, but has a delayed registration.
virtual llvm::unique_function< void(Operation *, OpAsmPrinter &printer)> getOperationPrinter(Operation *op) const
Print an operation registered to this dialect.
void handleAdditionOfUndefinedPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID)
Checks if the given interface, which is attempting to be attached to a construct owned by this dialec...
bool allowsUnknownTypes() const
Return true if this dialect allows for unregistered types, i.e., types prefixed with the dialect name...
virtual void printAttribute(Attribute, DialectAsmPrinter &) const
Print an attribute registered to this dialect.
void addTypes()
Register a set of type classes with this dialect.
virtual void printType(Type, DialectAsmPrinter &) const
Print a type registered to this dialect.
MLIRContext * getContext() const
void allowUnknownTypes(bool allow=true)
Enable support for unregistered types.
virtual LogicalResult verifyOperationAttribute(Operation *, NamedAttribute)
Verify an attribute from this dialect on the given operation.
void allowUnknownOperations(bool allow=true)
Enable support for unregistered operations.
bool allowsUnknownOperations() const
Returns true if this dialect allows for unregistered operations, i.e.
virtual Attribute parseAttribute(DialectAsmParser &parser, Type type) const
Parse an attribute registered to this dialect.
void declarePromisedInterfaces()
void addInterface(std::unique_ptr< DialectInterface > interface)
Register a dialect interface with this dialect instance.
TypeID getTypeID() const
Returns the unique identifier that corresponds to this dialect.
bool hasPromisedInterface(TypeID interfaceRequestorID, TypeID interfaceID) const
Checks if a promise has been made for the interface/requestor pair.
friend void registerDialect()
Dialect(StringRef name, MLIRContext *context, TypeID id)
The constructor takes a unique namespace for this dialect as well as the context to bind to.
InterfaceT & addInterface(Args &&...args)
virtual void getCanonicalizationPatterns(RewritePatternSet &results) const
Register dialect-wide canonicalization patterns.
virtual Operation * materializeConstant(OpBuilder &builder, Attribute value, Type type, Location loc)
Registered hook to materialize a single constant operation from a given attribute value with the desi...
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
NamedAttribute represents a combination of a name and an Attribute value.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This class helps build Operations.
Operation is the basic unit of execution within MLIR.
This class provides an efficient unique identifier for a specific C++ type.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
The OpAsmOpInterface, see OpAsmInterface.td for more details.
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
static auto & doit(::mlir::Dialect &dialect)
static std::enable_if_t< std::is_base_of<::mlir::Dialect, To >::value, To & > doitImpl(::mlir::Dialect &dialect)
static std::enable_if_t< std::is_base_of<::mlir::DialectInterface, To >::value, To & > doitImpl(::mlir::Dialect &dialect)
static auto doit(::mlir::Dialect *dialect)
static bool doit(const ::mlir::Dialect &dialect)
static bool doit(const ::mlir::Dialect &dialect)
This represents an operation in an abstracted form, suitable for use with the builder APIs.