gen_exp has code to detect when the same operand is used multiple
times. It ensures that second and subsequent uses call copy_rtx,
to enforce correct unsharing.
However, for historical reasons that aren't clear to me, this was
skipped for a define_insn unless the define_insn was a parallel.
It was also skipped for a single define_expand instruction,
regardless of its contents.
This meant that a single parallel instruction was treated differently
between define_insn (where sharing rules were followed) and
define_expand (where sharing rules weren't followed). define_splits
and define_peephole2s followed the sharing rules in all cases.
This patch makes everything follow the sharing rules. The code
it touches will be removed by the proposed bytecode-based expansion,
which will use its own tracking when enforcing sharing rules.
However, it seemed better for staging and bisection purposes
to make this change first.
gcc/
* genemit.cc (generator::used): Update comment.
(generator::gen_exp): Remove handling of null unused arrays.
(gen_insn, gen_expand): Always pass a used array.
(output_add_clobbers): Note why the used array is null here.
---
gcc/genemit.cc | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/gcc/genemit.cc b/gcc/genemit.cc
index df2b319fd23..a7e49a24506 100644
--- a/gcc/genemit.cc
+++ b/gcc/genemit.cc
@@ -78,9 +78,9 @@ struct generator
/* The type of subroutine that we're expanding. */
rtx_code subroutine_type;
- /* If nonnull, index N indicates that the original operand N has already
- been used to replace a MATCH_OPERATOR or MATCH_DUP, and so any further
- replacements must make a copy. */
+ /* Index N indicates that the original operand N has already been used to
+ replace a MATCH_OPERATOR or MATCH_DUP, and so any further replacements
+ must make a copy. */
char *used;
/* The construct that we're expanding. */
@@ -135,15 +135,12 @@ generator::gen_exp (rtx x)
{
case MATCH_OPERAND:
case MATCH_DUP:
- if (used)
+ if (used[XINT (x, 0)])
{
- if (used[XINT (x, 0)])
- {
- fprintf (file, "copy_rtx (operands[%d])", XINT (x, 0));
- return;
- }
- used[XINT (x, 0)] = 1;
+ fprintf (file, "copy_rtx (operands[%d])", XINT (x, 0));
+ return;
}
+ used[XINT (x, 0)] = 1;
fprintf (file, "operands[%d]", XINT (x, 0));
return;
@@ -505,10 +502,7 @@ gen_insn (const md_rtx_info &info, FILE *file)
/* Output code to construct and return the rtl for the instruction body. */
rtx pattern = add_implicit_parallel (XVEC (insn, 1));
- /* ??? This is the traditional behavior, but seems suspect. */
- char *used = (XVECLEN (insn, 1) == 1
- ? NULL
- : XCNEWVEC (char, stats.num_generator_args));
+ char *used = XCNEWVEC (char, stats.num_generator_args);
fprintf (file, " return ");
generator (DEFINE_INSN, used, info, file).gen_exp (pattern);
fprintf (file, ";\n}\n\n");
@@ -555,10 +549,12 @@ gen_expand (const md_rtx_info &info, FILE *file)
&& stats.max_opno >= stats.max_dup_opno
&& XVECLEN (expand, 1) == 1)
{
+ used = XCNEWVEC (char, stats.num_operand_vars);
fprintf (file, " return ");
- generator (DEFINE_EXPAND, NULL, info, file)
+ generator (DEFINE_EXPAND, used, info, file)
.gen_exp (XVECEXP (expand, 1, 0));
fprintf (file, ";\n}\n\n");
+ XDELETEVEC (used);
return;
}
@@ -717,6 +713,7 @@ output_add_clobbers (const md_rtx_info &info, FILE *file)
{
fprintf (file, " XVECEXP (pattern, 0, %d) = ", i);
rtx clobbered_value = RTVEC_ELT (clobber->pattern, i);
+ /* Pass null for USED since there are no operands. */
generator (clobber->code, NULL, info, file)
.gen_exp (clobbered_value);
fprintf (file, ";\n");
--
2.43.0