Skip to content

Commit 046af58

Browse files
Address comments
1 parent 0f01954 commit 046af58

File tree

3 files changed

+69
-59
lines changed

3 files changed

+69
-59
lines changed

mlir/docs/DefiningDialects/AttributesAndTypes.md

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,52 +1204,3 @@ void MyDialect::initialize() {
12041204
>();
12051205
}
12061206
```
1207-
1208-
### Attribute / Type Constraints
1209-
1210-
When defining the arguments of an operation in TableGen, users can specify
1211-
either plain attributes/types or use attribute/type constraints to levy
1212-
additional requirements on the attribute value or operand type.
1213-
1214-
```tablegen
1215-
def My_Type1 : MyDialect_Type<"Type1", "type1"> { ... }
1216-
def My_Type2 : MyDialect_Type<"Type2", "type2"> { ... }
1217-
1218-
// Plain type
1219-
let arguments = (ins MyType1:$val);
1220-
// Type constraint
1221-
let arguments = (ins AnyTypeOf<[MyType1, MyType2]>:$val);
1222-
```
1223-
1224-
`AnyTypeOf` is an example for a type constraints. Many useful type constraints
1225-
can be found in `mlir/IR/CommonTypeConstraints.td`. Additional verification
1226-
code is generated for type/attribute constraints. Type constraints can not only
1227-
be used when defining operation arguments, but also when defining type
1228-
parameters.
1229-
1230-
Optionally, C++ functions can be generated, so that type constraints can be
1231-
checked from C++. The name of the C++ function must be specified in the
1232-
`cppFunctionName` field. If no function name is specified, no C++ function is
1233-
emitted.
1234-
1235-
```tablegen
1236-
// Example: Element type constraint for VectorType
1237-
def Builtin_VectorTypeElementType : AnyTypeOf<[AnyInteger, Index, AnyFloat]> {
1238-
let cppFunctionName = "isValidVectorTypeElementType";
1239-
}
1240-
```
1241-
1242-
An extra TableGen rule is needed to emit C++ code for type constraints. This
1243-
will generate only the declarations/definitions of the type constaraints that
1244-
are defined in the specified `.td` file, but not those that are in included
1245-
`.td` files.
1246-
1247-
```cmake
1248-
mlir_tablegen(<Your Dialect>TypeConstraints.h.inc -gen-type-constraint-decls)
1249-
mlir_tablegen(<Your Dialect>TypeConstraints.cpp.inc -gen-type-constraint-defs)
1250-
```
1251-
1252-
The generated `<Your Dialect>TypeConstraints.h.inc` will need to be included
1253-
whereever you are referencing the type constraint in C++. Note that no C++
1254-
namespace will be emitted by the code generator. The `#include` statements of
1255-
the `.h.inc`/`.cpp.inc` files should be wrapped in C++ namespaces by the user.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Constraints
2+
3+
[TOC]
4+
5+
## Attribute / Type Constraints
6+
7+
When defining the arguments of an operation in TableGen, users can specify
8+
either plain attributes/types or use attribute/type constraints to levy
9+
additional requirements on the attribute value or operand type.
10+
11+
```tablegen
12+
def My_Type1 : MyDialect_Type<"Type1", "type1"> { ... }
13+
def My_Type2 : MyDialect_Type<"Type2", "type2"> { ... }
14+
15+
// Plain type
16+
let arguments = (ins MyType1:$val);
17+
// Type constraint
18+
let arguments = (ins AnyTypeOf<[MyType1, MyType2]>:$val);
19+
```
20+
21+
`AnyTypeOf` is an example for a type constraints. Many useful type constraints
22+
can be found in `mlir/IR/CommonTypeConstraints.td`. Additional verification
23+
code is generated for type/attribute constraints. Type constraints can not only
24+
be used when defining operation arguments, but also when defining type
25+
parameters.
26+
27+
Optionally, C++ functions can be generated, so that type constraints can be
28+
checked from C++. The name of the C++ function must be specified in the
29+
`cppFunctionName` field. If no function name is specified, no C++ function is
30+
emitted.
31+
32+
```tablegen
33+
// Example: Element type constraint for VectorType
34+
def Builtin_VectorTypeElementType : AnyTypeOf<[AnyInteger, Index, AnyFloat]> {
35+
let cppFunctionName = "isValidVectorTypeElementType";
36+
}
37+
```
38+
39+
The above example tranlates into the following C++ code:
40+
```c++
41+
bool isValidVectorTypeElementType(::mlir::Type type) {
42+
return (((::llvm::isa<::mlir::IntegerType>(type))) || ((::llvm::isa<::mlir::IndexType>(type))) || ((::llvm::isa<::mlir::FloatType>(type))));
43+
}
44+
```
45+
46+
An extra TableGen rule is needed to emit C++ code for type constraints. This
47+
will generate only the declarations/definitions of the type constaraints that
48+
are defined in the specified `.td` file, but not those that are in included
49+
`.td` files.
50+
51+
```cmake
52+
mlir_tablegen(<Your Dialect>TypeConstraints.h.inc -gen-type-constraint-decls)
53+
mlir_tablegen(<Your Dialect>TypeConstraints.cpp.inc -gen-type-constraint-defs)
54+
```
55+
56+
The generated `<Your Dialect>TypeConstraints.h.inc` will need to be included
57+
whereever you are referencing the type constraint in C++. Note that no C++
58+
namespace will be emitted by the code generator. The `#include` statements of
59+
the `.h.inc`/`.cpp.inc` files should be wrapped in C++ namespaces by the user.

mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,16 +1027,6 @@ bool DefGenerator::emitDefs(StringRef selectedDialect) {
10271027
// Type Constraints
10281028
//===----------------------------------------------------------------------===//
10291029

1030-
static const char *const typeConstraintDecl = R"(
1031-
bool {0}(::mlir::Type type);
1032-
)";
1033-
1034-
static const char *const typeConstraintDef = R"(
1035-
bool {0}(::mlir::Type type) {
1036-
return ({1});
1037-
}
1038-
)";
1039-
10401030
/// Find all type constraints for which a C++ function should be generated.
10411031
static std::vector<Constraint>
10421032
getAllTypeConstraints(const llvm::RecordKeeper &records) {
@@ -1058,12 +1048,22 @@ getAllTypeConstraints(const llvm::RecordKeeper &records) {
10581048

10591049
static void emitTypeConstraintDecls(const llvm::RecordKeeper &records,
10601050
raw_ostream &os) {
1051+
static const char *const typeConstraintDecl = R"(
1052+
bool {0}(::mlir::Type type);
1053+
)";
1054+
10611055
for (Constraint constr : getAllTypeConstraints(records))
10621056
os << strfmt(typeConstraintDecl, *constr.getCppFunctionName());
10631057
}
10641058

10651059
static void emitTypeConstraintDefs(const llvm::RecordKeeper &records,
10661060
raw_ostream &os) {
1061+
static const char *const typeConstraintDef = R"(
1062+
bool {0}(::mlir::Type type) {
1063+
return ({1});
1064+
}
1065+
)";
1066+
10671067
for (Constraint constr : getAllTypeConstraints(records)) {
10681068
FmtContext ctx;
10691069
ctx.withSelf("type");

0 commit comments

Comments
 (0)