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