One slightly awkward part about emitting the generator function bodies is that:
* define_insn and define_expand routines have a separate argument for each operand, named "operand0" upwards. * define_split and define_peephole2 routines take a pointer to an array, named "operands". * the C++ preparation code for expands, splits and peephole2s uses an array called "operands" to refer to the operands. * the automatically-generated code uses individual "operand<N>" variables to refer to the operands. So define_expands have to store the incoming arguments into an operands array before the md file's C++ code, then copy the operands array back to the individual variables before the automatically-generated code. splits and peephole2s have to copy the incoming operands array to individual variables after the md file's C++ code, creating more local variables that are live across calls to rtx_alloc. This patch tries to simplify things by making the whole function body use the operands array in preference to individual variables. define_insns and define_expands store their arguments to the array on entry. This would have pros and cons on its own, but having a single array helps with future efforts to reduce the duplication between gen_* functions. Doing this tripped a warning in stormy16.md about writing beyond the end of the array. The negsi2 C++ code writes to operands[2] even though the pattern has no operand 2. gcc/ * genemit.cc (gen_rtx_scratch, gen_exp): Use operands[%d] rather than operand%d. (start_gen_insn): Store the incoming arguments to an operands array. (gen_expand, gen_split): Remove copies into and out of the operands array. * config/stormy16/stormy16.md (negsi): Remove redundant assignment. --- gcc/genemit.cc | 61 ++++++++++++++++---------------------------------- 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/gcc/genemit.cc b/gcc/genemit.cc index 90f36e293b4..cdc098f19b8 100644 --- a/gcc/genemit.cc +++ b/gcc/genemit.cc @@ -71,7 +71,7 @@ gen_rtx_scratch (rtx x, enum rtx_code subroutine_type, FILE *file) { if (subroutine_type == DEFINE_PEEPHOLE2) { - fprintf (file, "operand%d", XINT (x, 0)); + fprintf (file, "operands[%d]", XINT (x, 0)); } else { @@ -108,21 +108,21 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, { if (used[XINT (x, 0)]) { - fprintf (file, "copy_rtx (operand%d)", XINT (x, 0)); + fprintf (file, "copy_rtx (operands[%d])", XINT (x, 0)); return; } used[XINT (x, 0)] = 1; } - fprintf (file, "operand%d", XINT (x, 0)); + fprintf (file, "operands[%d]", XINT (x, 0)); return; case MATCH_OP_DUP: fprintf (file, "gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 1); i++) fprintf (file, "e"); - fprintf (file, " (GET_CODE (operand%d), ", XINT (x, 0)); + fprintf (file, " (GET_CODE (operands[%d]), ", XINT (x, 0)); if (GET_MODE (x) == VOIDmode) - fprintf (file, "GET_MODE (operand%d)", XINT (x, 0)); + fprintf (file, "GET_MODE (operands[%d])", XINT (x, 0)); else fprintf (file, "%smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 1); i++) @@ -137,7 +137,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, fprintf (file, "gen_rtx_fmt_"); for (i = 0; i < XVECLEN (x, 2); i++) fprintf (file, "e"); - fprintf (file, " (GET_CODE (operand%d)", XINT (x, 0)); + fprintf (file, " (GET_CODE (operands[%d])", XINT (x, 0)); fprintf (file, ", %smode", GET_MODE_NAME (GET_MODE (x))); for (i = 0; i < XVECLEN (x, 2); i++) { @@ -149,7 +149,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used, case MATCH_PARALLEL: case MATCH_PAR_DUP: - fprintf (file, "operand%d", XINT (x, 0)); + fprintf (file, "operands[%d]", XINT (x, 0)); return; case MATCH_SCRATCH: @@ -437,14 +437,22 @@ start_gen_insn (FILE *file, const char *name, const pattern_stats &stats) fprintf (file, "rtx\ngen_%s (", name); if (stats.num_generator_args) for (int i = 0; i < stats.num_generator_args; i++) - if (i) - fprintf (file, ",\n\trtx operand%d ATTRIBUTE_UNUSED", i); - else - fprintf (file, "rtx operand%d ATTRIBUTE_UNUSED", i); + fprintf (file, "%srtx operand%d", i == 0 ? "" : ", ", i); else fprintf (file, "void"); fprintf (file, ")\n"); fprintf (file, "{\n"); + if (stats.num_generator_args) + { + fprintf (file, " rtx operands[%d] ATTRIBUTE_UNUSED = {", + stats.num_operand_vars); + for (int i = 0; i < stats.num_generator_args; i++) + fprintf (file, "%s operand%d", i == 0 ? "" : ",", i); + fprintf (file, " };\n"); + } + else if (stats.num_operand_vars != 0) + fprintf (file, " rtx operands[%d] ATTRIBUTE_UNUSED;\n", + stats.num_operand_vars); } /* Generate the `gen_...' function for a DEFINE_INSN. */ @@ -496,7 +504,6 @@ static void gen_expand (const md_rtx_info &info, FILE *file) { struct pattern_stats stats; - int i; char *used; /* Find out how many operands this function has. */ @@ -523,10 +530,6 @@ gen_expand (const md_rtx_info &info, FILE *file) return; } - /* For each operand referred to only with MATCH_DUPs, - make a local variable. */ - for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++) - fprintf (file, " rtx operand%d;\n", i); fprintf (file, " rtx_insn *_val = 0;\n"); fprintf (file, " start_sequence ();\n"); @@ -539,12 +542,6 @@ gen_expand (const md_rtx_info &info, FILE *file) if (XSTR (expand, 3) && *XSTR (expand, 3)) { fprintf (file, " {\n"); - if (stats.num_operand_vars > 0) - fprintf (file, " rtx operands[%d];\n", stats.num_operand_vars); - - /* Output code to copy the arguments into `operands'. */ - for (i = 0; i < stats.num_generator_args; i++) - fprintf (file, " operands[%d] = operand%d;\n", i, i); /* Output the special code to be executed before the sequence is generated. */ @@ -558,16 +555,6 @@ gen_expand (const md_rtx_info &info, FILE *file) } emit_c_code (XSTR (expand, 3), can_fail_p, XSTR (expand, 0), file); - /* Output code to copy the arguments back out of `operands' - (unless we aren't going to use them at all). */ - if (XVEC (expand, 1) != 0) - { - for (i = 0; i <= MAX (stats.max_opno, stats.max_dup_opno); i++) - { - fprintf (file, " operand%d = operands[%d];\n", i, i); - fprintf (file, " (void) operand%d;\n", i); - } - } fprintf (file, " }\n"); } @@ -606,7 +593,6 @@ static void gen_split (const md_rtx_info &info, FILE *file) { struct pattern_stats stats; - int i; rtx split = info.def; const char *const name = ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split"); @@ -639,8 +625,6 @@ gen_split (const md_rtx_info &info, FILE *file) fprintf (file, "{\n"); /* Declare all local variables. */ - for (i = 0; i < stats.num_operand_vars; i++) - fprintf (file, " rtx operand%d;\n", i); fprintf (file, " rtx_insn *_val = NULL;\n"); if (GET_CODE (split) == DEFINE_PEEPHOLE2) @@ -663,13 +647,6 @@ gen_split (const md_rtx_info &info, FILE *file) if (XSTR (split, 3)) emit_c_code (XSTR (split, 3), true, name, file); - /* Output code to copy the arguments back out of `operands' */ - for (i = 0; i < stats.num_operand_vars; i++) - { - fprintf (file, " operand%d = operands[%d];\n", i, i); - fprintf (file, " (void) operand%d;\n", i); - } - gen_emit_seq (XVEC (split, 2), used, info, file); /* Call `get_insns' to make a list of all the -- 2.43.0