genrecog.c (enum decision_type): Add DT_num_insns.
2005-08-27 Paul Brook <paul@codesourcery.com> * genrecog.c (enum decision_type): Add DT_num_insns. (struct decision_test): Add u.num_insns. (add_to_sequence): Add DT_num_insns test. (maybe_both_true_2, nodes_identical_1): Handle DT_num_insns. (write_cond, debug_decision_2): Ditto. (change_state): Assume peep2_next_insn never fails. Remove "afterward" argument. (write afterward, write_tree): Update to match. * recog.c (peep2_current_count): New variable. (peep2_next_insn): Check it. (peephole2_optimize): Set peep2_current_count. * recog.h (peep2_current_count): Declare. From-SVN: r103553
This commit is contained in:
parent
e0af6cb720
commit
0cd6c85a31
4 changed files with 66 additions and 27 deletions
|
@ -1,3 +1,18 @@
|
|||
2005-08-27 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* genrecog.c (enum decision_type): Add DT_num_insns.
|
||||
(struct decision_test): Add u.num_insns.
|
||||
(add_to_sequence): Add DT_num_insns test.
|
||||
(maybe_both_true_2, nodes_identical_1): Handle DT_num_insns.
|
||||
(write_cond, debug_decision_2): Ditto.
|
||||
(change_state): Assume peep2_next_insn never fails.
|
||||
Remove "afterward" argument.
|
||||
(write afterward, write_tree): Update to match.
|
||||
* recog.c (peep2_current_count): New variable.
|
||||
(peep2_next_insn): Check it.
|
||||
(peephole2_optimize): Set peep2_current_count.
|
||||
* recog.h (peep2_current_count): Declare.
|
||||
|
||||
2005-08-26 Josh Conner <jconner@apple.com>
|
||||
|
||||
PR middle-end/23584
|
||||
|
|
|
@ -87,6 +87,7 @@ struct decision_test
|
|||
/* These types are roughly in the order in which we'd like to test them. */
|
||||
enum decision_type
|
||||
{
|
||||
DT_num_insns,
|
||||
DT_mode, DT_code, DT_veclen,
|
||||
DT_elt_zero_int, DT_elt_one_int, DT_elt_zero_wide, DT_elt_zero_wide_safe,
|
||||
DT_const_int,
|
||||
|
@ -96,6 +97,7 @@ struct decision_test
|
|||
|
||||
union
|
||||
{
|
||||
int num_insns; /* Number if insn in a define_peephole2. */
|
||||
enum machine_mode mode; /* Machine mode of node. */
|
||||
RTX_CODE code; /* Code to test. */
|
||||
|
||||
|
@ -439,7 +441,7 @@ static void find_afterward
|
|||
(struct decision_head *, struct decision *);
|
||||
|
||||
static void change_state
|
||||
(const char *, const char *, struct decision *, const char *);
|
||||
(const char *, const char *, const char *);
|
||||
static void print_code
|
||||
(enum rtx_code);
|
||||
static void write_afterward
|
||||
|
@ -923,8 +925,22 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
|||
/* Toplevel peephole pattern. */
|
||||
if (insn_type == PEEPHOLE2 && top)
|
||||
{
|
||||
/* We don't need the node we just created -- unlink it. */
|
||||
last->first = last->last = NULL;
|
||||
int num_insns;
|
||||
|
||||
/* Check we have sufficient insns. This avoids complications
|
||||
because we then know peep2_next_insn never fails. */
|
||||
num_insns = XVECLEN (pattern, 0);
|
||||
if (num_insns > 1)
|
||||
{
|
||||
test = new_decision_test (DT_num_insns, &place);
|
||||
test->u.num_insns = num_insns;
|
||||
last = &sub->success;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We don't need the node we just created -- unlink it. */
|
||||
last->first = last->last = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++)
|
||||
{
|
||||
|
@ -1174,6 +1190,12 @@ maybe_both_true_2 (struct decision_test *d1, struct decision_test *d2)
|
|||
{
|
||||
switch (d1->type)
|
||||
{
|
||||
case DT_num_insns:
|
||||
if (d1->u.num_insns == d2->u.num_insns)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
||||
case DT_mode:
|
||||
return d1->u.mode == d2->u.mode;
|
||||
|
||||
|
@ -1372,6 +1394,9 @@ nodes_identical_1 (struct decision_test *d1, struct decision_test *d2)
|
|||
{
|
||||
switch (d1->type)
|
||||
{
|
||||
case DT_num_insns:
|
||||
return d1->u.num_insns == d2->u.num_insns;
|
||||
|
||||
case DT_mode:
|
||||
return d1->u.mode == d2->u.mode;
|
||||
|
||||
|
@ -1767,8 +1792,7 @@ find_afterward (struct decision_head *head, struct decision *real_afterward)
|
|||
match multiple insns and we try to step past the end of the stream. */
|
||||
|
||||
static void
|
||||
change_state (const char *oldpos, const char *newpos,
|
||||
struct decision *afterward, const char *indent)
|
||||
change_state (const char *oldpos, const char *newpos, const char *indent)
|
||||
{
|
||||
int odepth = strlen (oldpos);
|
||||
int ndepth = strlen (newpos);
|
||||
|
@ -1793,22 +1817,8 @@ change_state (const char *oldpos, const char *newpos,
|
|||
/* It's a different insn from the first one. */
|
||||
if (ISUPPER (newpos[depth]))
|
||||
{
|
||||
/* We can only fail if we're moving down the tree. */
|
||||
if (old_has_insn >= 0 && oldpos[old_has_insn] >= newpos[depth])
|
||||
{
|
||||
printf ("%stem = peep2_next_insn (%d);\n",
|
||||
indent, newpos[depth] - 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("%stem = peep2_next_insn (%d);\n",
|
||||
indent, newpos[depth] - 'A');
|
||||
printf ("%sif (tem == NULL_RTX)\n", indent);
|
||||
if (afterward)
|
||||
printf ("%s goto L%d;\n", indent, afterward->number);
|
||||
else
|
||||
printf ("%s goto ret0;\n", indent);
|
||||
}
|
||||
printf ("%stem = peep2_next_insn (%d);\n",
|
||||
indent, newpos[depth] - 'A');
|
||||
printf ("%sx%d = PATTERN (tem);\n", indent, depth + 1);
|
||||
}
|
||||
else if (ISLOWER (newpos[depth]))
|
||||
|
@ -1842,7 +1852,7 @@ write_afterward (struct decision *start, struct decision *afterward,
|
|||
printf("%sgoto ret0;\n", indent);
|
||||
else
|
||||
{
|
||||
change_state (start->position, afterward->position, NULL, indent);
|
||||
change_state (start->position, afterward->position, indent);
|
||||
printf ("%sgoto L%d;\n", indent, afterward->number);
|
||||
}
|
||||
}
|
||||
|
@ -2067,6 +2077,10 @@ write_cond (struct decision_test *p, int depth,
|
|||
{
|
||||
switch (p->type)
|
||||
{
|
||||
case DT_num_insns:
|
||||
printf ("peep2_current_count >= %d", p->u.num_insns);
|
||||
break;
|
||||
|
||||
case DT_mode:
|
||||
printf ("GET_MODE (x%d) == %smode", depth, GET_MODE_NAME (p->u.mode));
|
||||
break;
|
||||
|
@ -2363,7 +2377,7 @@ write_tree (struct decision_head *head, const char *prevpos,
|
|||
else
|
||||
printf (" if (tem >= 0)\n return tem;\n");
|
||||
|
||||
change_state (p->position, p->afterward->position, NULL, " ");
|
||||
change_state (p->position, p->afterward->position, " ");
|
||||
printf (" goto L%d;\n", p->afterward->number);
|
||||
}
|
||||
else
|
||||
|
@ -2376,7 +2390,7 @@ write_tree (struct decision_head *head, const char *prevpos,
|
|||
{
|
||||
int depth = strlen (p->position);
|
||||
|
||||
change_state (prevpos, p->position, head->last->afterward, " ");
|
||||
change_state (prevpos, p->position, " ");
|
||||
write_tree_1 (head, depth, type);
|
||||
|
||||
for (p = head->first; p; p = p->next)
|
||||
|
@ -2830,6 +2844,9 @@ debug_decision_2 (struct decision_test *test)
|
|||
{
|
||||
switch (test->type)
|
||||
{
|
||||
case DT_num_insns:
|
||||
fprintf (stderr, "num_insns=%d", test->u.num_insns);
|
||||
break;
|
||||
case DT_mode:
|
||||
fprintf (stderr, "mode=%s", GET_MODE_NAME (test->u.mode));
|
||||
break;
|
||||
|
|
12
gcc/recog.c
12
gcc/recog.c
|
@ -2853,6 +2853,8 @@ struct peep2_insn_data
|
|||
|
||||
static struct peep2_insn_data peep2_insn_data[MAX_INSNS_PER_PEEP2 + 1];
|
||||
static int peep2_current;
|
||||
/* The number of instructions available to match a peep2. */
|
||||
int peep2_current_count;
|
||||
|
||||
/* A non-insn marker indicating the last insn of the block.
|
||||
The live_before regset for this element is correct, indicating
|
||||
|
@ -2866,14 +2868,12 @@ static int peep2_current;
|
|||
rtx
|
||||
peep2_next_insn (int n)
|
||||
{
|
||||
gcc_assert (n < MAX_INSNS_PER_PEEP2 + 1);
|
||||
gcc_assert (n <= peep2_current_count);
|
||||
|
||||
n += peep2_current;
|
||||
if (n >= MAX_INSNS_PER_PEEP2 + 1)
|
||||
n -= MAX_INSNS_PER_PEEP2 + 1;
|
||||
|
||||
if (peep2_insn_data[n].insn == PEEP2_EOB)
|
||||
return NULL_RTX;
|
||||
return peep2_insn_data[n].insn;
|
||||
}
|
||||
|
||||
|
@ -3062,6 +3062,7 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
|
|||
/* Indicate that all slots except the last holds invalid data. */
|
||||
for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
|
||||
peep2_insn_data[i].insn = NULL_RTX;
|
||||
peep2_current_count = 0;
|
||||
|
||||
/* Indicate that the last slot contains live_after data. */
|
||||
peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
|
||||
|
@ -3090,6 +3091,8 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
|
|||
/* Record this insn. */
|
||||
if (--peep2_current < 0)
|
||||
peep2_current = MAX_INSNS_PER_PEEP2;
|
||||
if (peep2_current_count < MAX_INSNS_PER_PEEP2)
|
||||
peep2_current_count++;
|
||||
peep2_insn_data[peep2_current].insn = insn;
|
||||
propagate_one_insn (pbi, insn);
|
||||
COPY_REG_SET (peep2_insn_data[peep2_current].live_before, live);
|
||||
|
@ -3234,6 +3237,7 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
|
|||
for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i)
|
||||
peep2_insn_data[i].insn = NULL_RTX;
|
||||
peep2_insn_data[peep2_current].insn = PEEP2_EOB;
|
||||
peep2_current_count = 0;
|
||||
#else
|
||||
/* Back up lifetime information past the end of the
|
||||
newly created sequence. */
|
||||
|
@ -3249,6 +3253,8 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
|
|||
{
|
||||
if (--i < 0)
|
||||
i = MAX_INSNS_PER_PEEP2;
|
||||
if (peep2_current_count < MAX_INSNS_PER_PEEP2)
|
||||
peep2_current_count++;
|
||||
peep2_insn_data[i].insn = x;
|
||||
propagate_one_insn (pbi, x);
|
||||
COPY_REG_SET (peep2_insn_data[i].live_before, live);
|
||||
|
|
|
@ -265,3 +265,4 @@ struct insn_data
|
|||
};
|
||||
|
||||
extern const struct insn_data insn_data[];
|
||||
extern int peep2_current_count;
|
||||
|
|
Loading…
Add table
Reference in a new issue