13 #ifndef MLIR_IR_DIALECT_H
14 #define MLIR_IR_DIALECT_H
24 class DialectAsmParser;
25 class DialectAsmPrinter;
26 class DialectInterface;
103 llvm_unreachable(
"dialect has no registered attribute printing hook");
111 llvm_unreachable(
"dialect has no registered type printing hook");
118 virtual std::optional<ParseOpHook>
136 unsigned regionIndex,
145 unsigned regionIndex,
146 unsigned resultIndex,
166 auto it = registeredInterfaces.find(interfaceID);
167 return it != registeredInterfaces.end() ? it->getSecond().get() :
nullptr;
169 template <
typename InterfaceT>
173 InterfaceT::getInterfaceID(),
174 llvm::getTypeName<InterfaceT>());
177 return static_cast<InterfaceT *
>(
187 template <
typename InterfaceT>
188 typename InterfaceT::Concept *
190 return static_cast<typename InterfaceT::Concept *
>(
195 void addInterface(std::unique_ptr<DialectInterface> interface);
198 template <
typename... Args>
202 template <
typename InterfaceT,
typename... Args>
204 InterfaceT *
interface = new InterfaceT(this, std::forward<Args>(args)...);
205 addInterface(std::unique_ptr<DialectInterface>(interface));
213 template <typename ConcreteT, typename InterfaceT>
215 unresolvedPromisedInterfaces.insert(
216 {TypeID::get<ConcreteT>(), InterfaceT::getInterfaceID()});
225 StringRef interfaceName =
"") {
226 if (unresolvedPromisedInterfaces.count(
227 {interfaceRequestorID, interfaceID})) {
228 llvm::report_fatal_error(
229 "checking for an interface (`" + interfaceName +
231 "' but never implemented. This is generally an indication "
232 "that the dialect extension implementing the interface was never "
242 unresolvedPromisedInterfaces.erase({interfaceRequestorID, interfaceID});
247 TypeID interfaceID)
const {
248 return unresolvedPromisedInterfaces.count(
249 {interfaceRequestorID, interfaceID});
253 template <
typename ConcreteT,
typename InterfaceT>
256 InterfaceT::getInterfaceID());
271 template <
typename... Args>
277 (void)std::initializer_list<int>{
278 0, (RegisteredOperationName::insert<Args>(*
this), 0)...};
282 template <
typename... Args>
284 (addType<Args>(), ...);
293 template <
typename... Args>
295 (addAttribute<Args>(), ...);
311 void operator=(
Dialect &) =
delete;
314 template <
typename T>
315 void addAttribute() {
317 addAttribute(T::getTypeID(), AbstractAttribute::get<T>(*
this));
318 detail::AttributeUniquer::registerAttribute<T>(context);
322 template <
typename T>
325 addType(T::getTypeID(), AbstractType::get<T>(*
this));
326 detail::TypeUniquer::registerType<T>(context);
342 bool unknownOpsAllowed =
false;
347 bool unknownTypesAllowed =
false;
350 DenseMap<TypeID, std::unique_ptr<DialectInterface>> registeredInterfaces;
355 DenseSet<std::pair<TypeID, TypeID>> unresolvedPromisedInterfaces;
366 template <
typename T>
368 std::enable_if_t<std::is_base_of<::mlir::Dialect, T>::value>> {
369 static inline bool doit(const ::mlir::Dialect &dialect) {
370 return mlir::TypeID::get<T>() == dialect.getTypeID();
373 template <
typename T>
376 std::enable_if_t<std::is_base_of<::mlir::DialectInterface, T>::value>> {
377 static inline bool doit(const ::mlir::Dialect &dialect) {
378 return const_cast<::
mlir::Dialect &
>(dialect).getRegisteredInterface<T>();
381 template <
typename T>
385 template <
typename T>
390 template <
typename T>
392 template <
typename To>
393 static std::enable_if_t<std::is_base_of<::mlir::Dialect, To>::value, To &>
395 return static_cast<To &
>(dialect);
397 template <
typename To>
398 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 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 represents success/failure for parsing-like operations that find it important to chain tog...
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...
Include the generated interface declarations.
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
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 class represents an efficient way to signal success or failure.
This represents an operation in an abstracted form, suitable for use with the builder APIs.