Commit 7027f90a by Jim Wilson

(combine_givs): Use new macro GIV_SORT_CRITERION.

New variable giv_array.  Loop over giv_array instead of following
next_iv links.
(giv_sort): New function.
K

From-SVN: r11668
parent bdc49177
...@@ -5580,6 +5580,20 @@ combine_givs_p (g1, g2) ...@@ -5580,6 +5580,20 @@ combine_givs_p (g1, g2)
return 0; return 0;
} }
#ifdef GIV_SORT_CRITERION
/* Compare two givs and sort the most desirable one for combinations first.
This is used only in one qsort call below. */
static int
giv_sort (x, y)
struct induction **x, **y;
{
GIV_SORT_CRITERION (*x, *y);
return 0;
}
#endif
/* Check all pairs of givs for iv_class BL and see if any can be combined with /* Check all pairs of givs for iv_class BL and see if any can be combined with
any other. If so, point SAME to the giv combined with and set NEW_REG to any other. If so, point SAME to the giv combined with and set NEW_REG to
be an expression (in terms of the other giv's DEST_REG) equivalent to the be an expression (in terms of the other giv's DEST_REG) equivalent to the
...@@ -5589,39 +5603,67 @@ static void ...@@ -5589,39 +5603,67 @@ static void
combine_givs (bl) combine_givs (bl)
struct iv_class *bl; struct iv_class *bl;
{ {
struct induction *g1, *g2; struct induction *g1, *g2, **giv_array, *temp_iv;
int pass; int i, j, giv_count, pass;
/* Count givs, because bl->giv_count is incorrect here. */
giv_count = 0;
for (g1 = bl->giv; g1; g1 = g1->next_iv) for (g1 = bl->giv; g1; g1 = g1->next_iv)
for (pass = 0; pass <= 1; pass++) giv_count++;
for (g2 = bl->giv; g2; g2 = g2->next_iv)
if (g1 != g2 giv_array
/* First try to combine with replaceable givs, then all givs. */ = (struct induction **) alloca (giv_count * sizeof (struct induction *));
&& (g1->replaceable || pass == 1) i = 0;
/* If either has already been combined or is to be ignored, can't for (g1 = bl->giv; g1; g1 = g1->next_iv)
combine. */ giv_array[i++] = g1;
&& ! g1->ignore && ! g2->ignore && ! g1->same && ! g2->same
/* If something has been based on G2, G2 cannot itself be based #ifdef GIV_SORT_CRITERION
on something else. */ /* Sort the givs if GIV_SORT_CRITERION is defined.
&& ! g2->combined_with This is usually defined for processors which lack
&& combine_givs_p (g1, g2)) negative register offsets so more givs may be combined. */
if (loop_dump_stream)
fprintf (loop_dump_stream, "%d givs counted, sorting...\n", giv_count);
qsort (giv_array, giv_count, sizeof (struct induction *), giv_sort);
#endif
for (i = 0; i < giv_count; i++)
{
g1 = giv_array[i];
for (pass = 0; pass <= 1; pass++)
for (j = 0; j < giv_count; j++)
{ {
/* g2->new_reg set by `combine_givs_p' */ g2 = giv_array[j];
g2->same = g1; if (g1 != g2
g1->combined_with = 1; /* First try to combine with replaceable givs, then all givs. */
g1->benefit += g2->benefit; && (g1->replaceable || pass == 1)
/* ??? The new final_[bg]iv_value code does a much better job /* If either has already been combined or is to be ignored, can't
of finding replaceable giv's, and hence this code may no combine. */
longer be necessary. */ && ! g1->ignore && ! g2->ignore && ! g1->same && ! g2->same
if (! g2->replaceable && REG_USERVAR_P (g2->dest_reg)) /* If something has been based on G2, G2 cannot itself be based
g1->benefit -= copy_cost; on something else. */
g1->lifetime += g2->lifetime; && ! g2->combined_with
g1->times_used += g2->times_used; && combine_givs_p (g1, g2))
{
if (loop_dump_stream) /* g2->new_reg set by `combine_givs_p' */
fprintf (loop_dump_stream, "giv at %d combined with giv at %d\n", g2->same = g1;
INSN_UID (g2->insn), INSN_UID (g1->insn)); g1->combined_with = 1;
g1->benefit += g2->benefit;
/* ??? The new final_[bg]iv_value code does a much better job
of finding replaceable giv's, and hence this code may no
longer be necessary. */
if (! g2->replaceable && REG_USERVAR_P (g2->dest_reg))
g1->benefit -= copy_cost;
g1->lifetime += g2->lifetime;
g1->times_used += g2->times_used;
if (loop_dump_stream)
fprintf (loop_dump_stream, "giv at %d combined with giv at %d\n",
INSN_UID (g2->insn), INSN_UID (g1->insn));
}
} }
}
} }
/* EMIT code before INSERT_BEFORE to set REG = B * M + A. */ /* EMIT code before INSERT_BEFORE to set REG = B * M + A. */
......
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