summaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-04-06 08:30:52 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-04-06 08:30:52 +0000
commit6ca838330b632ebbe339a65d194afb0d863ddc21 (patch)
tree4dc06620d842bb76804b0257be5eed6e40596bf8 /gcc/alias.c
parent54ebcca7952144986748e819751cce0c6ebba2d2 (diff)
re PR rtl-optimization/85180 (Infinite loop in RTL DSE optimizer)
2018-04-06 Richard Biener <rguenther@suse.de> PR middle-end/85180 * alias.c (find_base_term): New wrapper around find_base_term unwinding CSELIB_VAL_PTR changes. (find_base_term): Do not restore CSELIB_VAL_PTR during the recursion. * gcc.dg/pr85180.c: New testcase. From-SVN: r259166
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index eac36a51519..74032f8503b 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1876,7 +1876,8 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y)
}
static rtx
-find_base_term (rtx x)
+find_base_term (rtx x, vec<std::pair<cselib_val *,
+ struct elt_loc_list *> > &visited_vals)
{
cselib_val *val;
struct elt_loc_list *l, *f;
@@ -1910,7 +1911,7 @@ find_base_term (rtx x)
case POST_DEC:
case PRE_MODIFY:
case POST_MODIFY:
- return find_base_term (XEXP (x, 0));
+ return find_base_term (XEXP (x, 0), visited_vals);
case ZERO_EXTEND:
case SIGN_EXTEND: /* Used for Alpha/NT pointers */
@@ -1921,7 +1922,7 @@ find_base_term (rtx x)
return 0;
{
- rtx temp = find_base_term (XEXP (x, 0));
+ rtx temp = find_base_term (XEXP (x, 0), visited_vals);
if (temp != 0 && CONSTANT_P (temp))
temp = convert_memory_address (Pmode, temp);
@@ -1940,7 +1941,9 @@ find_base_term (rtx x)
return static_reg_base_value[STACK_POINTER_REGNUM];
f = val->locs;
- /* Temporarily reset val->locs to avoid infinite recursion. */
+ /* Reset val->locs to avoid infinite recursion. */
+ if (f)
+ visited_vals.safe_push (std::make_pair (val, f));
val->locs = NULL;
for (l = f; l; l = l->next)
@@ -1949,16 +1952,15 @@ find_base_term (rtx x)
&& !CSELIB_VAL_PTR (l->loc)->locs->next
&& CSELIB_VAL_PTR (l->loc)->locs->loc == x)
continue;
- else if ((ret = find_base_term (l->loc)) != 0)
+ else if ((ret = find_base_term (l->loc, visited_vals)) != 0)
break;
- val->locs = f;
return ret;
case LO_SUM:
/* The standard form is (lo_sum reg sym) so look only at the
second operand. */
- return find_base_term (XEXP (x, 1));
+ return find_base_term (XEXP (x, 1), visited_vals);
case CONST:
x = XEXP (x, 0);
@@ -1984,7 +1986,7 @@ find_base_term (rtx x)
other operand is the base register. */
if (tmp1 == pic_offset_table_rtx && CONSTANT_P (tmp2))
- return find_base_term (tmp2);
+ return find_base_term (tmp2, visited_vals);
/* If either operand is known to be a pointer, then prefer it
to determine the base term. */
@@ -2001,12 +2003,12 @@ find_base_term (rtx x)
term is from a pointer or is a named object or a special address
(like an argument or stack reference), then use it for the
base term. */
- rtx base = find_base_term (tmp1);
+ rtx base = find_base_term (tmp1, visited_vals);
if (base != NULL_RTX
&& ((REG_P (tmp1) && REG_POINTER (tmp1))
|| known_base_value_p (base)))
return base;
- base = find_base_term (tmp2);
+ base = find_base_term (tmp2, visited_vals);
if (base != NULL_RTX
&& ((REG_P (tmp2) && REG_POINTER (tmp2))
|| known_base_value_p (base)))
@@ -2020,7 +2022,7 @@ find_base_term (rtx x)
case AND:
if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
- return find_base_term (XEXP (x, 0));
+ return find_base_term (XEXP (x, 0), visited_vals);
return 0;
case SYMBOL_REF:
@@ -2032,6 +2034,19 @@ find_base_term (rtx x)
}
}
+/* Wrapper around the worker above which removes locs from visited VALUEs
+ to avoid visiting them multiple times. We unwind that changes here. */
+
+static rtx
+find_base_term (rtx x)
+{
+ auto_vec<std::pair<cselib_val *, struct elt_loc_list *>, 32> visited_vals;
+ rtx res = find_base_term (x, visited_vals);
+ for (unsigned i = 0; i < visited_vals.length (); ++i)
+ visited_vals[i].first->locs = visited_vals[i].second;
+ return res;
+}
+
/* Return true if accesses to address X may alias accesses based
on the stack pointer. */