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
This commit is contained in:
parent
0e22465644
commit
a562837816
2 changed files with 43 additions and 5 deletions
|
@ -1,5 +1,12 @@
|
|||
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...
|
||||
|
|
41
gcc/alias.c
41
gcc/alias.c
|
@ -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;
|
||||
if (v->locs)
|
||||
return v->locs->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;
|
||||
/* 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)
|
||||
|
|
Loading…
Add table
Reference in a new issue