diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-25 12:09:41 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-25 12:09:41 +0000 |
commit | fa5e407e24409416e0baa60e5c6227fa297f736a (patch) | |
tree | 7bde4a2ac693ba3d3312bb5937c7160118e45921 /gcc/alias.c | |
parent | 0be329eff8728d984adb170591e01cd499de7a36 (diff) | |
download | gcc-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.c | 41 |
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) |