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
This commit is contained in:
parent
90630d1932
commit
e792559ab3
@ -1,3 +1,11 @@
|
||||
2011-04-01 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* 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 <froydnj@codesourcery.com>
|
||||
|
||||
* emit-rtl.c (emit_pattern_after_setloc): New function.
|
||||
|
111
gcc/genemit.c
111
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user