155de49acSRiver Riddle# Creating a Dialect 255de49acSRiver Riddle 355de49acSRiver Riddle[TOC] 455de49acSRiver Riddle 555de49acSRiver RiddlePublic dialects are typically separated into at least 3 directories: 655de49acSRiver Riddle* mlir/include/mlir/Dialect/Foo (for public include files) 755de49acSRiver Riddle* mlir/lib/Dialect/Foo (for sources) 855de49acSRiver Riddle* mlir/lib/Dialect/Foo/IR (for operations) 955de49acSRiver Riddle* mlir/lib/Dialect/Foo/Transforms (for transforms) 1055de49acSRiver Riddle* mlir/test/Dialect/Foo (for tests) 1155de49acSRiver Riddle 1255de49acSRiver RiddleAlong with other public headers, the 'include' directory contains a 13*1294fa69SRiver RiddleTableGen file in the [ODS format](../DefiningDialects/Operations.md), describing the 1455de49acSRiver Riddleoperations in the dialect. This is used to generate operation 1555de49acSRiver Riddledeclarations (FooOps.h.inc) and definitions (FooOps.cpp.inc) and 1655de49acSRiver Riddleoperation interface declarations (FooOpsInterfaces.h.inc) and 1755de49acSRiver Riddledefinitions (FooOpsInterfaces.cpp.inc). 1855de49acSRiver Riddle 1955de49acSRiver RiddleThe 'IR' directory typically contains implementations of functions for 2055de49acSRiver Riddlethe dialect which are not automatically generated by ODS. These are 2155de49acSRiver Riddletypically defined in FooDialect.cpp, which includes FooOps.cpp.inc and 2255de49acSRiver RiddleFooOpsInterfaces.h.inc. 2355de49acSRiver Riddle 2455de49acSRiver RiddleThe 'Transforms' directory contains rewrite rules for the dialect, 2555de49acSRiver Riddletypically described in TableGen file using the [DDR 2631d1ae79SMarkus Böckformat](../DeclarativeRewrites.md). 2755de49acSRiver Riddle 2855de49acSRiver RiddleNote that dialect names should not generally be suffixed with “Ops”, 29d4e889f1SGeoffrey Martin-Noblealthough some files pertaining only to the operations of a dialect (e.g. 3055de49acSRiver RiddleFooOps.cpp) might be. 3155de49acSRiver Riddle 3255de49acSRiver Riddle## CMake best practices 3355de49acSRiver Riddle 3455de49acSRiver Riddle### TableGen Targets 3555de49acSRiver Riddle 3655de49acSRiver RiddleOperations in dialects are typically declared using the ODS format in 3755de49acSRiver Riddletablegen in a file FooOps.td. This file forms the core of a dialect and 3855de49acSRiver Riddleis declared using add_mlir_dialect(). 3955de49acSRiver Riddle 4055de49acSRiver Riddle```cmake 4155de49acSRiver Riddleadd_mlir_dialect(FooOps foo) 42ab78e09bSMarius Brehleradd_mlir_doc(FooOps FooDialect Dialects/ -gen-dialect-doc) 4355de49acSRiver Riddle``` 4455de49acSRiver Riddle 4555de49acSRiver RiddleThis generates the correct rules to run mlir-tblgen, along with a 4655de49acSRiver Riddle'MLIRFooOpsIncGen' target which can be used to declare dependencies. 4755de49acSRiver Riddle 4855de49acSRiver RiddleDialect transformations are typically declared in a file FooTransforms.td. 4955de49acSRiver RiddleTargets for TableGen are described in typical llvm fashion. 50d4e889f1SGeoffrey Martin-Noble 5155de49acSRiver Riddle```cmake 5255de49acSRiver Riddleset(LLVM_TARGET_DEFINITIONS FooTransforms.td) 5355de49acSRiver Riddlemlir_tablegen(FooTransforms.h.inc -gen-rewriters) 5455de49acSRiver Riddleadd_public_tablegen_target(MLIRFooTransformIncGen) 5555de49acSRiver Riddle``` 5655de49acSRiver Riddle 5755de49acSRiver RiddleThe result is another 'IncGen' target, which runs mlir-tblgen. 5855de49acSRiver Riddle 5955de49acSRiver Riddle### Library Targets 6055de49acSRiver Riddle 6155de49acSRiver RiddleDialects may have multiple libraries. Each library is typically 6255de49acSRiver Riddledeclared with add_mlir_dialect_library(). Dialect libraries often 6355de49acSRiver Riddledepend on the generation of header files from TableGen (specified 6455de49acSRiver Riddleusing the DEPENDS keyword). Dialect libraries may also depend on 6555de49acSRiver Riddleother dialect libraries. Typically this dependence is declared using 6655de49acSRiver Riddletarget_link_libraries() and the PUBLIC keyword. For instance: 6755de49acSRiver Riddle 6855de49acSRiver Riddle```cmake 69d4e889f1SGeoffrey Martin-Nobleadd_mlir_dialect_library(MLIRFoo 7055de49acSRiver Riddle DEPENDS 7155de49acSRiver Riddle MLIRFooOpsIncGen 7255de49acSRiver Riddle MLIRFooTransformsIncGen 7393f7e525SStephen Neuendorffer 7493f7e525SStephen Neuendorffer LINK_COMPONENTS 7593f7e525SStephen Neuendorffer Core 7693f7e525SStephen Neuendorffer 7793f7e525SStephen Neuendorffer LINK_LIBS PUBLIC 78d4e889f1SGeoffrey Martin-Noble MLIRBar 7955de49acSRiver Riddle <some-other-library> 8055de49acSRiver Riddle ) 8155de49acSRiver Riddle``` 8255de49acSRiver Riddle 8355de49acSRiver Riddleadd_mlir_dialect_library() is a thin wrapper around add_llvm_library() 8455de49acSRiver Riddlewhich collects a list of all the dialect libraries. This list is 8555de49acSRiver Riddleoften useful for linking tools (e.g. mlir-opt) which should have 8655de49acSRiver Riddleaccess to all dialects. This list is also linked into libMLIR.so. 8755de49acSRiver RiddleThe list can be retrieved from the MLIR_DIALECT_LIBS global property: 8855de49acSRiver Riddle 8955de49acSRiver Riddle```cmake 9055de49acSRiver Riddleget_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) 9155de49acSRiver Riddle``` 9255de49acSRiver Riddle 9355de49acSRiver RiddleNote that although the Bar dialect also uses TableGen to declare its 9455de49acSRiver Riddleoperations, it is not necessary to explicitly depend on the 9555de49acSRiver Riddlecorresponding IncGen targets. The PUBLIC link dependency is 9655de49acSRiver Riddlesufficient. Also note that we avoid using add_dependencies 9755de49acSRiver Riddleexplicitly, since the dependencies need to be available to the 9855de49acSRiver Riddleunderlying add_llvm_library() call, allowing it to correctly create 9993f7e525SStephen Neuendorffernew targets with the same sources. However, dialects that depend on 10093f7e525SStephen NeuendorfferLLVM IR may need to depend on the LLVM 'intrinsics_gen' target to 10193f7e525SStephen Neuendorfferensure that tablegen'd LLVM header files have been generated. 10255de49acSRiver Riddle 10393f7e525SStephen NeuendorfferIn addition, linkage to MLIR libraries is specified using the 10493f7e525SStephen NeuendorfferLINK_LIBS descriptor and linkage to LLVM libraries is specified using 10593f7e525SStephen Neuendorfferthe LINK_COMPONENTS descriptor. This allows cmake infrastructure to 10693f7e525SStephen Neuendorffergenerate new library targets with correct linkage, in particular, when 10793f7e525SStephen NeuendorfferBUILD_SHARED_LIBS=on or LLVM_LINK_LLVM_DYLIB=on are specified. 10855de49acSRiver Riddle 10955de49acSRiver Riddle 11055de49acSRiver Riddle# Dialect Conversions 11155de49acSRiver Riddle 11255de49acSRiver RiddleConversions from “X” to “Y” live in mlir/include/mlir/Conversion/XToY, 11355de49acSRiver Riddlemlir/lib/Conversion/XToY and mlir/test/Conversion/XToY, respectively. 11455de49acSRiver Riddle 11555de49acSRiver RiddleDefault file names for conversion should omit “Convert” from their 11655de49acSRiver Riddlename, e.g. lib/VectorToLLVM/VectorToLLVM.cpp. 11755de49acSRiver Riddle 11855de49acSRiver RiddleConversion passes should live separately from conversions themselves 11955de49acSRiver Riddlefor convenience of users that only care about a pass and not about its 12055de49acSRiver Riddleimplementation with patterns or other infrastructure. For example 12155de49acSRiver Riddleinclude/mlir/VectorToLLVM/VectorToLLVMPass.h. 12255de49acSRiver Riddle 12355de49acSRiver RiddleCommon conversion functionality from or to dialect “X” that does not 12455de49acSRiver Riddlebelong to the dialect definition can be located in 12555de49acSRiver Riddlemlir/lib/Conversion/XCommon, for example 12655de49acSRiver Riddlemlir/lib/Conversion/GPUCommon. 12755de49acSRiver Riddle 12855de49acSRiver Riddle## CMake best practices 12955de49acSRiver Riddle 13055de49acSRiver RiddleEach conversion typically exists in a separate library, declared with 13155de49acSRiver Riddleadd_mlir_conversion_library(). Conversion libraries typically depend 13255de49acSRiver Riddleon their source and target dialects, but may also depend on other 13323aa5a74SRiver Riddledialects (e.g. MLIRFunc). Typically this dependence is specified 13455de49acSRiver Riddleusing target_link_libraries() and the PUBLIC keyword. For instance: 13555de49acSRiver Riddle 13655de49acSRiver Riddle```cmake 13755de49acSRiver Riddleadd_mlir_conversion_library(MLIRBarToFoo 13855de49acSRiver Riddle BarToFoo.cpp 13955de49acSRiver Riddle 14055de49acSRiver Riddle ADDITIONAL_HEADER_DIRS 14155de49acSRiver Riddle ${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/BarToFoo 14293f7e525SStephen Neuendorffer 14393f7e525SStephen Neuendorffer LINK_LIBS PUBLIC 144d4e889f1SGeoffrey Martin-Noble MLIRBar 145d4e889f1SGeoffrey Martin-Noble MLIRFoo 14655de49acSRiver Riddle ) 14755de49acSRiver Riddle``` 14855de49acSRiver Riddle 14955de49acSRiver Riddleadd_mlir_conversion_library() is a thin wrapper around 15055de49acSRiver Riddleadd_llvm_library() which collects a list of all the conversion 15155de49acSRiver Riddlelibraries. This list is often useful for linking tools 15255de49acSRiver Riddle(e.g. mlir-opt) which should have access to all dialects. This list 15355de49acSRiver Riddleis also linked in libMLIR.so. The list can be retrieved from the 15455de49acSRiver RiddleMLIR_CONVERSION_LIBS global property: 15555de49acSRiver Riddle 15655de49acSRiver Riddle```cmake 15755de49acSRiver Riddleget_property(dialect_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS) 15855de49acSRiver Riddle``` 15993f7e525SStephen Neuendorffer 16093f7e525SStephen NeuendorfferNote that it is only necessary to specify a PUBLIC dependence against 16193f7e525SStephen Neuendorfferdialects to generate compile-time and link-time dependencies, and it 16293f7e525SStephen Neuendorfferis not necessary to explicitly depend on the dialects' IncGen targets. 16393f7e525SStephen NeuendorfferHowever, conversions that directly include LLVM IR header files may 16493f7e525SStephen Neuendorfferneed to depend on the LLVM 'intrinsics_gen' target to ensure that 16593f7e525SStephen Neuendorffertablegen'd LLVM header files have been generated. 166