From e792559ab3d6fdb933e91bb0a317554d5920d58a Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 1 Apr 2011 08:15:08 +0000 Subject: [PATCH] gensupport.h (pattern_stats): New structure. gcc/ * gensupport.h (pattern_stats): New structure. * gensupport.c (get_pattern_stats_1, get_pattern_stats): New functions. * genemit.c (max_opno, max_dupno, max_scratch_opno): Delete. (max_operand_1, max_operand_vec): Delete. (gen_insn, gen_expand, gen_split): Use get_pattern_stats. From-SVN: r171821 --- gcc/ChangeLog | 8 ++++ gcc/genemit.c | 111 +++++++++++------------------------------------ gcc/gensupport.c | 77 ++++++++++++++++++++++++++++++++ gcc/gensupport.h | 28 ++++++++++++ 4 files changed, 138 insertions(+), 86 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 922f6e6f2ee..d048013b658 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-04-01 Richard Sandiford + + * gensupport.h (pattern_stats): New structure. + * gensupport.c (get_pattern_stats_1, get_pattern_stats): New functions. + * genemit.c (max_opno, max_dupno, max_scratch_opno): Delete. + (max_operand_1, max_operand_vec): Delete. + (gen_insn, gen_expand, gen_split): Use get_pattern_stats. + 2011-03-31 Nathan Froyd * emit-rtl.c (emit_pattern_after_setloc): New function. diff --git a/gcc/genemit.c b/gcc/genemit.c index 6b1ae7d8608..aea7cb8b68a 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -29,9 +29,6 @@ along with GCC; see the file COPYING3. If not see #include "gensupport.h" -static int max_opno; -static int max_dup_opno; -static int max_scratch_opno; static int insn_code_number; static int insn_index_number; @@ -56,8 +53,6 @@ struct clobber_ent struct clobber_ent *next; }; -static void max_operand_1 (rtx); -static int max_operand_vec (rtx, int); static void print_code (RTX_CODE); static void gen_exp (rtx, enum rtx_code, char *); static void gen_insn (rtx, int); @@ -68,58 +63,6 @@ static void output_added_clobbers_hard_reg_p (void); static void gen_rtx_scratch (rtx, enum rtx_code); static void output_peephole2_scratches (rtx); - -static void -max_operand_1 (rtx x) -{ - RTX_CODE code; - int i; - int len; - const char *fmt; - - if (x == 0) - return; - - code = GET_CODE (x); - - if (code == MATCH_OPERAND || code == MATCH_OPERATOR - || code == MATCH_PARALLEL) - max_opno = MAX (max_opno, XINT (x, 0)); - if (code == MATCH_DUP || code == MATCH_OP_DUP || code == MATCH_PAR_DUP) - max_dup_opno = MAX (max_dup_opno, XINT (x, 0)); - if (code == MATCH_SCRATCH) - max_scratch_opno = MAX (max_scratch_opno, XINT (x, 0)); - - fmt = GET_RTX_FORMAT (code); - len = GET_RTX_LENGTH (code); - for (i = 0; i < len; i++) - { - if (fmt[i] == 'e' || fmt[i] == 'u') - max_operand_1 (XEXP (x, i)); - else if (fmt[i] == 'E') - { - int j; - for (j = 0; j < XVECLEN (x, i); j++) - max_operand_1 (XVECEXP (x, i, j)); - } - } -} - -static int -max_operand_vec (rtx insn, int arg) -{ - int len = XVECLEN (insn, arg); - int i; - - max_opno = -1; - max_dup_opno = -1; - max_scratch_opno = -1; - - for (i = 0; i < len; i++) - max_operand_1 (XVECEXP (insn, arg, i)); - - return max_opno + 1; -} static void print_code (RTX_CODE code) @@ -317,7 +260,7 @@ gen_exp (rtx x, enum rtx_code subroutine_type, char *used) static void gen_insn (rtx insn, int lineno) { - int operands; + struct pattern_stats stats; int i; /* See if the pattern for this insn ends with a group of CLOBBERs of (hard) @@ -402,14 +345,14 @@ gen_insn (rtx insn, int lineno) printf ("/* %s:%d */\n", read_md_filename, lineno); /* Find out how many operands this function has. */ - operands = max_operand_vec (insn, 1); - if (max_dup_opno >= operands) + get_pattern_stats (&stats, XVEC (insn, 1)); + if (stats.max_dup_opno > stats.max_opno) fatal ("match_dup operand number has no match_operand"); /* Output the function name and argument declarations. */ printf ("rtx\ngen_%s (", XSTR (insn, 0)); - if (operands) - for (i = 0; i < operands; i++) + if (stats.num_generator_args) + for (i = 0; i < stats.num_generator_args; i++) if (i) printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i); else @@ -429,7 +372,7 @@ gen_insn (rtx insn, int lineno) } else { - char *used = XCNEWVEC (char, operands); + char *used = XCNEWVEC (char, stats.num_generator_args); printf (" return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1)); @@ -449,7 +392,7 @@ gen_insn (rtx insn, int lineno) static void gen_expand (rtx expand) { - int operands; + struct pattern_stats stats; int i; char *used; @@ -459,12 +402,12 @@ gen_expand (rtx expand) fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0)); /* Find out how many operands this function has. */ - operands = max_operand_vec (expand, 1); + get_pattern_stats (&stats, XVEC (expand, 1)); /* Output the function name and argument declarations. */ printf ("rtx\ngen_%s (", XSTR (expand, 0)); - if (operands) - for (i = 0; i < operands; i++) + if (stats.num_generator_args) + for (i = 0; i < stats.num_generator_args; i++) if (i) printf (",\n\trtx operand%d", i); else @@ -478,7 +421,7 @@ gen_expand (rtx expand) and no MATCH_DUPs are present, we can just return the desired insn like we do for a DEFINE_INSN. This saves memory. */ if ((XSTR (expand, 3) == 0 || *XSTR (expand, 3) == '\0') - && operands > max_dup_opno + && stats.max_opno >= stats.max_dup_opno && XVECLEN (expand, 1) == 1) { printf (" return "); @@ -489,9 +432,9 @@ gen_expand (rtx expand) /* For each operand referred to only with MATCH_DUPs, make a local variable. */ - for (i = operands; i <= max_dup_opno; i++) + for (i = stats.num_generator_args; i <= stats.max_dup_opno; i++) printf (" rtx operand%d;\n", i); - for (; i <= max_scratch_opno; i++) + for (; i <= stats.max_scratch_opno; i++) printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i); printf (" rtx _val = 0;\n"); printf (" start_sequence ();\n"); @@ -505,11 +448,11 @@ gen_expand (rtx expand) if (XSTR (expand, 3) && *XSTR (expand, 3)) { printf (" {\n"); - if (operands > 0 || max_dup_opno >= 0 || max_scratch_opno >= 0) - printf (" rtx operands[%d];\n", - MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1)); + if (stats.num_operand_vars > 0) + printf (" rtx operands[%d];\n", stats.num_operand_vars); + /* Output code to copy the arguments into `operands'. */ - for (i = 0; i < operands; i++) + for (i = 0; i < stats.num_generator_args; i++) printf (" operands[%d] = operand%d;\n", i, i); /* Output the special code to be executed before the sequence @@ -521,9 +464,7 @@ gen_expand (rtx expand) (unless we aren't going to use them at all). */ if (XVEC (expand, 1) != 0) { - for (i = 0; - i < MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1); - i++) + for (i = 0; i < stats.num_operand_vars; i++) { printf (" operand%d = operands[%d];\n", i, i); printf (" (void) operand%d;\n", i); @@ -536,8 +477,7 @@ gen_expand (rtx expand) Use emit_insn to add them to the sequence being accumulated. But don't do this if the user's code has set `no_more' nonzero. */ - used = XCNEWVEC (char, - MAX (operands, MAX (max_scratch_opno, max_dup_opno) + 1)); + used = XCNEWVEC (char, stats.num_operand_vars); for (i = 0; i < XVECLEN (expand, 1); i++) { @@ -591,8 +531,8 @@ gen_expand (rtx expand) static void gen_split (rtx split) { + struct pattern_stats stats; int i; - int operands; const char *const name = ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split"); const char *unused; @@ -607,10 +547,9 @@ gen_split (rtx split) /* Find out how many operands this function has. */ - max_operand_vec (split, 2); - operands = MAX (max_opno, MAX (max_dup_opno, max_scratch_opno)) + 1; - unused = (operands == 0 ? " ATTRIBUTE_UNUSED" : ""); - used = XCNEWVEC (char, operands); + get_pattern_stats (&stats, XVEC (split, 2)); + unused = (stats.num_operand_vars == 0 ? " ATTRIBUTE_UNUSED" : ""); + used = XCNEWVEC (char, stats.num_operand_vars); /* Output the prototype, function name and argument declarations. */ if (GET_CODE (split) == DEFINE_PEEPHOLE2) @@ -629,7 +568,7 @@ gen_split (rtx split) printf ("{\n"); /* Declare all local variables. */ - for (i = 0; i < operands; i++) + for (i = 0; i < stats.num_operand_vars; i++) printf (" rtx operand%d;\n", i); printf (" rtx _val = 0;\n"); @@ -648,7 +587,7 @@ gen_split (rtx split) } /* Output code to copy the arguments back out of `operands' */ - for (i = 0; i < operands; i++) + for (i = 0; i < stats.num_operand_vars; i++) { printf (" operand%d = operands[%d];\n", i, i); printf (" (void) operand%d;\n", i); diff --git a/gcc/gensupport.c b/gcc/gensupport.c index e81682c7c21..7bdfc41a4a1 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -1367,3 +1367,80 @@ record_insn_name (int code, const char *name) insn_name_ptr[code] = new_name; } + +/* Make STATS describe the operands that appear in rtx X. */ + +static void +get_pattern_stats_1 (struct pattern_stats *stats, rtx x) +{ + RTX_CODE code; + int i; + int len; + const char *fmt; + + if (x == NULL_RTX) + return; + + code = GET_CODE (x); + switch (code) + { + case MATCH_OPERAND: + case MATCH_OPERATOR: + case MATCH_PARALLEL: + stats->max_opno = MAX (stats->max_opno, XINT (x, 0)); + break; + + case MATCH_DUP: + case MATCH_OP_DUP: + case MATCH_PAR_DUP: + stats->num_dups++; + stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0)); + break; + + case MATCH_SCRATCH: + stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0)); + break; + + default: + break; + } + + fmt = GET_RTX_FORMAT (code); + len = GET_RTX_LENGTH (code); + for (i = 0; i < len; i++) + { + if (fmt[i] == 'e' || fmt[i] == 'u') + get_pattern_stats_1 (stats, XEXP (x, i)); + else if (fmt[i] == 'E') + { + int j; + for (j = 0; j < XVECLEN (x, i); j++) + get_pattern_stats_1 (stats, XVECEXP (x, i, j)); + } + } +} + +/* Make STATS describe the operands that appear in instruction pattern + PATTERN. */ + +void +get_pattern_stats (struct pattern_stats *stats, rtvec pattern) +{ + int i, len; + + stats->max_opno = -1; + stats->max_dup_opno = -1; + stats->max_scratch_opno = -1; + stats->num_dups = 0; + + len = GET_NUM_ELEM (pattern); + for (i = 0; i < len; i++) + get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i)); + + stats->num_generator_args = stats->max_opno + 1; + stats->num_insn_operands = MAX (stats->max_opno, + stats->max_scratch_opno) + 1; + stats->num_operand_vars = MAX (stats->max_opno, + MAX (stats->max_dup_opno, + stats->max_scratch_opno)) + 1; +} diff --git a/gcc/gensupport.h b/gcc/gensupport.h index 999c2222ecb..5ae32d5f40d 100644 --- a/gcc/gensupport.h +++ b/gcc/gensupport.h @@ -83,4 +83,32 @@ extern void add_predicate (struct pred_data *); #define FOR_ALL_PREDICATES(p) for (p = first_predicate; p; p = p->next) +struct pattern_stats +{ + /* The largest match_operand, match_operator or match_parallel + number found. */ + int max_opno; + + /* The largest match_dup, match_op_dup or match_par_dup number found. */ + int max_dup_opno; + + /* The largest match_scratch number found. */ + int max_scratch_opno; + + /* The number of times match_dup, match_op_dup or match_par_dup appears + in the pattern. */ + int num_dups; + + /* The number of rtx arguments to the generator function. */ + int num_generator_args; + + /* The number of rtx operands in an insn. */ + int num_insn_operands; + + /* The number of operand variables that are needed. */ + int num_operand_vars; +}; + +extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec); + #endif /* GCC_GENSUPPORT_H */ -- 2.30.2