| # Creating a Dialect |
| |
| [TOC] |
| |
| Public dialects are typically separated into at least 3 directories: |
| * mlir/include/mlir/Dialect/Foo (for public include files) |
| * mlir/lib/Dialect/Foo (for sources) |
| * mlir/lib/Dialect/Foo/IR (for operations) |
| * mlir/lib/Dialect/Foo/Transforms (for transforms) |
| * mlir/test/Dialect/Foo (for tests) |
| |
| Along with other public headers, the 'include' directory contains a |
| TableGen file in the [ODS format](OpDefinitions.md), describing the |
| operations in the dialect. This is used to generate operation |
| declarations (FooOps.h.inc) and definitions (FooOps.cpp.inc) and |
| operation interface declarations (FooOpsInterfaces.h.inc) and |
| definitions (FooOpsInterfaces.cpp.inc). |
| |
| The 'IR' directory typically contains implementations of functions for |
| the dialect which are not automatically generated by ODS. These are |
| typically defined in FooDialect.cpp, which includes FooOps.cpp.inc and |
| FooOpsInterfaces.h.inc. |
| |
| The 'Transforms' directory contains rewrite rules for the dialect, |
| typically described in TableGen file using the [DDR |
| format](DeclarativeRewrites.md). |
| |
| Note that dialect names should not generally be suffixed with “Ops”, |
| although some files pertaining only to the operations of a dialect (e.g. |
| FooOps.cpp) might be. |
| |
| ## CMake best practices |
| |
| ### TableGen Targets |
| |
| Operations in dialects are typically declared using the ODS format in |
| tablegen in a file FooOps.td. This file forms the core of a dialect and |
| is declared using add_mlir_dialect(). |
| |
| ```cmake |
| add_mlir_dialect(FooOps foo) |
| add_mlir_doc(FooOps -gen-dialect-doc FooDialect Dialects/) |
| ``` |
| |
| This generates the correct rules to run mlir-tblgen, along with a |
| 'MLIRFooOpsIncGen' target which can be used to declare dependencies. |
| |
| Dialect transformations are typically declared in a file FooTransforms.td. |
| Targets for TableGen are described in typical llvm fashion. |
| |
| ```cmake |
| set(LLVM_TARGET_DEFINITIONS FooTransforms.td) |
| mlir_tablegen(FooTransforms.h.inc -gen-rewriters) |
| add_public_tablegen_target(MLIRFooTransformIncGen) |
| ``` |
| |
| The result is another 'IncGen' target, which runs mlir-tblgen. |
| |
| ### Library Targets |
| |
| Dialects may have multiple libraries. Each library is typically |
| declared with add_mlir_dialect_library(). Dialect libraries often |
| depend on the generation of header files from TableGen (specified |
| using the DEPENDS keyword). Dialect libraries may also depend on |
| other dialect libraries. Typically this dependence is declared using |
| target_link_libraries() and the PUBLIC keyword. For instance: |
| |
| ```cmake |
| add_mlir_dialect_library(MLIRFoo |
| DEPENDS |
| MLIRFooOpsIncGen |
| MLIRFooTransformsIncGen |
| |
| LINK_COMPONENTS |
| Core |
| |
| LINK_LIBS PUBLIC |
| MLIRBar |
| <some-other-library> |
| ) |
| ``` |
| |
| add_mlir_dialect_library() is a thin wrapper around add_llvm_library() |
| which collects a list of all the dialect libraries. This list is |
| often useful for linking tools (e.g. mlir-opt) which should have |
| access to all dialects. This list is also linked into libMLIR.so. |
| The list can be retrieved from the MLIR_DIALECT_LIBS global property: |
| |
| ```cmake |
| get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) |
| ``` |
| |
| Note that although the Bar dialect also uses TableGen to declare its |
| operations, it is not necessary to explicitly depend on the |
| corresponding IncGen targets. The PUBLIC link dependency is |
| sufficient. Also note that we avoid using add_dependencies |
| explicitly, since the dependencies need to be available to the |
| underlying add_llvm_library() call, allowing it to correctly create |
| new targets with the same sources. However, dialects that depend on |
| LLVM IR may need to depend on the LLVM 'intrinsics_gen' target to |
| ensure that tablegen'd LLVM header files have been generated. |
| |
| In addition, linkage to MLIR libraries is specified using the |
| LINK_LIBS descriptor and linkage to LLVM libraries is specified using |
| the LINK_COMPONENTS descriptor. This allows cmake infrastructure to |
| generate new library targets with correct linkage, in particular, when |
| BUILD_SHARED_LIBS=on or LLVM_LINK_LLVM_DYLIB=on are specified. |
| |
| |
| # Dialect Conversions |
| |
| Conversions from “X” to “Y” live in mlir/include/mlir/Conversion/XToY, |
| mlir/lib/Conversion/XToY and mlir/test/Conversion/XToY, respectively. |
| |
| Default file names for conversion should omit “Convert” from their |
| name, e.g. lib/VectorToLLVM/VectorToLLVM.cpp. |
| |
| Conversion passes should live separately from conversions themselves |
| for convenience of users that only care about a pass and not about its |
| implementation with patterns or other infrastructure. For example |
| include/mlir/VectorToLLVM/VectorToLLVMPass.h. |
| |
| Common conversion functionality from or to dialect “X” that does not |
| belong to the dialect definition can be located in |
| mlir/lib/Conversion/XCommon, for example |
| mlir/lib/Conversion/GPUCommon. |
| |
| ## CMake best practices |
| |
| Each conversion typically exists in a separate library, declared with |
| add_mlir_conversion_library(). Conversion libraries typically depend |
| on their source and target dialects, but may also depend on other |
| dialects (e.g. MLIRStandard). Typically this dependence is specified |
| using target_link_libraries() and the PUBLIC keyword. For instance: |
| |
| ```cmake |
| add_mlir_conversion_library(MLIRBarToFoo |
| BarToFoo.cpp |
| |
| ADDITIONAL_HEADER_DIRS |
| ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/BarToFoo |
| |
| LINK_LIBS PUBLIC |
| MLIRBar |
| MLIRFoo |
| ) |
| ``` |
| |
| add_mlir_conversion_library() is a thin wrapper around |
| add_llvm_library() which collects a list of all the conversion |
| libraries. This list is often useful for linking tools |
| (e.g. mlir-opt) which should have access to all dialects. This list |
| is also linked in libMLIR.so. The list can be retrieved from the |
| MLIR_CONVERSION_LIBS global property: |
| |
| ```cmake |
| get_property(dialect_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) |
| ``` |
| |
| Note that it is only necessary to specify a PUBLIC dependence against |
| dialects to generate compile-time and link-time dependencies, and it |
| is not necessary to explicitly depend on the dialects' IncGen targets. |
| However, conversions that directly include LLVM IR header files may |
| need to depend on the LLVM 'intrinsics_gen' target to ensure that |
| tablegen'd LLVM header files have been generated. |