[llvm-dev] Extending TableGen's 'foreach' to work with 'multiclass' and 'defm'
Martin J. O'Riordan via llvm-dev
llvm-dev at lists.llvm.org
Mon Aug 21 05:23:33 PDT 2017
I have been reading the “RFC/bikeshedding: Separation of instruction and pattern definitions in LLVM backends” topic with considerable interest. This is an approach I have been considering for taming our own large instruction set, and it looks like it structures our descriptions better than the conventional approach we have used so far.
However, I have another form of TableGen taming that I would like to do.
In addition to the separation of instruction from the patterns that use it, I have also got a large number of “instruction groups” that differ in their schedules and operands, but are in all other respects structurally similar.
For example, I have a large number of load instructions that are almost identical but which are in 5 specific groups:
* Loads where the memory operand is in a register [LDA]
* Loads where the memory operand is in a register and is auto-incremented by an implicit value [LDB]
* Loads where the memory operand is in a register and is auto-incremented by a value in another register [LDC]
* Loads where the memory operand has a base pointer in a register and an immediate offset [LDD]
* Loads where the memory operand has a base pointer in a register and an offset in a register [LDE]
If I don’t have the multiple processor versions, I can use ‘class/def’ by specifying the appropriate ‘class’ for each type of instruction in the group, and then use a common set of ‘def’ declarations for them with ‘foreach’, for example:
// Describe the meta-classes for the LDA group
class T_LDA_Type1 : ...
class T_LDA_Type2 : ...
// Describe the meta-classes for the LDB group
class T_LDB_Type1 : ...
class T_LDB_Type2 : ...
// Describe the meta-classes for the LDC group
class T_LDC_Type1 : ...
class T_LDC_Type2 : ...
// Describe the meta-classes for the LDD group
class T_LDD_Type1 : ...
class T_LDD_Type2 : ...
// Describe the meta-classes for the LDE group
class T_LDE_Type1 : ...
class T_LDE_Type2 : ...
// Share a single set of definitions, but parameterised by meta-class
foreach loadOp = ["LDA", "LDB", "LDC", "LDD", "LDE" ] in {
def Prefix_#loadOp#_suffix1 : T_#loadOp#_Type1<...>;
def Prefix_#loadOp#_suffix2 : T_#loadOp#_Type2<...>;
}
All of the ‘def’s pass the same values to the ‘class’s, though the ‘class’s may ignore some as appropriate. For example, I pass the auto-increment size to each, though only the auto-increment patterns care.
This neatly allows me to symmetrically manage all the instructions in each of the groups using a single statement of the patterns, and maintain only one fifth of the number of definitions. In my actual source, there are around 50 different types of instruction within each group, so reducing the repetition is quite significant.
But there is a downside.
For each of the above I also have variations that are a result of different processor and ISA versions, and because of this I have to use ‘multiclass/defm’ to define the descriptions along with ‘Require’ predicates. The same approach does not work with ‘multiclass/defm’ though, because TableGen does not support ‘foreach’ with ‘multiclass/defm’.
I have experimented with adapting TableGen to do this, but I am just not knowledgeable enough about how TableGen works and my attempts have not been successful. Perhaps some of the people debating the separation of instruction and patterns topic might have some insight into how TableGen might be adapted to support ‘foreach’ with ‘multiclass/defm’ definitions and could advise me how I should do this; or maybe the maintainers of TableGen might consider this something that they would be willing to add to TableGen in the future?
Thanks,
MartinO
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170821/88a774ce/attachment.html>
More information about the llvm-dev
mailing list