Skip to content

Commit c1864aa

Browse files
committed
fixup! [TableGen] Add a field to filter out GenericTable entries
Add a test in `llvm/test/TableGen/generic-tables.td` and make detailed document
1 parent c7c59dc commit c1864aa

File tree

2 files changed

+129
-5
lines changed

2 files changed

+129
-5
lines changed

llvm/docs/TableGen/BackEnds.rst

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,8 @@ This class provides six fields.
691691

692692
* ``string FilterClassField``. This is an optional field of ``FilterClass``
693693
which should be `bit` type. If specified, only those records with this field
694-
being true will have corresponding entries in the table.
694+
being true will have corresponding entries in the table. This field won't be
695+
included in generated C++ fields if it isn't included in ``Fields`` list.
695696

696697
* ``string CppTypeName``. The name of the C++ struct/class type of the
697698
table that holds the entries. If unspecified, the ``FilterClass`` name is
@@ -906,6 +907,63 @@ causes the lookup function to change as follows:
906907
struct KeyType {
907908
...
908909
910+
We can construct two GenericTables with the same ``FilterClass``, so that they
911+
select from the same overall set of records, but assign them with different
912+
``FilterClassField`` values so that they include different subsets of the
913+
records of that class.
914+
915+
For example, we can create two tables that contain only even or odd records.
916+
Fields ``IsEven`` and ``IsOdd`` won't be included in generated C++ fields
917+
because they aren't included in ``Fields`` list.
918+
919+
.. code-block:: text
920+
921+
class EEntry<bits<8> value> {
922+
bits<8> Value = value;
923+
bit IsEven = !eq(!and(value, 1), 0);
924+
bit IsOdd = !not(IsEven);
925+
}
926+
927+
foreach i = {1-10} in {
928+
def : EEntry<i>;
929+
}
930+
931+
def EEntryEvenTable : GenericTable {
932+
let FilterClass = "EEntry";
933+
let FilterClassField = "IsEven";
934+
let Fields = ["Value"];
935+
let PrimaryKey = ["Value"];
936+
let PrimaryKeyName = "lookupEEntryEvenTableByValue";
937+
}
938+
939+
def EEntryOddTable : GenericTable {
940+
let FilterClass = "EEntry";
941+
let FilterClassField = "IsOdd";
942+
let Fields = ["Value"];
943+
let PrimaryKey = ["Value"];
944+
let PrimaryKeyName = "lookupEEntryOddTableByValue";
945+
}
946+
947+
The generated tables are:
948+
949+
.. code-block:: text
950+
951+
constexpr EEntry EEntryEvenTable[] = {
952+
{ 0x2 }, // 0
953+
{ 0x4 }, // 1
954+
{ 0x6 }, // 2
955+
{ 0x8 }, // 3
956+
{ 0xA }, // 4
957+
};
958+
959+
constexpr EEntry EEntryOddTable[] = {
960+
{ 0x1 }, // 0
961+
{ 0x3 }, // 1
962+
{ 0x5 }, // 2
963+
{ 0x7 }, // 3
964+
{ 0x9 }, // 4
965+
};
966+
909967
Search Indexes
910968
~~~~~~~~~~~~~~
911969

llvm/test/TableGen/generic-tables.td

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ include "llvm/TableGen/SearchableTable.td"
2424

2525
// CHECK-LABEL: GET_ATable_IMPL
2626
// CHECK: constexpr AEntry ATable[] = {
27-
// CHECK: { "baz"
28-
// CHECK: { "foo"
29-
// CHECK: { "foobar"
30-
// CHECK: { "bar"
27+
// CHECK-NOT: { "aaa"
28+
// CHECK: { "baz"
29+
// CHECK: { "foo"
30+
// CHECK: { "foobar"
31+
// CHECK: { "bar"
3132
// CHECK: };
3233

3334
// CHECK: const AEntry *lookupATableByValues(uint8_t Val1, uint16_t Val2) {
@@ -38,15 +39,18 @@ class AEntry<string str, int val1, int val2> {
3839
string Str = str;
3940
bits<8> Val1 = val1;
4041
bits<10> Val2 = val2;
42+
bit IsNeeded = 1;
4143
}
4244

45+
def : AEntry<"aaa", 0, 0> { let IsNeeded = 0; }
4346
def : AEntry<"bar", 5, 3>;
4447
def : AEntry<"baz", 2, 6>;
4548
def : AEntry<"foo", 4, 4>;
4649
def : AEntry<"foobar", 4, 5>;
4750

4851
def ATable : GenericTable {
4952
let FilterClass = "AEntry";
53+
let FilterClassField = "IsNeeded";
5054
let Fields = ["Str", "Val1", "Val2"];
5155

5256
let PrimaryKey = ["Val1", "Val2"];
@@ -171,3 +175,65 @@ def DTable : GenericTable {
171175
}
172176

173177
#endif // ERROR1
178+
179+
// CHECK-LABEL: GET_EEntryEvenTable_DECL
180+
// CHECK: const EEntry *lookupEEntryEvenTableByValue(uint8_t Value);
181+
182+
// CHECK-LABEL: GET_EEntryEvenTable_IMPL
183+
// CHECK: constexpr EEntry EEntryEvenTable[] = {
184+
// CHECK: { 0x2
185+
// CHECK: { 0x4
186+
// CHECK: { 0x6
187+
// CHECK: { 0x8
188+
// CHECK: { 0xA
189+
// CHECK: };
190+
191+
// CHECK: const EEntry *lookupEEntryEvenTableByValue(uint8_t Value) {
192+
// CHECK: return &*Idx;
193+
// CHECK: }
194+
195+
// CHECK-LABEL: GET_EEntryOddTable_DECL
196+
// CHECK: const EEntry *lookupEEntryOddTableByValue(uint8_t Value);
197+
198+
// CHECK-LABEL: GET_EEntryOddTable_IMPL
199+
// CHECK: constexpr EEntry EEntryOddTable[] = {
200+
// CHECK: { 0x1
201+
// CHECK: { 0x3
202+
// CHECK: { 0x5
203+
// CHECK: { 0x7
204+
// CHECK: { 0x9
205+
// CHECK: };
206+
207+
// CHECK: const EEntry *lookupEEntryOddTableByValue(uint8_t Value) {
208+
// CHECK: return &*Idx;
209+
// CHECK: }
210+
211+
// We can construct two GenericTables with the same FilterClass, so that they
212+
// select from the same overall set of records, but assign them with different
213+
// FilterClassField values so that they include different subsets of the records
214+
// of that class.
215+
class EEntry<bits<8> value> {
216+
bits<8> Value = value;
217+
bit IsEven = !eq(!and(value, 1), 0);
218+
bit IsOdd = !not(IsEven);
219+
}
220+
221+
foreach i = {1-10} in {
222+
def : EEntry<i>;
223+
}
224+
225+
def EEntryEvenTable : GenericTable {
226+
let FilterClass = "EEntry";
227+
let FilterClassField = "IsEven";
228+
let Fields = ["Value"];
229+
let PrimaryKey = ["Value"];
230+
let PrimaryKeyName = "lookupEEntryEvenTableByValue";
231+
}
232+
233+
def EEntryOddTable : GenericTable {
234+
let FilterClass = "EEntry";
235+
let FilterClassField = "IsOdd";
236+
let Fields = ["Value"];
237+
let PrimaryKey = ["Value"];
238+
let PrimaryKeyName = "lookupEEntryOddTableByValue";
239+
}

0 commit comments

Comments
 (0)