@@ -1498,22 +1498,17 @@ optionality, default values, etc.:
1498
1498
* ` AllAttrOf ` : adapts an attribute with
1499
1499
[ multiple constraints] ( #combining-constraints ) .
1500
1500
1501
- ### Enum attributes
1501
+ ## Enum definition
1502
1502
1503
- Some attributes can only take values from a predefined enum, e.g., the
1504
- comparison kind of a comparison op. To define such attributes, ODS provides
1505
- several mechanisms: ` IntEnumAttr ` , and ` BitEnumAttr ` .
1503
+ MLIR is capabable of generating C++ enums, both those that represent a set
1504
+ of values drawn from a list or that can hold a combination of flags
1505
+ using the ` IntEnum ` and ` BitEnum ` classes, respectively .
1506
1506
1507
- * ` IntEnumAttr ` : each enum case is an integer, the attribute is stored as a
1508
- [ ` IntegerAttr ` ] [ IntegerAttr ] in the op.
1509
- * ` BitEnumAttr ` : each enum case is a either the empty case, a single bit,
1510
- or a group of single bits, and the attribute is stored as a
1511
- [ ` IntegerAttr ` ] [ IntegerAttr ] in the op.
1512
-
1513
- All these ` *EnumAttr ` attributes require fully specifying all of the allowed
1514
- cases via their corresponding ` *EnumAttrCase ` . With this, ODS is able to
1507
+ All these ` IntEnum ` and ` BitEnum ` classes require fully specifying all of the allowed
1508
+ cases via a ` EnumCase ` or ` BitEnumCase ` subclass, respectively. With this, ODS is able to
1515
1509
generate additional verification to only accept allowed cases. To facilitate the
1516
- interaction between ` *EnumAttr ` s and their C++ consumers, the
1510
+ interaction between tablegen enums and the attributes or properties that wrap them and
1511
+ to make them easier to use in C++, the
1517
1512
[ ` EnumsGen ` ] [ EnumsGen ] TableGen backend can generate a few common utilities: a
1518
1513
C++ enum class, ` llvm::DenseMapInfo ` for the enum class, conversion functions
1519
1514
from/to strings. This is controlled via the ` -gen-enum-decls ` and
@@ -1522,10 +1517,10 @@ from/to strings. This is controlled via the `-gen-enum-decls` and
1522
1517
For example, given the following ` EnumAttr ` :
1523
1518
1524
1519
``` tablegen
1525
- def Case15: I32EnumAttrCase <"Case15", 15>;
1526
- def Case20: I32EnumAttrCase <"Case20", 20>;
1520
+ def Case15: I32EnumCase <"Case15", 15>;
1521
+ def Case20: I32EnumCase <"Case20", 20>;
1527
1522
1528
- def MyIntEnum: I32EnumAttr <"MyIntEnum", "An example int enum",
1523
+ def MyIntEnum: I32Enum <"MyIntEnum", "An example int enum",
1529
1524
[Case15, Case20]> {
1530
1525
let cppNamespace = "Outer::Inner";
1531
1526
let stringToSymbolFnName = "ConvertToEnum";
@@ -1611,14 +1606,17 @@ std::optional<MyIntEnum> symbolizeMyIntEnum(uint32_t value) {
1611
1606
Similarly for the following ` BitEnumAttr ` definition:
1612
1607
1613
1608
``` tablegen
1614
- def None: I32BitEnumAttrCaseNone<"None">;
1615
- def Bit0: I32BitEnumAttrCaseBit<"Bit0", 0, "tagged">;
1616
- def Bit1: I32BitEnumAttrCaseBit<"Bit1", 1>;
1617
- def Bit2: I32BitEnumAttrCaseBit<"Bit2", 2>;
1618
- def Bit3: I32BitEnumAttrCaseBit<"Bit3", 3>;
1619
-
1620
- def MyBitEnum: BitEnumAttr<"MyBitEnum", "An example bit enum",
1621
- [None, Bit0, Bit1, Bit2, Bit3]>;
1609
+ def None: I32BitEnumCaseNone<"None">;
1610
+ def Bit0: I32BitEnumCaseBit<"Bit0", 0, "tagged">;
1611
+ def Bit1: I32BitEnumCaseBit<"Bit1", 1>;
1612
+ def Bit2: I32BitEnumCaseBit<"Bit2", 2>;
1613
+ def Bit3: I32BitEnumCaseBit<"Bit3", 3>;
1614
+
1615
+ def MyBitEnum: I32BitEnum<"MyBitEnum", "An example bit enum",
1616
+ [None, Bit0, Bit1, Bit2, Bit3]> {
1617
+ // Note: this is the default value, and is listed for illustrative purposes.
1618
+ let separator = "|";
1619
+ }
1622
1620
```
1623
1621
1624
1622
We can have:
@@ -1738,6 +1736,26 @@ std::optional<MyBitEnum> symbolizeMyBitEnum(uint32_t value) {
1738
1736
}
1739
1737
```
1740
1738
1739
+ ### Wrapping enums in attributes
1740
+
1741
+ There are several mechanisms for creating an ` Attribute ` whose values are
1742
+ taken from a ` *Enum ` .
1743
+
1744
+ The most common of these is to use the ` EnumAttr ` class, which takes
1745
+ an ` EnumInfo ` (either a ` IntEnum ` or ` BitEnum ` ) as a parameter and constructs
1746
+ an attribute that holds one argument - value of the enum. This attribute
1747
+ is defined within a dialect and can have its assembly format customized to,
1748
+ for example, print angle brackets around the enum value or assign a mnemonic.
1749
+
1750
+ An older form involves using the ` *IntEnumAttr ` and ` *BitEnumATtr ` classes
1751
+ and their corresponding ` *EnumAttrCase ` classes (which can be used
1752
+ anywhere a ` *EnumCase ` is needed). These classes store their values
1753
+ as a ` SignlessIntegerAttr ` of their bitwidth, imposing the constraint on it
1754
+ that it has a value within the valid range of the enum. If their
1755
+ ` genSpecializedAttr ` parameter is set, they will also generate a
1756
+ wrapper attribute instead of using a bare signless integer attribute
1757
+ for storage.
1758
+
1741
1759
## Debugging Tips
1742
1760
1743
1761
### Run ` mlir-tblgen ` to see the generated content
0 commit comments