Commit a5628378 by Alexandre Oliva Committed by Alexandre Oliva

re PR debug/52001 (Huge compile-time regression with var-tracking)

PR debug/52001
* alias.c (refs_newer_value_cb, refs_newer_value_p): New.
(get_addr): Walk canonical value's locs.  Avoid returning VALUEs
and locs that reference values newer than the non-canonical value
at hand.  Return the canonical value as a worst case.
(memrefs_conflict_p): Walk canonical value's locs.

From-SVN: r184572
parent 0e224656
2012-02-25 Alexandre Oliva <aoliva@redhat.com>
PR debug/52001
* alias.c (refs_newer_value_cb, refs_newer_value_p): New.
(get_addr): Walk canonical value's locs. Avoid returning VALUEs
and locs that reference values newer than the non-canonical value
at hand. Return the canonical value as a worst case.
(memrefs_conflict_p): Walk canonical value's locs.
PR debug/52001
* cselib.c (preserve_only_constants): Rename to...
(preserve_constants_and_equivs): ... this. Split out...
(invariant_or_equiv_p): ... this. Preserve plus expressions
......
......@@ -1773,6 +1773,29 @@ base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
return 1;
}
/* Callback for for_each_rtx, that returns 1 upon encountering a VALUE
whose UID is greater than the int uid that D points to. */
static int
refs_newer_value_cb (rtx *x, void *d)
{
if (GET_CODE (*x) == VALUE && CSELIB_VAL_PTR (*x)->uid > *(int *)d)
return 1;
return 0;
}
/* Return TRUE if EXPR refers to a VALUE whose uid is greater than
that of V. */
static bool
refs_newer_value_p (rtx expr, rtx v)
{
int minuid = CSELIB_VAL_PTR (v)->uid;
return for_each_rtx (&expr, refs_newer_value_cb, &minuid);
}
/* Convert the address X into something we can use. This is done by returning
it unchanged unless it is a value; in the latter case we call cselib to get
a more useful rtx. */
......@@ -1788,14 +1811,20 @@ get_addr (rtx x)
v = CSELIB_VAL_PTR (x);
if (v)
{
v = canonical_cselib_val (v);
for (l = v->locs; l; l = l->next)
if (CONSTANT_P (l->loc))
return l->loc;
for (l = v->locs; l; l = l->next)
if (!REG_P (l->loc) && !MEM_P (l->loc))
if (!REG_P (l->loc) && !MEM_P (l->loc) && GET_CODE (l->loc) != VALUE
&& !refs_newer_value_p (l->loc, x))
return l->loc;
for (l = v->locs; l; l = l->next)
if (REG_P (l->loc) || (GET_CODE (l->loc) != VALUE
&& !refs_newer_value_p (l->loc, x)))
return l->loc;
if (v->locs)
return v->locs->loc;
/* Return the canonical value. */
return v->val_rtx;
}
return x;
}
......@@ -1873,7 +1902,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{
struct elt_loc_list *l = NULL;
if (CSELIB_VAL_PTR (x))
for (l = CSELIB_VAL_PTR (x)->locs; l; l = l->next)
for (l = canonical_cselib_val (CSELIB_VAL_PTR (x))->locs;
l; l = l->next)
if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, y))
break;
if (l)
......@@ -1891,7 +1921,8 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{
struct elt_loc_list *l = NULL;
if (CSELIB_VAL_PTR (y))
for (l = CSELIB_VAL_PTR (y)->locs; l; l = l->next)
for (l = canonical_cselib_val (CSELIB_VAL_PTR (y))->locs;
l; l = l->next)
if (REG_P (l->loc) && rtx_equal_for_memref_p (l->loc, x))
break;
if (l)
......
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