Commit 0f68ba3e by Alexandre Oliva Committed by Alexandre Oliva

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
parent 2aceddd8
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> 2012-03-01 Steven Bosscher <steven@gcc.gnu.org>
* config/mn10300/mn10300-modes.def: Fix copyright notice. * config/mn10300/mn10300-modes.def: Fix copyright notice.
......
...@@ -1811,20 +1811,34 @@ get_addr (rtx x) ...@@ -1811,20 +1811,34 @@ get_addr (rtx x)
v = CSELIB_VAL_PTR (x); v = CSELIB_VAL_PTR (x);
if (v) 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) for (l = v->locs; l; l = l->next)
if (CONSTANT_P (l->loc)) if (CONSTANT_P (l->loc))
return l->loc; return l->loc;
for (l = v->locs; l; l = l->next) for (l = v->locs; l; l = l->next)
if (!REG_P (l->loc) && !MEM_P (l->loc) && GET_CODE (l->loc) != VALUE if (!REG_P (l->loc) && !MEM_P (l->loc)
&& !refs_newer_value_p (l->loc, x)) /* 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; return l->loc;
for (l = v->locs; l; l = l->next) if (have_equivs)
if (REG_P (l->loc) || (GET_CODE (l->loc) != VALUE {
&& !refs_newer_value_p (l->loc, x))) for (l = v->locs; l; l = l->next)
return l->loc; if (REG_P (l->loc)
/* Return the canonical value. */ || (GET_CODE (l->loc) != VALUE
return v->val_rtx; && !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; return x;
} }
......
...@@ -52,6 +52,7 @@ struct elt_list { ...@@ -52,6 +52,7 @@ struct elt_list {
static bool cselib_record_memory; static bool cselib_record_memory;
static bool cselib_preserve_constants; static bool cselib_preserve_constants;
static bool cselib_any_perm_equivs;
static int entry_and_rtx_equal_p (const void *, const void *); static int entry_and_rtx_equal_p (const void *, const void *);
static hashval_t get_value_hash (const void *); static hashval_t get_value_hash (const void *);
static struct elt_list *new_elt_list (struct elt_list *, cselib_val *); static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
...@@ -477,7 +478,10 @@ cselib_reset_table (unsigned int num) ...@@ -477,7 +478,10 @@ cselib_reset_table (unsigned int num)
if (cselib_preserve_constants) if (cselib_preserve_constants)
htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL); htab_traverse (cselib_hash_table, preserve_constants_and_equivs, NULL);
else else
htab_empty (cselib_hash_table); {
htab_empty (cselib_hash_table);
gcc_checking_assert (!cselib_any_perm_equivs);
}
n_useless_values = 0; n_useless_values = 0;
n_useless_debug_values = 0; n_useless_debug_values = 0;
...@@ -2388,6 +2392,8 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn) ...@@ -2388,6 +2392,8 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn)
if (nelt != elt) if (nelt != elt)
{ {
cselib_any_perm_equivs = true;
if (!PRESERVED_VALUE_P (nelt->val_rtx)) if (!PRESERVED_VALUE_P (nelt->val_rtx))
cselib_preserve_value (nelt); cselib_preserve_value (nelt);
...@@ -2397,6 +2403,14 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn) ...@@ -2397,6 +2403,14 @@ cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx insn)
cselib_current_insn = save_cselib_current_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 /* 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. */ in a PARALLEL. Since it's fairly cheap, use a really large number. */
#define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2)
...@@ -2651,6 +2665,7 @@ cselib_init (int record_what) ...@@ -2651,6 +2665,7 @@ cselib_init (int record_what)
value_pool = create_alloc_pool ("value", RTX_CODE_SIZE (VALUE), 100); value_pool = create_alloc_pool ("value", RTX_CODE_SIZE (VALUE), 100);
cselib_record_memory = record_what & CSELIB_RECORD_MEMORY; cselib_record_memory = record_what & CSELIB_RECORD_MEMORY;
cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS; cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS;
cselib_any_perm_equivs = false;
/* (mem:BLK (scratch)) is a special mechanism to conflict with everything, /* (mem:BLK (scratch)) is a special mechanism to conflict with everything,
see canon_true_dependence. This is only created once. */ see canon_true_dependence. This is only created once. */
...@@ -2684,6 +2699,7 @@ cselib_finish (void) ...@@ -2684,6 +2699,7 @@ cselib_finish (void)
{ {
cselib_discard_hook = NULL; cselib_discard_hook = NULL;
cselib_preserve_constants = false; cselib_preserve_constants = false;
cselib_any_perm_equivs = false;
cfa_base_preserved_val = NULL; cfa_base_preserved_val = NULL;
cfa_base_preserved_regno = INVALID_REGNUM; cfa_base_preserved_regno = INVALID_REGNUM;
free_alloc_pool (elt_list_pool); free_alloc_pool (elt_list_pool);
......
...@@ -98,6 +98,7 @@ extern bool cselib_preserved_value_p (cselib_val *); ...@@ -98,6 +98,7 @@ extern bool cselib_preserved_value_p (cselib_val *);
extern void cselib_preserve_only_values (void); extern void cselib_preserve_only_values (void);
extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int); extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx); extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx);
extern bool cselib_have_permanent_equivalences (void);
extern void dump_cselib_table (FILE *); extern void dump_cselib_table (FILE *);
......
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