Re: New .md construct: define_insn_and_rewrite
Hans-Peter Nilsson writes: > On Tue, 14 May 2019, Richard Sandiford wrote: >> Several SVE patterns need define_insn_and_splits that generate the >> same insn_code, but with different operands. That's probably a >> niche requirement, but it's cropping up often enough on the ACLE >> branch that I think it would be good to have a syntactic sugar for it. >> >> This patch therefore adds a new construct called define_insn_and_rewrite. > >> It's basically a define_insn_and_split with an implicit split pattern, >> obtained by copying the insn pattern and replacing match_operands with >> match_dups and match_operators with match_op_dups. > > I think that sentence should be in the documentation, in one of > the introductory sentences. > >> Any comments? > >> Suggestions for better names? > > I'll pass on this, for now. ;-) > But, IMHO it lacks an allusion to define_insn_and_split. > >> Index: gcc/doc/md.texi > >> +@end smallexample > > Can you please add the equivalent define_insn_and_split > "expansion" to the example? It'd help understanding the concept > graphically at a glance. OK, here's what I installed. Richard 2019-05-31 Richard Sandiford gcc/ * doc/md.texi: Document define_insn_and_rewrite. * rtl.def (DEFINE_INSN_AND_REWRITE): New rtx code. * gensupport.c (queue_elem): Update comment. (replace_operands_with_dups): New function. (gen_rewrite_sequence): Likewise. (process_rtx): Handle DEFINE_INSN_AND_REWRITE. * read-rtl.c (apply_subst_iterator): Likewise. (add_condition_to_rtx, named_rtx_p): Likewise. (rtx_reader::read_rtx_operand): Likewise. * config/aarch64/aarch64-sve.md (while_ult_cc): Rename to... (*while_ult_cc): ...this and use define_insn_and_rewrite. (*cond__any): Turn into define_insn_and_rewrites. Remove separate define_split. Index: gcc/doc/md.texi === --- gcc/doc/md.texi 2019-05-31 17:26:54.367202007 +0100 +++ gcc/doc/md.texi 2019-05-31 17:27:03.711176173 +0100 @@ -8498,6 +8498,119 @@ functionality as two separate @code{defi patterns. It exists for compactness, and as a maintenance tool to prevent having to ensure the two patterns' templates match. +@findex define_insn_and_rewrite +It is sometimes useful to have a @code{define_insn_and_split} +that replaces specific operands of an instruction but leaves the +rest of the instruction pattern unchanged. You can do this directly +with a @code{define_insn_and_split}, but it requires a +@var{new-insn-pattern-1} that repeats most of the original @var{insn-pattern}. +There is also the complication that an implicit @code{parallel} in +@var{insn-pattern} must become an explicit @code{parallel} in +@var{new-insn-pattern-1}, which is easy to overlook. +A simpler alternative is to use @code{define_insn_and_rewrite}, which +is a form of @code{define_insn_and_split} that automatically generates +@var{new-insn-pattern-1} by replacing each @code{match_operand} +in @var{insn-pattern} with a corresponding @code{match_dup}, and each +@code{match_operator} in the pattern with a corresponding @code{match_op_dup}. +The arguments are otherwise identical to @code{define_insn_and_split}: + +@smallexample +(define_insn_and_rewrite + [@var{insn-pattern}] + "@var{condition}" + "@var{output-template}" + "@var{split-condition}" + "@var{preparation-statements}" + [@var{insn-attributes}]) +@end smallexample + +The @code{match_dup}s and @code{match_op_dup}s in the new +instruction pattern use any new operand values that the +@var{preparation-statements} store in the @code{operands} array, +as for a normal @code{define_insn_and_split}. @var{preparation-statements} +can also emit additional instructions before the new instruction. +They can even emit an entirely different sequence of instructions and +use @code{DONE} to avoid emitting a new form of the original +instruction. + +The split in a @code{define_insn_and_rewrite} is only intended +to apply to existing instructions that match @var{insn-pattern}. +@var{split-condition} must therefore start with @code{&&}, +so that the split condition applies on top of @var{condition}. + +Here is an example from the AArch64 SVE port, in which operand 1 is +known to be equivalent to an all-true constant and isn't used by the +output template: + +@smallexample +(define_insn_and_rewrite "*while_ult_cc" + [(set (reg:CC CC_REGNUM) +(compare:CC + (unspec:SI [(match_operand:PRED_ALL 1) + (unspec:PRED_ALL +[(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ") + (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")] +UNSPEC_WHILE_LO)] + UNSPEC_PTEST_PTRUE) + (const_int 0))) + (set (match_operand:PRED_ALL 0 "register_operand" "=Upa") +(unspec:PRED_ALL [(match_dup 2) + (match
Re: New .md construct: define_insn_and_rewrite
On 5/14/19 8:14 AM, Richard Sandiford wrote: > Several SVE patterns need define_insn_and_splits that generate the > same insn_code, but with different operands. That's probably a > niche requirement, but it's cropping up often enough on the ACLE > branch that I think it would be good to have a syntactic sugar for it. > > This patch therefore adds a new construct called define_insn_and_rewrite. > It's basically a define_insn_and_split with an implicit split pattern, > obtained by copying the insn pattern and replacing match_operands with > match_dups and match_operators with match_op_dups. > > Any comments? Suggestions for better names? No strong opinions here other than to mention that I think there's other places we could use this. Jeff
Re: New .md construct: define_insn_and_rewrite
On Tue, 14 May 2019, Richard Sandiford wrote: > Several SVE patterns need define_insn_and_splits that generate the > same insn_code, but with different operands. That's probably a > niche requirement, but it's cropping up often enough on the ACLE > branch that I think it would be good to have a syntactic sugar for it. > > This patch therefore adds a new construct called define_insn_and_rewrite. > It's basically a define_insn_and_split with an implicit split pattern, > obtained by copying the insn pattern and replacing match_operands with > match_dups and match_operators with match_op_dups. I think that sentence should be in the documentation, in one of the introductory sentences. > Any comments? > Suggestions for better names? I'll pass on this, for now. ;-) But, IMHO it lacks an allusion to define_insn_and_split. > Index: gcc/doc/md.texi > +@end smallexample Can you please add the equivalent define_insn_and_split "expansion" to the example? It'd help understanding the concept graphically at a glance. brgds, H-P
Re: New .md construct: define_insn_and_rewrite
Eric Botcazou writes: >> This patch therefore adds a new construct called define_insn_and_rewrite. >> It's basically a define_insn_and_split with an implicit split pattern, >> obtained by copying the insn pattern and replacing match_operands with >> match_dups and match_operators with match_op_dups. > > Isn't that what define_subst does in a different context? > >> Any comments? Suggestions for better names? > > define_insn_and_subst? define_subst is a static substitution though, creating multiple insn codes, whereas the substitution here is dynamic and can be controlled by C++ code. It might be confusing to link the two. Thanks, Richard
Re: New .md construct: define_insn_and_rewrite
> This patch therefore adds a new construct called define_insn_and_rewrite. > It's basically a define_insn_and_split with an implicit split pattern, > obtained by copying the insn pattern and replacing match_operands with > match_dups and match_operators with match_op_dups. Isn't that what define_subst does in a different context? > Any comments? Suggestions for better names? define_insn_and_subst? -- Eric Botcazou
New .md construct: define_insn_and_rewrite
Several SVE patterns need define_insn_and_splits that generate the same insn_code, but with different operands. That's probably a niche requirement, but it's cropping up often enough on the ACLE branch that I think it would be good to have a syntactic sugar for it. This patch therefore adds a new construct called define_insn_and_rewrite. It's basically a define_insn_and_split with an implicit split pattern, obtained by copying the insn pattern and replacing match_operands with match_dups and match_operators with match_op_dups. Any comments? Suggestions for better names? Richard 2019-05-14 Richard Sandiford gcc/ * doc/md.texi: Document define_insn_and_rewrite. * rtl.def (DEFINE_INSN_AND_REWRITE): New rtx code. * gensupport.c (queue_elem): Update comment. (replace_operands_with_dups): New function. (gen_rewrite_sequence): Likewise. (process_rtx): Handle DEFINE_INSN_AND_REWRITE. * read-rtl.c (apply_subst_iterator): Likewise. (add_condition_to_rtx, named_rtx_p): Likewise. (rtx_reader::read_rtx_operand): Likewise. * config/aarch64/aarch64-sve.md (while_ult_cc): Rename to... (*while_ult_cc): ...this and use define_insn_and_rewrite. (*cond__any): Turn into define_insn_and_rewrites. Remove separate define_split. Index: gcc/doc/md.texi === --- gcc/doc/md.texi 2019-05-12 12:27:15.753897237 +0100 +++ gcc/doc/md.texi 2019-05-14 15:06:14.496625455 +0100 @@ -8537,6 +8537,72 @@ functionality as two separate @code{defi patterns. It exists for compactness, and as a maintenance tool to prevent having to ensure the two patterns' templates match. +@findex define_insn_and_rewrite +It is sometimes useful to have a @code{define_insn_and_split} +in which the new instruction pattern replaces some of the operands but leaves +the rest of the original pattern unchanged. Doing this directly in a +@code{define_insn_and_split} would require a sequence of +@var{new-insn-pattern}s that repeats the fixed parts of the +@var{insn-pattern}. You can avoid this by using +@code{define_insn_and_rewrite}, which automatically generates +a new pattern based on the original one, but using any new +operand values provided by the @var{preparation-statements}. +The operands are otherwise identical: + +@smallexample +(define_insn_and_rewrite + [@var{insn-pattern}] + "@var{condition}" + "@var{output-template}" + "@var{split-condition}" + "@var{preparation-statements}" + [@var{insn-attributes}]) +@end smallexample + +The split in a @code{define_insn_and_rewrite} is only intended +to apply to existing instructions that match @var{insn-pattern}. +The @var{split-condition} must therefore start with @code{&&}, +so that the split condition applies on top of @var{condition}. + +Here is an example from the SVE port, in which operand 1 is known +to be equivalent to an all-true constant and isn't used by the +output template: + +@smallexample +(define_insn_and_rewrite "*while_ult_cc" + [(set (reg:CC CC_REGNUM) +(compare:CC + (unspec:SI [(match_operand:PRED_ALL 1) + (unspec:PRED_ALL +[(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ") + (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")] +UNSPEC_WHILE_LO)] + UNSPEC_PTEST_PTRUE) + (const_int 0))) + (set (match_operand:PRED_ALL 0 "register_operand" "=Upa") +(unspec:PRED_ALL [(match_dup 2) + (match_dup 3)] + UNSPEC_WHILE_LO))] + "TARGET_SVE" + "whilelo\t%0., %2, %3" + ;; Force the compiler to drop the unused predicate operand, so that we + ;; don't have an unnecessary PTRUE. + "&& !CONSTANT_P (operands[1])" + @{ +operands[1] = CONSTM1_RTX (mode); + @} +) +@end smallexample + +The splitter in this case simply replaces operand 1 with the constant +value that it is known to have. + +As with a @code{define_split} or @code{define_insn_and_split}, +the @var{preparation-statements} in a @code{define_insn_and_rewrite} +can emit additional instructions before the new instruction. They +can also emit an entirely different sequence of instructions and use +@code{DONE} to avoid emitting a new form of the original instruction. + @end ifset @ifset INTERNALS @node Including Patterns Index: gcc/rtl.def === --- gcc/rtl.def 2019-03-08 18:15:26.824777889 + +++ gcc/rtl.def 2019-05-14 15:06:14.500625443 +0100 @@ -936,6 +936,12 @@ DEF_RTL_EXPR(DEFINE_SPLIT, "define_split 7: optionally, a vector of attributes for this insn. */ DEF_RTL_EXPR(DEFINE_INSN_AND_SPLIT, "define_insn_and_split", "sEsTsESV", RTX_EXTRA) +/* A form of define_insn_and_split in which the split insn pattern (operand 5) + is determined automatically by replacing match_operands