1# Creating a Dialect 2 3[TOC] 4 5Public dialects are typically separated into at least 3 directories: 6* mlir/include/mlir/Dialect/Foo (for public include files) 7* mlir/lib/Dialect/Foo (for sources) 8* mlir/lib/Dialect/Foo/IR (for operations) 9* mlir/lib/Dialect/Foo/Transforms (for transforms) 10* mlir/test/Dialect/Foo (for tests) 11 12Along with other public headers, the 'include' directory contains a 13TableGen file in the [ODS format](OpDefinitions.md), describing the 14operations in the dialect. This is used to generate operation 15declarations (FooOps.h.inc) and definitions (FooOps.cpp.inc) and 16operation interface declarations (FooOpsInterfaces.h.inc) and 17definitions (FooOpsInterfaces.cpp.inc). 18 19The 'IR' directory typically contains implementations of functions for 20the dialect which are not automatically generated by ODS. These are 21typically defined in FooDialect.cpp, which includes FooOps.cpp.inc and 22FooOpsInterfaces.h.inc. 23 24The 'Transforms' directory contains rewrite rules for the dialect, 25typically described in TableGen file using the [DDR 26format](DeclarativeRewrites.md). 27 28Note that dialect names should not generally be suffixed with “Ops”, 29although some files pertaining to the operations of a dialect (e.g. 30FooOps.cpp) might be. 31 32## CMake best practices 33 34### TableGen Targets 35 36Operations in dialects are typically declared using the ODS format in 37tablegen in a file FooOps.td. This file forms the core of a dialect and 38is declared using add_mlir_dialect(). 39 40```cmake 41 42add_mlir_dialect(FooOps foo) 43add_mlir_doc(FooOps -gen-dialect-doc FooDialect Dialects/) 44 45``` 46 47This generates the correct rules to run mlir-tblgen, along with a 48'MLIRFooOpsIncGen' target which can be used to declare dependencies. 49 50Dialect transformations are typically declared in a file FooTransforms.td. 51Targets for TableGen are described in typical llvm fashion. 52```cmake 53set(LLVM_TARGET_DEFINITIONS FooTransforms.td) 54mlir_tablegen(FooTransforms.h.inc -gen-rewriters) 55add_public_tablegen_target(MLIRFooTransformIncGen) 56``` 57 58The result is another 'IncGen' target, which runs mlir-tblgen. 59 60### Library Targets 61 62Dialects may have multiple libraries. Each library is typically 63declared with add_mlir_dialect_library(). Dialect libraries often 64depend on the generation of header files from TableGen (specified 65using the DEPENDS keyword). Dialect libraries may also depend on 66other dialect libraries. Typically this dependence is declared using 67target_link_libraries() and the PUBLIC keyword. For instance: 68 69```cmake 70 71add_mlir_dialect_library(FooOps 72 DEPENDS 73 MLIRFooOpsIncGen 74 MLIRFooTransformsIncGen 75 ) 76target_link_libraries(FooOps 77 PUBLIC 78 BarOps 79 <some-other-library> 80 ) 81 82``` 83 84add_mlir_dialect_library() is a thin wrapper around add_llvm_library() 85which collects a list of all the dialect libraries. This list is 86often useful for linking tools (e.g. mlir-opt) which should have 87access to all dialects. This list is also linked into libMLIR.so. 88The list can be retrieved from the MLIR_DIALECT_LIBS global property: 89 90```cmake 91 92get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 93 94``` 95 96Note that although the Bar dialect also uses TableGen to declare its 97operations, it is not necessary to explicitly depend on the 98corresponding IncGen targets. The PUBLIC link dependency is 99sufficient. Also note that we avoid using add_dependencies 100explicitly, since the dependencies need to be available to the 101underlying add_llvm_library() call, allowing it to correctly create 102new targets with the same sources. 103 104 105 106# Dialect Conversions 107 108Conversions from “X” to “Y” live in mlir/include/mlir/Conversion/XToY, 109mlir/lib/Conversion/XToY and mlir/test/Conversion/XToY, respectively. 110 111Default file names for conversion should omit “Convert” from their 112name, e.g. lib/VectorToLLVM/VectorToLLVM.cpp. 113 114Conversion passes should live separately from conversions themselves 115for convenience of users that only care about a pass and not about its 116implementation with patterns or other infrastructure. For example 117include/mlir/VectorToLLVM/VectorToLLVMPass.h. 118 119Common conversion functionality from or to dialect “X” that does not 120belong to the dialect definition can be located in 121mlir/lib/Conversion/XCommon, for example 122mlir/lib/Conversion/GPUCommon. 123 124## CMake best practices 125 126Each conversion typically exists in a separate library, declared with 127add_mlir_conversion_library(). Conversion libraries typically depend 128on their source and target dialects, but may also depend on other 129dialects (e.g. MLIRStandard). Typically this dependence is specified 130using target_link_libraries() and the PUBLIC keyword. For instance: 131 132```cmake 133 134add_mlir_conversion_library(MLIRBarToFoo 135 BarToFoo.cpp 136 137 ADDITIONAL_HEADER_DIRS 138 ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/BarToFoo 139 ) 140target_link_libraries(MLIRBarToFoo 141 PUBLIC 142 BarOps 143 FooOps 144 ) 145 146``` 147 148add_mlir_conversion_library() is a thin wrapper around 149add_llvm_library() which collects a list of all the conversion 150libraries. This list is often useful for linking tools 151(e.g. mlir-opt) which should have access to all dialects. This list 152is also linked in libMLIR.so. The list can be retrieved from the 153MLIR_CONVERSION_LIBS global property: 154 155```cmake 156 157get_property(dialect_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 158 159``` 160