Files
clang-p2996/mlir/docs/DefiningDialects/Constraints.md
Matthias Springer a3d41879ec [mlir][ODS] Optionally generate public C++ functions for type constraints (#104577)
Add `gen-type-constraint-decls` and `gen-type-constraint-defs`, which
generate public C++ functions for type constraints. The name of the C++
function is specified in the `cppFunctionName` field.

Type constraints are typically used for op/type/attribute verification.
They are also sometimes called from builders and transformations. Until
now, this required duplicating the check in C++.

Note: This commit just adds the option for type constraints, but
attribute constraints could be supported in the same way.

Alternatives considered:
1. The C++ functions could also be generated as part of
`gen-typedef-decls/defs`, but that can be confusing because type
constraints may rely on type definitions from multiple `.td` files.
`#include`s could cause duplicate definitions of the same type
constraint.
2. The C++ functions could also be generated as static member functions
of dialects, but they don't really belong to a dialect. (Because they
may rely on type definitions from multiple dialects.)
2024-08-21 08:44:54 +02:00

60 lines
2.2 KiB
Markdown

# Constraints
[TOC]
## Attribute / Type Constraints
When defining the arguments of an operation in TableGen, users can specify
either plain attributes/types or use attribute/type constraints to levy
additional requirements on the attribute value or operand type.
```tablegen
def My_Type1 : MyDialect_Type<"Type1", "type1"> { ... }
def My_Type2 : MyDialect_Type<"Type2", "type2"> { ... }
// Plain type
let arguments = (ins MyType1:$val);
// Type constraint
let arguments = (ins AnyTypeOf<[MyType1, MyType2]>:$val);
```
`AnyTypeOf` is an example for a type constraints. Many useful type constraints
can be found in `mlir/IR/CommonTypeConstraints.td`. Additional verification
code is generated for type/attribute constraints. Type constraints can not only
be used when defining operation arguments, but also when defining type
parameters.
Optionally, C++ functions can be generated, so that type constraints can be
checked from C++. The name of the C++ function must be specified in the
`cppFunctionName` field. If no function name is specified, no C++ function is
emitted.
```tablegen
// Example: Element type constraint for VectorType
def Builtin_VectorTypeElementType : AnyTypeOf<[AnyInteger, Index, AnyFloat]> {
let cppFunctionName = "isValidVectorTypeElementType";
}
```
The above example tranlates into the following C++ code:
```c++
bool isValidVectorTypeElementType(::mlir::Type type) {
return (((::llvm::isa<::mlir::IntegerType>(type))) || ((::llvm::isa<::mlir::IndexType>(type))) || ((::llvm::isa<::mlir::FloatType>(type))));
}
```
An extra TableGen rule is needed to emit C++ code for type constraints. This
will generate only the declarations/definitions of the type constaraints that
are defined in the specified `.td` file, but not those that are in included
`.td` files.
```cmake
mlir_tablegen(<Your Dialect>TypeConstraints.h.inc -gen-type-constraint-decls)
mlir_tablegen(<Your Dialect>TypeConstraints.cpp.inc -gen-type-constraint-defs)
```
The generated `<Your Dialect>TypeConstraints.h.inc` will need to be included
whereever you are referencing the type constraint in C++. Note that no C++
namespace will be emitted by the code generator. The `#include` statements of
the `.h.inc`/`.cpp.inc` files should be wrapped in C++ namespaces by the user.