xref: /llvm-project/mlir/docs/Tutorials/CreatingADialect.md (revision 1294fa697176c244e92e72c0b01fd3b5e3a06477)
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