diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2012-03-01 16:58:11 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2012-03-01 16:58:11 +0000 |
commit | 0f68ba3ea390e3b71320cc3bf70deedbb9534223 (patch) | |
tree | c2c1bae2d077b418073a5806f3512ee632e4b466 | |
parent | 2aceddd8fc0fa80fffd5a6eca0745895b95011e1 (diff) | |
download | gcc-0f68ba3ea390e3b71320cc3bf70deedbb9534223.zip gcc-0f68ba3ea390e3b71320cc3bf70deedbb9534223.tar.gz gcc-0f68ba3ea390e3b71320cc3bf70deedbb9534223.tar.bz2 |
re PR debug/52001 (Huge compile-time regression with var-tracking)
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.
From-SVN: r184750
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/alias.c | 32 | ||||
-rw-r--r-- | gcc/cselib.c | 18 | ||||
-rw-r--r-- | gcc/cselib.h | 1 |
4 files changed, 55 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c18b261..805e359 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2012-03-01 Alexandre Oliva <aoliva@redhat.com> + + 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. + 2012-03-01 Steven Bosscher <steven@gcc.gnu.org> * config/mn10300/mn10300-modes.def: Fix copyright notice. diff --git a/gcc/alias.c b/gcc/alias.c index 4bda40d..e9d701f 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; } diff --git a/gcc/cselib.c b/gcc/cselib.c index 4985357..56f2b7f 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -52,6 +52,7 @@ struct elt_list { static bool cselib_record_memory; static bool cselib_preserve_constants; +static bool cselib_any_perm_equivs; static int entry_and_rtx_equal_p (const void *, const void *); static hashval_t get_value_hash (const void *); static struct elt_list *new_elt_list (struct elt_list *, cselib_val *); @@ -477,7 +478,10 @@ cselib_reset_table (unsigned int num) if (cselib_preserve_constants) htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL); else - htab_empty (cselib_hash_table); + { + htab_empty (cselib_hash_table); + gcc_checking_assert (!cselib_any_perm_equivs); + } n_useless_values = 0; n_useless_debug_values = 0; @@ -2388,6 +2392,8 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn) if (nelt != elt) { + cselib_any_perm_equivs = true; + if (!PRESERVED_VALUE_P (nelt->val_rtx)) cselib_preserve_value (nelt); @@ -2397,6 +2403,14 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn) cselib_current_insn = save_cselib_current_insn; } +/* Return TRUE if any permanent equivalences have been recorded since + the table was last initialized. */ +bool +cselib_have_permanent_equivalences (void) +{ + return cselib_any_perm_equivs; +} + /* There is no good way to determine how many elements there can be in a PARALLEL. Since it's fairly cheap, use a really large number. */ #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) @@ -2651,6 +2665,7 @@ cselib_init (int record_what) value_pool = create_alloc_pool ("value", RTX_CODE_SIZE (VALUE), 100); cselib_record_memory = record_what & CSELIB_RECORD_MEMORY; cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS; + cselib_any_perm_equivs = false; /* (mem:BLK (scratch)) is a special mechanism to conflict with everything, see canon_true_dependence. This is only created once. */ @@ -2684,6 +2699,7 @@ cselib_finish (void) { cselib_discard_hook = NULL; cselib_preserve_constants = false; + cselib_any_perm_equivs = false; cfa_base_preserved_val = NULL; cfa_base_preserved_regno = INVALID_REGNUM; free_alloc_pool (elt_list_pool); diff --git a/gcc/cselib.h b/gcc/cselib.h index 5b5fe23..96575f9 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -98,6 +98,7 @@ extern bool cselib_preserved_value_p (cselib_val *); extern void cselib_preserve_only_values (void); extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int); extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx); +extern bool cselib_have_permanent_equivalences (void); extern void dump_cselib_table (FILE *); |