Commit 6a1a787e by Richard Sandiford Committed by Richard Sandiford

re PR rtl-optimization/48575 (RTL vector patterns are limited to 26 elements)

gcc/
	PR rtl-optimization/48575
	* genrecog.c (position_type): New enum.
	(position): New structure.
	(decision): Use position structure instead of a string.
	(root_pos, peep2_insn_pos_list): New variables.
	(next_position, compare_positions): New functions.
	(new_decision): Use position structures instead of strings.
	(maybe_both_true): Likewise.
	(change_state): Likewise.
	(write_tree): Likewise.
	(make_insn_sequence): Likewise.

From-SVN: r174305
parent f256f612
2011-05-26 Richard Sandiford <rdsandiford@googlemail.com>
PR rtl-optimization/48575
* genrecog.c (position_type): New enum.
(position): New structure.
(decision): Use position structure instead of a string.
(root_pos, peep2_insn_pos_list): New variables.
(next_position, compare_positions): New functions.
(new_decision): Use position structures instead of strings.
(maybe_both_true): Likewise.
(change_state): Likewise.
(write_tree): Likewise.
(make_insn_sequence): Likewise.
2011-05-26 Nathan Froyd <froydnj@codesourcery.com> 2011-05-26 Nathan Froyd <froydnj@codesourcery.com>
* tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as * tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as
......
...@@ -62,6 +62,49 @@ ...@@ -62,6 +62,49 @@
#define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \ #define OUTPUT_LABEL(INDENT_STRING, LABEL_NUMBER) \
printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER)) printf("%sL%d: ATTRIBUTE_UNUSED_LABEL\n", (INDENT_STRING), (LABEL_NUMBER))
/* Ways of obtaining an rtx to be tested. */
enum position_type {
/* PATTERN (peep2_next_insn (ARG)). */
POS_PEEP2_INSN,
/* XEXP (BASE, ARG). */
POS_XEXP,
/* XVECEXP (BASE, 0, ARG). */
POS_XVECEXP0
};
/* The position of an rtx relative to X0. Each useful position is
represented by exactly one instance of this structure. */
struct position
{
/* The parent rtx. This is the root position for POS_PEEP2_INSNs. */
struct position *base;
/* A position with the same BASE and TYPE, but with the next value
of ARG. */
struct position *next;
/* A list of all POS_XEXP positions that use this one as their base,
chained by NEXT fields. The first entry represents XEXP (this, 0),
the second represents XEXP (this, 1), and so on. */
struct position *xexps;
/* A list of POS_XVECEXP0 positions that use this one as their base,
chained by NEXT fields. The first entry represents XVECEXP (this, 0, 0),
the second represents XVECEXP (this, 0, 1), and so on. */
struct position *xvecexp0s;
/* The type of position. */
enum position_type type;
/* The argument to TYPE (shown as ARG in the position_type comments). */
int arg;
/* The depth of this position, with 0 as the root. */
int depth;
};
/* A listhead of decision trees. The alternatives to a node are kept /* A listhead of decision trees. The alternatives to a node are kept
in a doubly-linked list so we can easily add nodes to the proper in a doubly-linked list so we can easily add nodes to the proper
place when merging. */ place when merging. */
...@@ -132,7 +175,7 @@ struct decision ...@@ -132,7 +175,7 @@ struct decision
struct decision *afterward; /* Node to test on success, struct decision *afterward; /* Node to test on success,
but failure of successor nodes. */ but failure of successor nodes. */
const char *position; /* String denoting position in pattern. */ struct position *position; /* Position in pattern. */
struct decision_test *tests; /* The tests for this node. */ struct decision_test *tests; /* The tests for this node. */
...@@ -170,9 +213,16 @@ static int max_depth; ...@@ -170,9 +213,16 @@ static int max_depth;
/* The line number of the start of the pattern currently being processed. */ /* The line number of the start of the pattern currently being processed. */
static int pattern_lineno; static int pattern_lineno;
/* The root position (x0). */
static struct position root_pos;
/* A list of all POS_PEEP2_INSNs. The entry for insn 0 is the root position,
since we are given that instruction's pattern as x0. */
static struct position *peep2_insn_pos_list = &root_pos;
static struct decision *new_decision static struct decision *new_decision
(const char *, struct decision_head *); (struct position *, struct decision_head *);
static struct decision_test *new_decision_test static struct decision_test *new_decision_test
(enum decision_type, struct decision_test ***); (enum decision_type, struct decision_test ***);
static rtx find_operand static rtx find_operand
...@@ -182,7 +232,7 @@ static rtx find_matching_operand ...@@ -182,7 +232,7 @@ static rtx find_matching_operand
static void validate_pattern static void validate_pattern
(rtx, rtx, rtx, int); (rtx, rtx, rtx, int);
static struct decision *add_to_sequence static struct decision *add_to_sequence
(rtx, struct decision_head *, const char *, enum routine_type, int); (rtx, struct decision_head *, struct position *, enum routine_type, int);
static int maybe_both_true_2 static int maybe_both_true_2
(struct decision_test *, struct decision_test *); (struct decision_test *, struct decision_test *);
...@@ -210,7 +260,7 @@ static void find_afterward ...@@ -210,7 +260,7 @@ static void find_afterward
(struct decision_head *, struct decision *); (struct decision_head *, struct decision *);
static void change_state static void change_state
(const char *, const char *, const char *); (struct position *, struct position *, const char *);
static void print_code static void print_code
(enum rtx_code); (enum rtx_code);
static void write_afterward static void write_afterward
...@@ -229,7 +279,7 @@ static int write_node ...@@ -229,7 +279,7 @@ static int write_node
static void write_tree_1 static void write_tree_1
(struct decision_head *, int, enum routine_type); (struct decision_head *, int, enum routine_type);
static void write_tree static void write_tree
(struct decision_head *, const char *, enum routine_type, int); (struct decision_head *, struct position *, enum routine_type, int);
static void write_subroutine static void write_subroutine
(struct decision_head *, enum routine_type); (struct decision_head *, enum routine_type);
static void write_subroutines static void write_subroutines
...@@ -253,15 +303,66 @@ extern void debug_decision ...@@ -253,15 +303,66 @@ extern void debug_decision
extern void debug_decision_list extern void debug_decision_list
(struct decision *); (struct decision *);
/* Return a position with the given BASE, TYPE and ARG. NEXT_PTR
points to where the unique object that represents the position
should be stored. Create the object if it doesn't already exist,
otherwise reuse the object that is already there. */
static struct position *
next_position (struct position **next_ptr, struct position *base,
enum position_type type, int arg)
{
struct position *pos;
pos = *next_ptr;
if (!pos)
{
pos = XCNEW (struct position);
pos->base = base;
pos->type = type;
pos->arg = arg;
pos->depth = base->depth + 1;
*next_ptr = pos;
}
return pos;
}
/* Compare positions POS1 and POS2 lexicographically. */
static int
compare_positions (struct position *pos1, struct position *pos2)
{
int diff;
diff = pos1->depth - pos2->depth;
if (diff < 0)
do
pos2 = pos2->base;
while (pos1->depth != pos2->depth);
else if (diff > 0)
do
pos1 = pos1->base;
while (pos1->depth != pos2->depth);
while (pos1 != pos2)
{
diff = (int) pos1->type - (int) pos2->type;
if (diff == 0)
diff = pos1->arg - pos2->arg;
pos1 = pos1->base;
pos2 = pos2->base;
}
return diff;
}
/* Create a new node in sequence after LAST. */ /* Create a new node in sequence after LAST. */
static struct decision * static struct decision *
new_decision (const char *position, struct decision_head *last) new_decision (struct position *pos, struct decision_head *last)
{ {
struct decision *new_decision = XCNEW (struct decision); struct decision *new_decision = XCNEW (struct decision);
new_decision->success = *last; new_decision->success = *last;
new_decision->position = xstrdup (position); new_decision->position = pos;
new_decision->number = next_number++; new_decision->number = next_number++;
last->first = last->last = new_decision; last->first = last->last = new_decision;
...@@ -636,35 +737,31 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code) ...@@ -636,35 +737,31 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
LAST is a pointer to the listhead in the previous node in the chain (or LAST is a pointer to the listhead in the previous node in the chain (or
in the calling function, for the first node). in the calling function, for the first node).
POSITION is the string representing the current position in the insn. POSITION is the current position in the insn.
INSN_TYPE is the type of insn for which we are emitting code. INSN_TYPE is the type of insn for which we are emitting code.
A pointer to the final node in the chain is returned. */ A pointer to the final node in the chain is returned. */
static struct decision * static struct decision *
add_to_sequence (rtx pattern, struct decision_head *last, const char *position, add_to_sequence (rtx pattern, struct decision_head *last,
enum routine_type insn_type, int top) struct position *pos, enum routine_type insn_type, int top)
{ {
RTX_CODE code; RTX_CODE code;
struct decision *this_decision, *sub; struct decision *this_decision, *sub;
struct decision_test *test; struct decision_test *test;
struct decision_test **place; struct decision_test **place;
char *subpos; struct position *subpos, **subpos_ptr;
size_t i; size_t i;
const char *fmt; const char *fmt;
int depth = strlen (position);
int len; int len;
enum machine_mode mode; enum machine_mode mode;
enum position_type pos_type;
if (depth > max_depth) if (pos->depth > max_depth)
max_depth = depth; max_depth = pos->depth;
subpos = XNEWVAR (char, depth + 2);
strcpy (subpos, position);
subpos[depth + 1] = 0;
sub = this_decision = new_decision (position, last); sub = this_decision = new_decision (pos, last);
place = &this_decision->tests; place = &this_decision->tests;
restart: restart:
...@@ -694,15 +791,15 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -694,15 +791,15 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
last->first = last->last = NULL; last->first = last->last = NULL;
} }
subpos_ptr = &peep2_insn_pos_list;
for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++) for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++)
{ {
/* Which insn we're looking at is represented by A-Z. We don't subpos = next_position (subpos_ptr, &root_pos,
ever use 'A', however; it is always implied. */ POS_PEEP2_INSN, i);
subpos[depth] = (i > 0 ? 'A' + i : 0);
sub = add_to_sequence (XVECEXP (pattern, 0, i), sub = add_to_sequence (XVECEXP (pattern, 0, i),
last, subpos, insn_type, 0); last, subpos, insn_type, 0);
last = &sub->success; last = &sub->success;
subpos_ptr = &subpos->next;
} }
goto ret; goto ret;
} }
...@@ -786,12 +883,22 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -786,12 +883,22 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL) if (was_code == MATCH_OPERATOR || was_code == MATCH_PARALLEL)
{ {
char base = (was_code == MATCH_OPERATOR ? '0' : 'a'); if (was_code == MATCH_OPERATOR)
{
pos_type = POS_XEXP;
subpos_ptr = &pos->xexps;
}
else
{
pos_type = POS_XVECEXP0;
subpos_ptr = &pos->xvecexp0s;
}
for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++) for (i = 0; i < (size_t) XVECLEN (pattern, 2); i++)
{ {
subpos[depth] = i + base; subpos = next_position (subpos_ptr, pos, pos_type, i);
sub = add_to_sequence (XVECEXP (pattern, 2, i), sub = add_to_sequence (XVECEXP (pattern, 2, i),
&sub->success, subpos, insn_type, 0); &sub->success, subpos, insn_type, 0);
subpos_ptr = &subpos->next;
} }
} }
goto fini; goto fini;
...@@ -806,11 +913,13 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -806,11 +913,13 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
test = new_decision_test (DT_accept_op, &place); test = new_decision_test (DT_accept_op, &place);
test->u.opno = XINT (pattern, 0); test->u.opno = XINT (pattern, 0);
subpos_ptr = &pos->xvecexp0s;
for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++) for (i = 0; i < (size_t) XVECLEN (pattern, 1); i++)
{ {
subpos[depth] = i + '0'; subpos = next_position (subpos_ptr, pos, POS_XVECEXP0, i);
sub = add_to_sequence (XVECEXP (pattern, 1, i), sub = add_to_sequence (XVECEXP (pattern, 1, i),
&sub->success, subpos, insn_type, 0); &sub->success, subpos, insn_type, 0);
subpos_ptr = &subpos->next;
} }
goto fini; goto fini;
...@@ -874,24 +983,29 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -874,24 +983,29 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
} }
/* Now test our sub-patterns. */ /* Now test our sub-patterns. */
subpos_ptr = &pos->xexps;
for (i = 0; i < (size_t) len; i++) for (i = 0; i < (size_t) len; i++)
{ {
subpos = next_position (subpos_ptr, pos, POS_XEXP, i);
switch (fmt[i]) switch (fmt[i])
{ {
case 'e': case 'u': case 'e': case 'u':
subpos[depth] = '0' + i;
sub = add_to_sequence (XEXP (pattern, i), &sub->success, sub = add_to_sequence (XEXP (pattern, i), &sub->success,
subpos, insn_type, 0); subpos, insn_type, 0);
break; break;
case 'E': case 'E':
{ {
struct position *subpos2, **subpos2_ptr;
int j; int j;
subpos2_ptr = &pos->xvecexp0s;
for (j = 0; j < XVECLEN (pattern, i); j++) for (j = 0; j < XVECLEN (pattern, i); j++)
{ {
subpos[depth] = 'a' + j; subpos2 = next_position (subpos2_ptr, pos, POS_XVECEXP0, j);
sub = add_to_sequence (XVECEXP (pattern, i, j), sub = add_to_sequence (XVECEXP (pattern, i, j),
&sub->success, subpos, insn_type, 0); &sub->success, subpos2, insn_type, 0);
subpos2_ptr = &subpos2->next;
} }
break; break;
} }
...@@ -905,6 +1019,7 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -905,6 +1019,7 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
subpos_ptr = &subpos->next;
} }
fini: fini:
...@@ -928,7 +1043,6 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position, ...@@ -928,7 +1043,6 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
gcc_assert (this_decision->tests); gcc_assert (this_decision->tests);
ret: ret:
free (subpos);
return sub; return sub;
} }
...@@ -1094,12 +1208,12 @@ maybe_both_true (struct decision *d1, struct decision *d2, ...@@ -1094,12 +1208,12 @@ maybe_both_true (struct decision *d1, struct decision *d2,
of a node's success nodes (from the loop at the end of this function). of a node's success nodes (from the loop at the end of this function).
Skip forward until we come to a position that matches. Skip forward until we come to a position that matches.
Due to the way position strings are constructed, we know that iterating Due to the way positions are constructed, we know that iterating
forward from the lexically lower position (e.g. "00") will run into forward from the lexically lower position will run into the lexically
the lexically higher position (e.g. "1") and not the other way around. higher position and not the other way around. This saves a bit
This saves a bit of effort. */ of effort. */
cmp = strcmp (d1->position, d2->position); cmp = compare_positions (d1->position, d2->position);
if (cmp != 0) if (cmp != 0)
{ {
gcc_assert (!toplevel); gcc_assert (!toplevel);
...@@ -1214,7 +1328,7 @@ nodes_identical (struct decision *d1, struct decision *d2) ...@@ -1214,7 +1328,7 @@ nodes_identical (struct decision *d1, struct decision *d2)
invoked. */ invoked. */
if (d1->success.first if (d1->success.first
&& d2->success.first && d2->success.first
&& strcmp (d1->success.first->position, d2->success.first->position)) && d1->success.first->position != d2->success.first->position)
return 0; return 0;
return 1; return 1;
...@@ -1284,7 +1398,7 @@ merge_trees (struct decision_head *oldh, struct decision_head *addh) ...@@ -1284,7 +1398,7 @@ merge_trees (struct decision_head *oldh, struct decision_head *addh)
} }
/* Trying to merge bits at different positions isn't possible. */ /* Trying to merge bits at different positions isn't possible. */
gcc_assert (!strcmp (oldh->first->position, addh->first->position)); gcc_assert (oldh->first->position == addh->first->position);
for (add = addh->first; add ; add = next) for (add = addh->first; add ; add = next)
{ {
...@@ -1543,33 +1657,31 @@ find_afterward (struct decision_head *head, struct decision *real_afterward) ...@@ -1543,33 +1657,31 @@ find_afterward (struct decision_head *head, struct decision *real_afterward)
match multiple insns and we try to step past the end of the stream. */ match multiple insns and we try to step past the end of the stream. */
static void static void
change_state (const char *oldpos, const char *newpos, const char *indent) change_state (struct position *oldpos, struct position *newpos,
const char *indent)
{ {
int odepth = strlen (oldpos); while (oldpos->depth > newpos->depth)
int ndepth = strlen (newpos); oldpos = oldpos->base;
int depth;
/* Pop up as many levels as necessary. */ if (oldpos != newpos)
for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth) switch (newpos->type)
continue; {
case POS_PEEP2_INSN:
printf ("%stem = peep2_next_insn (%d);\n", indent, newpos->arg);
printf ("%sx%d = PATTERN (tem);\n", indent, newpos->depth);
break;
/* Go down to desired level. */ case POS_XEXP:
while (depth < ndepth) change_state (oldpos, newpos->base, indent);
{ printf ("%sx%d = XEXP (x%d, %d);\n",
/* It's a different insn from the first one. */ indent, newpos->depth, newpos->depth - 1, newpos->arg);
if (ISUPPER (newpos[depth])) break;
{
printf ("%stem = peep2_next_insn (%d);\n", case POS_XVECEXP0:
indent, newpos[depth] - 'A'); change_state (oldpos, newpos->base, indent);
printf ("%sx%d = PATTERN (tem);\n", indent, depth + 1);
}
else if (ISLOWER (newpos[depth]))
printf ("%sx%d = XVECEXP (x%d, 0, %d);\n", printf ("%sx%d = XVECEXP (x%d, 0, %d);\n",
indent, depth + 1, depth, newpos[depth] - 'a'); indent, newpos->depth, newpos->depth - 1, newpos->arg);
else break;
printf ("%sx%d = XEXP (x%d, %c);\n",
indent, depth + 1, depth, newpos[depth]);
++depth;
} }
} }
...@@ -1942,12 +2054,13 @@ write_action (struct decision *p, struct decision_test *test, ...@@ -1942,12 +2054,13 @@ write_action (struct decision *p, struct decision_test *test,
case PEEPHOLE2: case PEEPHOLE2:
{ {
int match_len = 0, i; int match_len = 0;
struct position *pos;
for (i = strlen (p->position) - 1; i >= 0; --i) for (pos = p->position; pos; pos = pos->base)
if (ISUPPER (p->position[i])) if (pos->type == POS_PEEP2_INSN)
{ {
match_len = p->position[i] - 'A'; match_len = pos->arg;
break; break;
} }
printf ("%s*_pmatch_len = %d;\n", indent, match_len); printf ("%s*_pmatch_len = %d;\n", indent, match_len);
...@@ -2089,7 +2202,7 @@ write_tree_1 (struct decision_head *head, int depth, ...@@ -2089,7 +2202,7 @@ write_tree_1 (struct decision_head *head, int depth,
position at the node that branched to this node. */ position at the node that branched to this node. */
static void static void
write_tree (struct decision_head *head, const char *prevpos, write_tree (struct decision_head *head, struct position *prevpos,
enum routine_type type, int initial) enum routine_type type, int initial)
{ {
struct decision *p = head->first; struct decision *p = head->first;
...@@ -2131,10 +2244,8 @@ write_tree (struct decision_head *head, const char *prevpos, ...@@ -2131,10 +2244,8 @@ write_tree (struct decision_head *head, const char *prevpos,
} }
else else
{ {
int depth = strlen (p->position);
change_state (prevpos, p->position, " "); change_state (prevpos, p->position, " ");
write_tree_1 (head, depth, type); write_tree_1 (head, p->position->depth, type);
for (p = head->first; p; p = p->next) for (p = head->first; p; p = p->next)
if (p->success.first) if (p->success.first)
...@@ -2190,7 +2301,7 @@ peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pma ...@@ -2190,7 +2301,7 @@ peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pma
printf (" recog_data.insn = NULL_RTX;\n"); printf (" recog_data.insn = NULL_RTX;\n");
if (head->first) if (head->first)
write_tree (head, "", type, 1); write_tree (head, &root_pos, type, 1);
else else
printf (" goto ret0;\n"); printf (" goto ret0;\n");
...@@ -2287,12 +2398,12 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2287,12 +2398,12 @@ make_insn_sequence (rtx insn, enum routine_type type)
struct decision *last; struct decision *last;
struct decision_test *test, **place; struct decision_test *test, **place;
struct decision_head head; struct decision_head head;
char c_test_pos[2]; struct position *c_test_pos, **pos_ptr;
/* We should never see an insn whose C test is false at compile time. */ /* We should never see an insn whose C test is false at compile time. */
gcc_assert (truth); gcc_assert (truth);
c_test_pos[0] = '\0'; c_test_pos = &root_pos;
if (type == PEEPHOLE2) if (type == PEEPHOLE2)
{ {
int i, j; int i, j;
...@@ -2304,19 +2415,20 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2304,19 +2415,20 @@ make_insn_sequence (rtx insn, enum routine_type type)
x = rtx_alloc (PARALLEL); x = rtx_alloc (PARALLEL);
PUT_MODE (x, VOIDmode); PUT_MODE (x, VOIDmode);
XVEC (x, 0) = rtvec_alloc (XVECLEN (insn, 0)); XVEC (x, 0) = rtvec_alloc (XVECLEN (insn, 0));
pos_ptr = &peep2_insn_pos_list;
for (i = j = 0; i < XVECLEN (insn, 0); i++) for (i = j = 0; i < XVECLEN (insn, 0); i++)
{ {
rtx tmp = XVECEXP (insn, 0, i); rtx tmp = XVECEXP (insn, 0, i);
if (GET_CODE (tmp) != MATCH_SCRATCH && GET_CODE (tmp) != MATCH_DUP) if (GET_CODE (tmp) != MATCH_SCRATCH && GET_CODE (tmp) != MATCH_DUP)
{ {
c_test_pos = next_position (pos_ptr, &root_pos,
POS_PEEP2_INSN, i);
XVECEXP (x, 0, j) = tmp; XVECEXP (x, 0, j) = tmp;
j++; j++;
pos_ptr = &c_test_pos->next;
} }
} }
XVECLEN (x, 0) = j; XVECLEN (x, 0) = j;
c_test_pos[0] = 'A' + j - 1;
c_test_pos[1] = '\0';
} }
else if (XVECLEN (insn, type == RECOG) == 1) else if (XVECLEN (insn, type == RECOG) == 1)
x = XVECEXP (insn, type == RECOG, 0); x = XVECEXP (insn, type == RECOG, 0);
...@@ -2330,7 +2442,7 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2330,7 +2442,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
validate_pattern (x, insn, NULL_RTX, 0); validate_pattern (x, insn, NULL_RTX, 0);
memset(&head, 0, sizeof(head)); memset(&head, 0, sizeof(head));
last = add_to_sequence (x, &head, "", type, 1); last = add_to_sequence (x, &head, &root_pos, type, 1);
/* Find the end of the test chain on the last node. */ /* Find the end of the test chain on the last node. */
for (test = last->tests; test->next; test = test->next) for (test = last->tests; test->next; test = test->next)
...@@ -2396,7 +2508,8 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2396,7 +2508,8 @@ make_insn_sequence (rtx insn, enum routine_type type)
/* Recognize it. */ /* Recognize it. */
memset (&clobber_head, 0, sizeof(clobber_head)); memset (&clobber_head, 0, sizeof(clobber_head));
last = add_to_sequence (new_rtx, &clobber_head, "", type, 1); last = add_to_sequence (new_rtx, &clobber_head, &root_pos,
type, 1);
/* Find the end of the test chain on the last node. */ /* Find the end of the test chain on the last node. */
for (test = last->tests; test->next; test = test->next) for (test = last->tests; test->next; test = test->next)
...@@ -2407,7 +2520,7 @@ make_insn_sequence (rtx insn, enum routine_type type) ...@@ -2407,7 +2520,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
place = &test->next; place = &test->next;
if (test->type == DT_accept_op) if (test->type == DT_accept_op)
{ {
last = new_decision ("", &last->success); last = new_decision (&root_pos, &last->success);
place = &last->tests; place = &last->tests;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment