From 0e22465644731d86e2d317bf5fbfab2a76eccc9c Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sat, 25 Feb 2012 12:09:27 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 11 +++++++++ gcc/cselib.c | 56 ++++++++++++++++++++++++++++------------------ gcc/var-tracking.c | 4 ++++ 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 121d74a6406..4a2c9fb6c2f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-02-25 Alexandre Oliva + + 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 * config/i386/i386.c (ix86_delegitimize_address): Handle diff --git a/gcc/cselib.c b/gcc/cselib.c index d7cb355fc33..4985357c83a 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -383,22 +383,29 @@ cselib_clear_table (void) cselib_reset_table (1); } -/* Remove from hash table all VALUEs except constants - and function invariants. */ +/* Return TRUE if V is a constant, a function invariant or a VALUE + equivalence; FALSE otherwise. */ -static int -preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) +static bool +invariant_or_equiv_p (cselib_val *v) { - cselib_val *v = (cselib_val *)*x; 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 && v->locs->next == NULL) { if (CONSTANT_P (v->locs->loc) && (GET_CODE (v->locs->loc) != CONST || !references_value_p (v->locs->loc, 0))) - return 1; + return true; /* Although a debug expr may be bound to different expressions, we can preserve it as if it was constant, to get unification and proper merging within var-tracking. */ @@ -406,24 +413,29 @@ preserve_only_constants (void **x, void *info ATTRIBUTE_UNUSED) || GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR || GET_CODE (v->locs->loc) == ENTRY_VALUE || GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF) - return 1; - if (cfa_base_preserved_val) - { - if (v == cfa_base_preserved_val) - return 1; - if (GET_CODE (v->locs->loc) == PLUS - && CONST_INT_P (XEXP (v->locs->loc, 1)) - && XEXP (v->locs->loc, 0) == cfa_base_preserved_val->val_rtx) - return 1; - } + return true; + + /* (plus (value V) (const_int C)) is invariant iff V is invariant. */ + if (GET_CODE (v->locs->loc) == PLUS + && CONST_INT_P (XEXP (v->locs->loc, 1)) + && GET_CODE (XEXP (v->locs->loc, 0)) == VALUE + && invariant_or_equiv_p (CSELIB_VAL_PTR (XEXP (v->locs->loc, 0)))) + return true; } - /* Keep VALUE equivalences around. */ - for (l = v->locs; l; l = l->next) - if (GET_CODE (l->loc) == VALUE) - return 1; + return false; +} + +/* 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; - htab_clear_slot (cselib_hash_table, x); + if (!invariant_or_equiv_p (v)) + htab_clear_slot (cselib_hash_table, x); return 1; } @@ -463,7 +475,7 @@ cselib_reset_table (unsigned int num) } if (cselib_preserve_constants) - htab_traverse (cselib_hash_table, preserve_only_constants, NULL); + htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL); else htab_empty (cselib_hash_table); diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index e9b5ca886ae..c6280e2c1f1 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -5334,6 +5334,10 @@ reverse_op (rtx val, const_rtx expr, rtx insn) if (!v || !cselib_preserved_value_p (v)) 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 location. Ignore ENTRY_VALUE, while it is always constant, we should prefer non-ENTRY_VALUE locations whenever possible. */ -- 2.30.2