summaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-25 12:09:41 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-25 12:09:41 +0000
commitfa5e407e24409416e0baa60e5c6227fa297f736a (patch)
tree7bde4a2ac693ba3d3312bb5937c7160118e45921 /gcc/alias.c
parent0be329eff8728d984adb170591e01cd499de7a36 (diff)
downloadgcc-fa5e407e24409416e0baa60e5c6227fa297f736a.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184572 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index b9b9676b173..4bda40d8836 100644
--- a/gcc/alias.c
+++ b/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;
+ 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)