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
greened at obbligato.org (David A. Greene) writes:> Also, I know I introduced the #..# "pasting" operation but I've found it > to be too limiting. In this example:[snip!]> 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.Here's some more detail on this. I want to be able to use #..# pasted stuff in a variety of contexts. For example: multiclass blah<string intr> { for prefix = [<empty>, Vx, Vy] { for suffix = [ps, pd] { def #prefix#ADD#suffix# : ProcessSomePattern< [(set RegClass:$dst, (!cast<Intrinsic>(#prefix#intr#suffix) RegClass:$src1, RegClass:$src2))] } } } It's actually more complex than this but this gives the basic idea. The key thing I need to be able to do is construct an instrinsic name given some base string, a prefix and a suffix. Here's a critical question. What type do the for loop iterators have? string? If the iterators are strings, I know that this will work: !cast<Instrinsic>(!strconcat(!strconcat(prefix, intr), suffix)) Will this work as well? !cast<Intrinsic>(#prefix#intr#suffix) If so, I think I can get away with using #..#. If for loop iterators are typed as strings that would also allow me to do what I need via strconcat. Actually, having both iterators as strings and paste "operator" results as strings would be useful. -Dave
greened at obbligato.org (David A. Greene) writes:> 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 think I can actually make this work using the existing multidef feature code. The ideas are fundamentally the same. I do like the for syntax a lot better. Che-Liang, would you mind if I played around with changing the multidef parsing to recognize your for syntax? Your code will work in places that multidefs can't right now (as Jakob noted) and we want to retain that ability. I would be working on integrating for loops into TableGen proper, not as a preprocessor. -Dave
On Oct 6, 2011, at 10:01 AM, David A. Greene wrote:> I want to be able to use #..# pasted stuff in a variety of contexts. > For example: > > multiclass blah<string intr> { > for prefix = [<empty>, Vx, Vy] { > for suffix = [ps, pd] { > def #prefix#ADD#suffix# : ProcessSomePattern< > [(set RegClass:$dst, (!cast<Intrinsic>(#prefix#intr#suffix) > RegClass:$src1, RegClass:$src2))] > } > } > } > > It's actually more complex than this but this gives the basic idea. The > key thing I need to be able to do is construct an instrinsic name given > some base string, a prefix and a suffix.David, I think the syntax you are proposing here is much better than the multidef syntax. When I look at test/TableGen/MultiPat.td, I have a really hard time figuring out what is happening. Basically, I don't want our target descriptions to end up looking like that.> Here's a critical question. What type do the for loop iterators have? > string?That's probably good enough. /jakob
On Oct 6, 2011, at 10:25 AM, David A. Greene wrote:> greened at obbligato.org (David A. Greene) writes: > >> 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 think I can actually make this work using the existing multidef > feature code. The ideas are fundamentally the same. I do like the > for syntax a lot better. > > Che-Liang, would you mind if I played around with changing the multidef > parsing to recognize your for syntax? Your code will work in places > that multidefs can't right now (as Jakob noted) and we want to retain > that ability. I would be working on integrating for loops into TableGen > proper, not as a preprocessor.+1 for not adding a preprocessor. There seems to be two use cases for this: 1. Generating a sequence of similar top-level defs, for example registers named R0--R15. 2. Injecting patterns into multiclasses. It seems to me that the same mechanism could support both. /jakob