Lines Matching defs:dialect
22 At the most fundamental level, defining a dialect in MLIR is as simple as
29 C++ code, significantly reduces maintainence burden when changing aspects of dialect
39 and other sub-components of the dialect to establish a proper layering between
40 the various different dialect components. It also prevents situations where you may
46 // our dialect.
49 // Here is a simple definition of a dialect.
51 let summary = "A short one line description of my dialect.";
53 My dialect is a very important dialect. This section contains a much more
58 /// This is the namespace of the dialect. It is used to encapsulate the sub-components
59 /// of the dialect, such as operations ("my_dialect.foo").
62 /// The C++ namespace that the dialect, and its sub-components, get placed in.
67 The above showcases a very simple description of a dialect, but dialects have lots
72 Every dialect must implement an initialization hook to add attributes, operations, types,
74 dialect that should happen on construction. This hook is declared for every dialect to
86 for the dialect. The `summary` field expects a simple single-line string, with the
88 used to generate markdown documentation for the dialect and is used by upstream
94 dialect definition, but with any `_` characters stripped out. This means that if you name
95 your dialect `Foo_Dialect`, the generated C++ class would be `FooDialect`. In the example
96 above, we would get a C++ dialect named `MyDialect`.
100 The namespace that the C++ class for our dialect, and all of its sub-components, is placed
101 under is specified by the `cppNamespace` field. By default, uses the name of the dialect as
106 Note that this works in conjunction with the dialect's C++ code. Depending on how the generated files
139 attributes or types, etc. When a dialect has a dependency on another, i.e. when it constructs and/or
140 generally relies on the components of another dialect, a dialect dependency should be explicitly
142 dialect. Dialect dependencies can be recorded using the `dependentDialects` dialects field:
146 // Here we register the Arithmetic and Func dialect as dependencies of our `MyDialect`.
168 a `Type`. This is generally used when an operation within this dialect has been folded,
170 materialization, and the `materializeConstant` hook is declared on the dialect. This
194 when the dialect has some special logic to be run in the `~MyDialect`. In this case,
201 by the dialect whose name prefixes that of the attribute. For example, if an
202 operation has an attribute named `gpu.contained_module`, the `gpu` dialect
205 by our dialect, several hooks on the Dialect may be used:
209 This field generates the hook for verifying when a discardable attribute of this dialect
214 /// dialect, that was used in `op`s dictionary.
220 This field generates the hook for verifying when a discardable attribute of this dialect
226 In these cases, those operations will invoke this hook on the dialect to ensure the attribute
227 is verified. The hook necessary for the dialect to implement has the form:
231 /// dialect, that was used on the attribute dictionary of a region entry block argument.
240 This field generates the hook for verifying when a discardable attribute of this dialect
246 dialect to ensure the attribute is verified. The hook necessary for the dialect to implement
251 /// of this dialect, that was used on the attribute dictionary of a region result.
263 interface, the query will fallback to the dialect itself. The `hasOperationInterfaceFallback`
273 [interface documentation](../Interfaces.md/#dialect-fallback-for-opinterface).
277 When a dialect registers an Attribute or Type, it must also override the respective
279 `Dialect::parseType`/`Dialect::printType` methods. In these cases, the dialect must
281 the dialect. If all of the attributes and types of the dialect provide a mnemonic,
284 these fields are set to `1`(enabled), meaning that if a dialect needs to explicitly handle the
290 operations within a dialect. There are some cases, however, that prompt canonicalization
291 patterns to be added to the dialect-level. For example, if a dialect defines a canonicalization
295 the `getCanonicalizationPatterns` method on the dialect, which has the form:
298 /// Return the canonicalization patterns for this dialect:
305 ### Defining bytecode format for dialect attributes and types
307 By default bytecode serialization of dialect attributes and types uses the
309 the attributes and types in dialect by defining & attaching
310 `BytecodeDialectInterface` to the dialect. Basic support for generating
311 readers/writers for the bytecode dialect interface can be generated using ODS's
314 One can define the printing and parsing for a type in dialect `Foo` as follow:
380 * Many of the common dialect bytecode reading and writing atoms (such as
390 following interface can define the bytecode dialect interface:
396 FooDialectBytecodeInterface(Dialect *dialect)
397 : BytecodeDialectInterface(dialect) {}
426 (`-gen-bytecode -bytecode-dialect="Quant"`).
428 ## Defining an Extensible dialect
435 ### Defining an extensible dialect
440 class contains the necessary fields and methods to extend the dialect at
463 if (auto extensibleDialect = llvm::dyn_cast<ExtensibleDialect>(dialect)) {
468 ### Defining a dynamic dialect
475 auto populateDialect = [](MLIRContext *ctx, DynamicDialect* dialect) {
476 // Code that will be ran when the dynamic dialect is created and loaded.
478 // attributes of the dialect.
485 Once a dynamic dialect is registered in the `MLIRContext`, it can be retrieved
489 Dialect *dialect = ctx->getOrLoadDialect("dialectName");
496 functions. An operation defined at runtime must provide a name, a dialect in
501 // The operation name, without the dialect name prefix.
504 // The dialect defining the operation.
505 Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
543 DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
585 functions. A type definition requires a name, the dialect that will register the
591 // The type name, without the dialect name prefix.
594 // The dialect defining the type.
595 Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
616 DynamicTypeDefinition::get(std::move(name), std::move(dialect),
622 generated with the format `!dialect.typename<arg1, arg2, ..., argN>`.
627 dialect->registerDynamicType(std::move(typeDef));
630 ### Parsing types defined at runtime in an extensible dialect
684 functions. An attribute definition requires a name, the dialect that will
690 // The attribute name, without the dialect name prefix.
693 // The dialect defining the attribute.
694 Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
715 DynamicAttrDefinition::get(std::move(name), std::move(dialect),
721 generated with the format `!dialect.attrname<arg1, arg2, ..., argN>`.
726 dialect->registerDynamicAttr(std::move(typeDef));
729 ### Parsing attributes defined at runtime in an extensible dialect
777 #### Extensible dialect