aboutsummaryrefslogtreecommitdiff
path: root/mlir/docs/CreatingADialect.md
blob: 8c8d3a9bc0ebfcb82ee529184aa15da8197b4460 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# 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 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 FooOps)

```

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(FooOps
	DEPENDS
	MLIRFooOpsIncGen
	MLIRFooTransformsIncGen
	)
target_link_libraries(FooOps
	PUBLIC
	BarOps
	<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.



# Dialect Conversions

Conversions from “X” to “Y” live in mlir/include/mlir/Conversion/XToY,
mlir/lib/Convresion/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 specifid
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
	)
target_link_libraries(MLIRBarToFoo
	PUBLIC
	BarOps
	FooOps
	)

```

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)

```