Re: New .md construct: define_insn_and_rewrite

2019-05-31 Thread Richard Sandiford
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

2019-05-20 Thread Jeff Law
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

2019-05-18 Thread Hans-Peter Nilsson
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

2019-05-14 Thread Richard Sandiford
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

2019-05-14 Thread Eric Botcazou
> 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

2019-05-14 Thread Richard Sandiford
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