forked from OSchip/llvm-project
[MLIR] Add document about creating a dialect.
Goal is also to document best naming practices from here: https://llvm.discourse.group/t/rfc-canonical-file-paths-to-dialects/621 Differential Revision: https://reviews.llvm.org/D75762
This commit is contained in:
parent
53b135eeb4
commit
d774fbc350
|
@ -0,0 +1,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 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)
|
||||||
|
|
||||||
|
```
|
Loading…
Reference in New Issue