[LLVMdev] TableGen and Greenspun
David A. Greene
greened at obbligato.org
Thu Oct 6 09:46:50 PDT 2011
greened at obbligato.org (David A. Greene) writes:
> The problem I solved via multidefs was this: how does one write a set of
> Pat<> patterns in a generic way?
>
> For example, I want to be able to do this:
>
> defm MOVH :
> vs1x_fps_binary_vv_node_rmonly<
> 0x16, "movh", undef, 0,
> // rr
> [(undef)],
> // rm
> [(set DSTREGCLASS:$dst,
> (DSTTYPE (movlhps SRCREGCLASS:$src1,
> (DSTTYPE (bitconvert
> (v2f64 (scalar_to_vector
> (loadf64 addr:$src2))))))))],
> // rr Pat
> [],
> // rm Pat
> [[(DSTTYPE (movlhps SRCREGCLASS:$src1, (load addr:$src2))),
> (MNEMONIC SRCREGCLASS:$src1, addr:$src2)],
> [(INTDSTTYPE (movlhps SRCREGCLASS:$src1, (load addr:$src2))),
> (MNEMONIC SRCREGCLASS:$src1, addr:$src2)]]>;
>
> I need to have the various types substituted and the mnemonic with
> appropriate suffixes substituted. I need to have this done for each
> Pat<> pattern in the list ("rm Pat" above). To do this TableGen needs
> to know something about the top-level defm (the "defm name," if you
> will) and something about the types and classes the defm gets
> instantiated with.
>
> Therefore, I need some way to process a list of patterns and do
> substitutions in the context of a specific defm and all of the classes
> it inherits from.
So here's why I think the for loop proposal can't be a preprocessing
phase. Down in the guts of this I fundamentally need to be able to do
this:
multiclass blah<list<int> Values> {
for v = Values {
def DEF#v : base_class<v>;
}
}
Will that work? Is the for loop evaluated after parameter binding?
I like the for loop idea. But it can't be "just" a preprocessing step.
Also, I know I introduced the #..# "pasting" operation but I've found it
to be too limiting. In this example:
(Equivalent TableGen code with a for-loop)
----------------------------------------
multiclass PTX_FLOAT_4OP<string opcstr, SDNode opnode1, SDNode opnode2> {
for nbit = [32, 32, 64, 64],
op_suffix = [r, i, r, i],
op_type = [RegF32, f32imm, RegF64, f64imm],
op_node_type = [RegF32, fpimm, RegF64, fpimm] in {
def rr#op_suffix#nbit
: InstPTX<(outs RegF#nbit:$d),
(ins RegF#nbit:$a, RegF#nbit:$b, #op_type:$c),
!strconcat(opcstr, ".f#nbit\t$d, $a, $b, $c"),
[(set RegF#nbit:$d,
(opnode2 (opnode1 RegF#nbit:$a, RegF#nbit:$b),
#op_node_type:$c))]>;
}
}
what if we instead did this:
(Equivalent TableGen code with a for-loop)
----------------------------------------
multiclass PTX_FLOAT_4OP<string opcstr, SDNode opnode1, SDNode opnode2> {
for nbit = [32, 32, 64, 64],
op_suffix = [r, i, r, i],
op_type = [RegF32, f32imm, RegF64, f64imm],
op_node_type = [RegF32, fpimm, RegF64, fpimm] in {
def !strconcat(!strconcat("rr", !cast<string>(op_suffix)), "nbit")
[...]
}
}
Yes, it's a bit more verbose but also more flexible in what you can do
with iterator values.
-Dave
More information about the llvm-dev
mailing list