Commit 0e224656 by Alexandre Oliva Committed by Alexandre Oliva

re PR debug/52001 (Huge compile-time regression with var-tracking)

PR debug/52001
* cselib.c (preserve_only_constants): Rename to...
(preserve_constants_and_equivs): ... this.  Split out...
(invariant_or_equiv_p): ... this.  Preserve plus expressions
of other preserved expressions too.
(cselib_reset_table): Adjust.
* var-tracking.c (reverse_op): Use canonical value to build
reverse operation.

From-SVN: r184571
parent 2ef7cdff
2012-02-25 Alexandre Oliva <aoliva@redhat.com>
PR debug/52001
* cselib.c (preserve_only_constants): Rename to...
(preserve_constants_and_equivs): ... this. Split out...
(invariant_or_equiv_p): ... this. Preserve plus expressions
of other preserved expressions too.
(cselib_reset_table): Adjust.
* var-tracking.c (reverse_op): Use canonical value to build
reverse operation.
2012-02-23 Kai Tietz <ktietz@redhat.com> 2012-02-23 Kai Tietz <ktietz@redhat.com>
* config/i386/i386.c (ix86_delegitimize_address): Handle * config/i386/i386.c (ix86_delegitimize_address): Handle
......
...@@ -383,22 +383,29 @@ cselib_clear_table (void) ...@@ -383,22 +383,29 @@ cselib_clear_table (void)
cselib_reset_table (1); cselib_reset_table (1);
} }
/* Remove from hash table all VALUEs except constants /* Return TRUE if V is a constant, a function invariant or a VALUE
and function invariants. */ equivalence; FALSE otherwise. */
static int static bool
preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) invariant_or_equiv_p (cselib_val *v)
{ {
cselib_val *v = (cselib_val *)*x;
struct elt_loc_list *l; struct elt_loc_list *l;
if (v == cfa_base_preserved_val)
return true;
/* Keep VALUE equivalences around. */
for (l = v->locs; l; l = l->next)
if (GET_CODE (l->loc) == VALUE)
return true;
if (v->locs != NULL if (v->locs != NULL
&& v->locs->next == NULL) && v->locs->next == NULL)
{ {
if (CONSTANT_P (v->locs->loc) if (CONSTANT_P (v->locs->loc)
&& (GET_CODE (v->locs->loc) != CONST && (GET_CODE (v->locs->loc) != CONST
|| !references_value_p (v->locs->loc, 0))) || !references_value_p (v->locs->loc, 0)))
return 1; return true;
/* Although a debug expr may be bound to different expressions, /* Although a debug expr may be bound to different expressions,
we can preserve it as if it was constant, to get unification we can preserve it as if it was constant, to get unification
and proper merging within var-tracking. */ and proper merging within var-tracking. */
...@@ -406,23 +413,28 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) ...@@ -406,23 +413,28 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED)
|| GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR || GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR
|| GET_CODE (v->locs->loc) == ENTRY_VALUE || GET_CODE (v->locs->loc) == ENTRY_VALUE
|| GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF) || GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF)
return 1; return true;
if (cfa_base_preserved_val)
{ /* (plus (value V) (const_int C)) is invariant iff V is invariant. */
if (v == cfa_base_preserved_val)
return 1;
if (GET_CODE (v->locs->loc) == PLUS if (GET_CODE (v->locs->loc) == PLUS
&& CONST_INT_P (XEXP (v->locs->loc, 1)) && CONST_INT_P (XEXP (v->locs->loc, 1))
&& XEXP (v->locs->loc, 0) == cfa_base_preserved_val->val_rtx) && GET_CODE (XEXP (v->locs->loc, 0)) == VALUE
return 1; && invariant_or_equiv_p (CSELIB_VAL_PTR (XEXP (v->locs->loc, 0))))
} return true;
} }
/* Keep VALUE equivalences around. */ return false;
for (l = v->locs; l; l = l->next) }
if (GET_CODE (l->loc) == VALUE)
return 1; /* Remove from hash table all VALUEs except constants, function
invariants and VALUE equivalences. */
static int
preserve_constants_and_equivs (void **x, void *info ATTRIBUTE_UNUSED)
{
cselib_val *v = (cselib_val *)*x;
if (!invariant_or_equiv_p (v))
htab_clear_slot (cselib_hash_table, x); htab_clear_slot (cselib_hash_table, x);
return 1; return 1;
} }
...@@ -463,7 +475,7 @@ cselib_reset_table (unsigned int num) ...@@ -463,7 +475,7 @@ cselib_reset_table (unsigned int num)
} }
if (cselib_preserve_constants) if (cselib_preserve_constants)
htab_traverse (cselib_hash_table, preserve_only_constants, NULL); htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL);
else else
htab_empty (cselib_hash_table); htab_empty (cselib_hash_table);
......
...@@ -5334,6 +5334,10 @@ reverse_op (rtx val, const_rtx expr, rtx insn) ...@@ -5334,6 +5334,10 @@ reverse_op (rtx val, const_rtx expr, rtx insn)
if (!v || !cselib_preserved_value_p (v)) if (!v || !cselib_preserved_value_p (v))
return; return;
/* Use canonical V to avoid creating multiple redundant expressions
for different VALUES equivalent to V. */
v = canonical_cselib_val (v);
/* Adding a reverse op isn't useful if V already has an always valid /* Adding a reverse op isn't useful if V already has an always valid
location. Ignore ENTRY_VALUE, while it is always constant, we should location. Ignore ENTRY_VALUE, while it is always constant, we should
prefer non-ENTRY_VALUE locations whenever possible. */ prefer non-ENTRY_VALUE locations whenever possible. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment