Hi Jakob and David, The for-loop inside multiclass definition does not have to add extra abstraction layer. As in the pseudo codes that David wrote earlier (see below), it only condenses the repetitive 'def' statements inside the multiclass definition into a more compact and less copy-paste style form, instead of encapsulating them somewhere outside the multiclass definition. I believe this would be more readable and easier to maintain than the repetitive copy-n-paste 'def' statements as in the PTXInstInfo.td. I understand if you don't want an extra layer of abstraction (which adds extra looking-ups to someone reading td files), but I think we can have for-loop inside a multiclass without abstractions. -------------------- multiclass sse_binop<opcode> { for type = [f32, f64, v4f32, v2f64] regclass = [FP32, FP64, VR128, VR128] suffix = [ss, sd, ps, pd] { def !toupper(suffix)#rr : Instr< [(set (type regclass:$dst), (type (opcode (type regclass:$src1), (type regclass:$src2))))]>; def !toupper(suffix)#rm : Instr< [(set (type regclass:$dst), (type (opcode (type regclass:$src1), (type addr:$src2))))]>; } } -------------------- Regards, Che-Liang On Sat, Oct 8, 2011 at 7:24 AM, Jakob Stoklund Olesen <jolesen at apple.com> wrote:> > On Oct 7, 2011, at 2:23 PM, David A. Greene wrote: > >>> As repeated many times on this thread, the most common operation that >>> a .td file must support is looking up an instruction and figuring out >>> what its properties are and where they came from. >> >> Ok. What properties are most important to look up? I have found it >> really easy to just run "tblgen X86.td" and look at the output. That's >> really the canonical definition, right? > > In other words, .td files are write-only. This is not acceptable. > > It also doesn't answer '...and where they came from'. > >> This could be mitigated somewhat by doing something like this: >> >> class binary_pattern<string opcstr, string type> { >> string pattern = !strconcat(opcstr, "$r."#type#"\t$d, $a, $b"); >> } >> >> multiclass PTX_FLOAT_3OP<string opcstr> { >> def rr32 : InstPTX<(outs RegF32:$d), >> (ins RndMode:$r, RegF32:$a, RegF32:$b), >> binary_pattern<opcstrm "f32">.pattern, []>; >> def ri32 : InstPTX<(outs RegF32:$d), >> (ins RndMode:$r, RegF32:$a, f32imm:$b), >> binary_pattern<opcstrm "f32">.pattern, []>; >> def rr64 : InstPTX<(outs RegF64:$d), >> (ins RndMode:$r, RegF64:$a, RegF64:$b), >> binary_pattern<opcstrm "f64">.pattern, []>; >> def ri64 : InstPTX<(outs RegF64:$d), >> (ins RndMode:$r, RegF64:$a, f64imm:$b), >> binary_pattern<opcstrm "f64">.pattern, []>; >> } >> >> Would something like that be acceptable? > > You are adding complexity for no benefit. Now I have to look up the definition of InstPTX AND binary_pattern? This is not helping. > > Please focus your efforts on making .td files easy to use as an instruction reference. > > Compressing them with clever abstractions is contrary to that. > > /jakob > >
On Oct 8, 2011, at 6:19 AM, Che-Liang Chiou wrote:> I understand if you don't want an extra layer of abstraction (which > adds extra looking-ups to someone reading td files), but I think we > can have for-loop inside a multiclass without abstractions. > > -------------------- > multiclass sse_binop<opcode> { > for type = [f32, f64, v4f32, v2f64] > regclass = [FP32, FP64, VR128, VR128] > suffix = [ss, sd, ps, pd] { > > def !toupper(suffix)#rr : Instr< > [(set (type regclass:$dst), (type (opcode (type regclass:$src1), > (type regclass:$src2))))]>; > def !toupper(suffix)#rm : Instr< > [(set (type regclass:$dst), (type (opcode (type regclass:$src1), > (type addr:$src2))))]>; > } > } > --------------------You are right that it is better without referring to other definitions, but what you are suggesting is still much harder to read than just expanding the loop. Especially if you are searching for the properties of a specific def. Look, I understand the urge to eliminate redundancy. Every good programmer has it. But for target descriptions, it simply isn't the right thing to do. The TableGen multiclass construct can be used to clean up gratuitous redundancy in one dimension, like the ADD and SUB having the exact same variants. If it isn't overused, it even helps readability. We are missing a mechanism for eliminating gratuitous sequential redundancy, and a for loop for top-level defs would help with that. Please use PPCRegisterInfo.td as the primary use case for a for loop. /jakob
Che-Liang Chiou <clchiou at gmail.com> writes:> I understand if you don't want an extra layer of abstraction (which > adds extra looking-ups to someone reading td files), but I think we > can have for-loop inside a multiclass without abstractions.Yeah, I agree. Putting things directly in the multiclass is better than separating them out into different classes. But we would need for loop support to do it.> -------------------- > multiclass sse_binop<opcode> { > for type = [f32, f64, v4f32, v2f64] > regclass = [FP32, FP64, VR128, VR128] > suffix = [ss, sd, ps, pd] { > > def !toupper(suffix)#rr : Instr<Note that I don't necessarily like the above line. It does obscure the naming. I think we can come up with something better. I was presenting this as an example of what's possible, not as a prescription for how it should be done. -Dave
Jakob Stoklund Olesen <stoklund at 2pi.dk> writes:> On Oct 8, 2011, at 6:19 AM, Che-Liang Chiou wrote: > >> I understand if you don't want an extra layer of abstraction (which >> adds extra looking-ups to someone reading td files), but I think we >> can have for-loop inside a multiclass without abstractions. >> >> -------------------- >> multiclass sse_binop<opcode> { >> for type = [f32, f64, v4f32, v2f64] >> regclass = [FP32, FP64, VR128, VR128] >> suffix = [ss, sd, ps, pd] { >> >> def !toupper(suffix)#rr : Instr< >> [(set (type regclass:$dst), (type (opcode (type regclass:$src1), >> (type regclass:$src2))))]>; >> def !toupper(suffix)#rm : Instr< >> [(set (type regclass:$dst), (type (opcode (type regclass:$src1), >> (type addr:$src2))))]>; >> } >> } >> -------------------- > > You are right that it is better without referring to other > definitions, but what you are suggesting is still much harder to read > than just expanding the loop. Especially if you are searching for the > properties of a specific def.Can you give an example of the kind of search you want to do?> But for target descriptions, it simply isn't the right thing to do.Why? If we retain the ability to do the kind of searches you want, wouldn't that be a good thing? -Dave