diff options
author | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-01 16:58:11 +0000 |
---|---|---|
committer | aoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-03-01 16:58:11 +0000 |
commit | 85b6e75b288bff150dada22c0980082006f9d1e0 (patch) | |
tree | c2c1bae2d077b418073a5806f3512ee632e4b466 /gcc/alias.c | |
parent | ff560cc5e32f84a599cc111b8dc4c66b1082b1ca (diff) | |
download | gcc-85b6e75b288bff150dada22c0980082006f9d1e0.tar.gz |
PR debug/52001
PR rtl-optimization/52417
* cselib.c (cselib_any_perm_equivs): New variable.
(cselib_reset_table): Check that it's not set when not
preserving constants.
(cselib_add_permanent_equiv): Set it.
(cselib_have_permanent_equivalences): New.
(cselib_init, cselib_finish): Reset it.
* cselib.h (cselib_have_permanent_equivalences): Declare.
* alias.c (get_addr): Restore earlier behavior when there
aren't permanent equivalences.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184750 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index 4bda40d8836..e9d701f9636 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1811,20 +1811,34 @@ get_addr (rtx x) v = CSELIB_VAL_PTR (x); if (v) { - v = canonical_cselib_val (v); + bool have_equivs = cselib_have_permanent_equivalences (); + if (have_equivs) + 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) && GET_CODE (l->loc) != VALUE - && !refs_newer_value_p (l->loc, x)) + if (!REG_P (l->loc) && !MEM_P (l->loc) + /* Avoid infinite recursion when potentially dealing with + var-tracking artificial equivalences, by skipping the + equivalences themselves, and not choosing expressions + that refer to newer VALUEs. */ + && (!have_equivs + || (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; - /* Return the canonical value. */ - return v->val_rtx; + if (have_equivs) + { + 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; + } + if (v->locs) + return v->locs->loc; } return x; } |