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
This commit is contained in:
parent
f256f612d4
commit
6a1a787e41
@ -1,3 +1,17 @@
|
||||
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>
|
||||
|
||||
* tree.c (initialize_tree_contains_struct): Mark TS_BLOCK as
|
||||
|
267
gcc/genrecog.c
267
gcc/genrecog.c
@ -62,6 +62,49 @@
|
||||
#define OUTPUT_LABEL(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
|
||||
in a doubly-linked list so we can easily add nodes to the proper
|
||||
place when merging. */
|
||||
@ -132,7 +175,7 @@ struct decision
|
||||
struct decision *afterward; /* Node to test on success,
|
||||
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. */
|
||||
|
||||
@ -170,9 +213,16 @@ static int max_depth;
|
||||
|
||||
/* The line number of the start of the pattern currently being processed. */
|
||||
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
|
||||
(const char *, struct decision_head *);
|
||||
(struct position *, struct decision_head *);
|
||||
static struct decision_test *new_decision_test
|
||||
(enum decision_type, struct decision_test ***);
|
||||
static rtx find_operand
|
||||
@ -182,7 +232,7 @@ static rtx find_matching_operand
|
||||
static void validate_pattern
|
||||
(rtx, rtx, rtx, int);
|
||||
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
|
||||
(struct decision_test *, struct decision_test *);
|
||||
@ -210,7 +260,7 @@ static void find_afterward
|
||||
(struct decision_head *, struct decision *);
|
||||
|
||||
static void change_state
|
||||
(const char *, const char *, const char *);
|
||||
(struct position *, struct position *, const char *);
|
||||
static void print_code
|
||||
(enum rtx_code);
|
||||
static void write_afterward
|
||||
@ -229,7 +279,7 @@ static int write_node
|
||||
static void write_tree_1
|
||||
(struct decision_head *, int, enum routine_type);
|
||||
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
|
||||
(struct decision_head *, enum routine_type);
|
||||
static void write_subroutines
|
||||
@ -253,15 +303,66 @@ extern void debug_decision
|
||||
extern void debug_decision_list
|
||||
(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. */
|
||||
|
||||
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);
|
||||
|
||||
new_decision->success = *last;
|
||||
new_decision->position = xstrdup (position);
|
||||
new_decision->position = pos;
|
||||
new_decision->number = next_number++;
|
||||
|
||||
last->first = last->last = new_decision;
|
||||
@ -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
|
||||
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.
|
||||
|
||||
A pointer to the final node in the chain is returned. */
|
||||
|
||||
static struct decision *
|
||||
add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
||||
enum routine_type insn_type, int top)
|
||||
add_to_sequence (rtx pattern, struct decision_head *last,
|
||||
struct position *pos, enum routine_type insn_type, int top)
|
||||
{
|
||||
RTX_CODE code;
|
||||
struct decision *this_decision, *sub;
|
||||
struct decision_test *test;
|
||||
struct decision_test **place;
|
||||
char *subpos;
|
||||
struct position *subpos, **subpos_ptr;
|
||||
size_t i;
|
||||
const char *fmt;
|
||||
int depth = strlen (position);
|
||||
int len;
|
||||
enum machine_mode mode;
|
||||
enum position_type pos_type;
|
||||
|
||||
if (depth > max_depth)
|
||||
max_depth = depth;
|
||||
if (pos->depth > max_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;
|
||||
|
||||
restart:
|
||||
@ -694,15 +791,15 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
||||
last->first = last->last = NULL;
|
||||
}
|
||||
|
||||
subpos_ptr = &peep2_insn_pos_list;
|
||||
for (i = 0; i < (size_t) XVECLEN (pattern, 0); i++)
|
||||
{
|
||||
/* Which insn we're looking at is represented by A-Z. We don't
|
||||
ever use 'A', however; it is always implied. */
|
||||
|
||||
subpos[depth] = (i > 0 ? 'A' + i : 0);
|
||||
subpos = next_position (subpos_ptr, &root_pos,
|
||||
POS_PEEP2_INSN, i);
|
||||
sub = add_to_sequence (XVECEXP (pattern, 0, i),
|
||||
last, subpos, insn_type, 0);
|
||||
last = &sub->success;
|
||||
subpos_ptr = &subpos->next;
|
||||
}
|
||||
goto ret;
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
subpos[depth] = i + base;
|
||||
subpos = next_position (subpos_ptr, pos, pos_type, i);
|
||||
sub = add_to_sequence (XVECEXP (pattern, 2, i),
|
||||
&sub->success, subpos, insn_type, 0);
|
||||
subpos_ptr = &subpos->next;
|
||||
}
|
||||
}
|
||||
goto fini;
|
||||
@ -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->u.opno = XINT (pattern, 0);
|
||||
|
||||
subpos_ptr = &pos->xvecexp0s;
|
||||
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->success, subpos, insn_type, 0);
|
||||
subpos_ptr = &subpos->next;
|
||||
}
|
||||
goto fini;
|
||||
|
||||
@ -874,24 +983,29 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
||||
}
|
||||
|
||||
/* Now test our sub-patterns. */
|
||||
subpos_ptr = &pos->xexps;
|
||||
for (i = 0; i < (size_t) len; i++)
|
||||
{
|
||||
subpos = next_position (subpos_ptr, pos, POS_XEXP, i);
|
||||
switch (fmt[i])
|
||||
{
|
||||
case 'e': case 'u':
|
||||
subpos[depth] = '0' + i;
|
||||
sub = add_to_sequence (XEXP (pattern, i), &sub->success,
|
||||
subpos, insn_type, 0);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
{
|
||||
struct position *subpos2, **subpos2_ptr;
|
||||
int j;
|
||||
|
||||
subpos2_ptr = &pos->xvecexp0s;
|
||||
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->success, subpos, insn_type, 0);
|
||||
&sub->success, subpos2, insn_type, 0);
|
||||
subpos2_ptr = &subpos2->next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -905,6 +1019,7 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
subpos_ptr = &subpos->next;
|
||||
}
|
||||
|
||||
fini:
|
||||
@ -928,7 +1043,6 @@ add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
|
||||
gcc_assert (this_decision->tests);
|
||||
|
||||
ret:
|
||||
free (subpos);
|
||||
return sub;
|
||||
}
|
||||
|
||||
@ -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).
|
||||
Skip forward until we come to a position that matches.
|
||||
|
||||
Due to the way position strings are constructed, we know that iterating
|
||||
forward from the lexically lower position (e.g. "00") will run into
|
||||
the lexically higher position (e.g. "1") and not the other way around.
|
||||
This saves a bit of effort. */
|
||||
Due to the way positions are constructed, we know that iterating
|
||||
forward from the lexically lower position will run into the lexically
|
||||
higher position and not the other way around. This saves a bit
|
||||
of effort. */
|
||||
|
||||
cmp = strcmp (d1->position, d2->position);
|
||||
cmp = compare_positions (d1->position, d2->position);
|
||||
if (cmp != 0)
|
||||
{
|
||||
gcc_assert (!toplevel);
|
||||
@ -1214,7 +1328,7 @@ nodes_identical (struct decision *d1, struct decision *d2)
|
||||
invoked. */
|
||||
if (d1->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 1;
|
||||
@ -1284,7 +1398,7 @@ merge_trees (struct decision_head *oldh, struct decision_head *addh)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@ -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. */
|
||||
|
||||
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);
|
||||
int ndepth = strlen (newpos);
|
||||
int depth;
|
||||
while (oldpos->depth > newpos->depth)
|
||||
oldpos = oldpos->base;
|
||||
|
||||
/* Pop up as many levels as necessary. */
|
||||
for (depth = odepth; strncmp (oldpos, newpos, depth) != 0; --depth)
|
||||
continue;
|
||||
if (oldpos != newpos)
|
||||
switch (newpos->type)
|
||||
{
|
||||
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. */
|
||||
while (depth < ndepth)
|
||||
{
|
||||
/* It's a different insn from the first one. */
|
||||
if (ISUPPER (newpos[depth]))
|
||||
{
|
||||
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]))
|
||||
case POS_XEXP:
|
||||
change_state (oldpos, newpos->base, indent);
|
||||
printf ("%sx%d = XEXP (x%d, %d);\n",
|
||||
indent, newpos->depth, newpos->depth - 1, newpos->arg);
|
||||
break;
|
||||
|
||||
case POS_XVECEXP0:
|
||||
change_state (oldpos, newpos->base, indent);
|
||||
printf ("%sx%d = XVECEXP (x%d, 0, %d);\n",
|
||||
indent, depth + 1, depth, newpos[depth] - 'a');
|
||||
else
|
||||
printf ("%sx%d = XEXP (x%d, %c);\n",
|
||||
indent, depth + 1, depth, newpos[depth]);
|
||||
++depth;
|
||||
indent, newpos->depth, newpos->depth - 1, newpos->arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1942,12 +2054,13 @@ write_action (struct decision *p, struct decision_test *test,
|
||||
|
||||
case PEEPHOLE2:
|
||||
{
|
||||
int match_len = 0, i;
|
||||
int match_len = 0;
|
||||
struct position *pos;
|
||||
|
||||
for (i = strlen (p->position) - 1; i >= 0; --i)
|
||||
if (ISUPPER (p->position[i]))
|
||||
for (pos = p->position; pos; pos = pos->base)
|
||||
if (pos->type == POS_PEEP2_INSN)
|
||||
{
|
||||
match_len = p->position[i] - 'A';
|
||||
match_len = pos->arg;
|
||||
break;
|
||||
}
|
||||
printf ("%s*_pmatch_len = %d;\n", indent, match_len);
|
||||
@ -2089,7 +2202,7 @@ write_tree_1 (struct decision_head *head, int depth,
|
||||
position at the node that branched to this node. */
|
||||
|
||||
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)
|
||||
{
|
||||
struct decision *p = head->first;
|
||||
@ -2131,10 +2244,8 @@ write_tree (struct decision_head *head, const char *prevpos,
|
||||
}
|
||||
else
|
||||
{
|
||||
int depth = strlen (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)
|
||||
if (p->success.first)
|
||||
@ -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");
|
||||
|
||||
if (head->first)
|
||||
write_tree (head, "", type, 1);
|
||||
write_tree (head, &root_pos, type, 1);
|
||||
else
|
||||
printf (" goto ret0;\n");
|
||||
|
||||
@ -2287,12 +2398,12 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
struct decision *last;
|
||||
struct decision_test *test, **place;
|
||||
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. */
|
||||
gcc_assert (truth);
|
||||
|
||||
c_test_pos[0] = '\0';
|
||||
c_test_pos = &root_pos;
|
||||
if (type == PEEPHOLE2)
|
||||
{
|
||||
int i, j;
|
||||
@ -2304,19 +2415,20 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
x = rtx_alloc (PARALLEL);
|
||||
PUT_MODE (x, VOIDmode);
|
||||
XVEC (x, 0) = rtvec_alloc (XVECLEN (insn, 0));
|
||||
pos_ptr = &peep2_insn_pos_list;
|
||||
for (i = j = 0; i < XVECLEN (insn, 0); i++)
|
||||
{
|
||||
rtx tmp = XVECEXP (insn, 0, i);
|
||||
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;
|
||||
j++;
|
||||
pos_ptr = &c_test_pos->next;
|
||||
}
|
||||
}
|
||||
XVECLEN (x, 0) = j;
|
||||
|
||||
c_test_pos[0] = 'A' + j - 1;
|
||||
c_test_pos[1] = '\0';
|
||||
}
|
||||
else if (XVECLEN (insn, type == RECOG) == 1)
|
||||
x = XVECEXP (insn, type == RECOG, 0);
|
||||
@ -2330,7 +2442,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
validate_pattern (x, insn, NULL_RTX, 0);
|
||||
|
||||
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. */
|
||||
for (test = last->tests; test->next; test = test->next)
|
||||
@ -2396,7 +2508,8 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
|
||||
/* Recognize it. */
|
||||
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. */
|
||||
for (test = last->tests; test->next; test = test->next)
|
||||
@ -2407,7 +2520,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
|
||||
place = &test->next;
|
||||
if (test->type == DT_accept_op)
|
||||
{
|
||||
last = new_decision ("", &last->success);
|
||||
last = new_decision (&root_pos, &last->success);
|
||||
place = &last->tests;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user