diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2010-03-18 20:16:48 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-03-18 21:16:48 +0100 |
commit | e999b0c986e49756090018ec7187f2b8b21985c7 (patch) | |
tree | b91b7524e4a0f89e9def1e74be1352bc81093cc0 /gcc | |
parent | 5644a3d0e39e5705bbf8bba5ff59f8ae336830d9 (diff) | |
download | gcc-e999b0c986e49756090018ec7187f2b8b21985c7.zip gcc-e999b0c986e49756090018ec7187f2b8b21985c7.tar.gz gcc-e999b0c986e49756090018ec7187f2b8b21985c7.tar.bz2 |
re PR debug/42873 (deadlock in var tracking in recent builds)
PR debug/42873
* var-tracking.c (canonicalize_vars_star): New.
(dataflow_post_merge_adjust): Use it.
From-SVN: r157548
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/var-tracking.c | 62 |
2 files changed, 68 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26d70d1..3e74d3f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-03-18 Alexandre Oliva <aoliva@redhat.com> + + PR debug/42873 + * var-tracking.c (canonicalize_vars_star): New. + (dataflow_post_merge_adjust): Use it. + 2010-03-18 Jakub Jelinek <jakub@redhat.com> PR debug/43058 diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 8b4f2f3..12286ec 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -3168,6 +3168,67 @@ canonicalize_values_star (void **slot, void *data) return 1; } +/* Bind one-part variables to the canonical value in an equivalence + set. Not doing this causes dataflow convergence failure in rare + circumstances, see PR42873. Unfortunately we can't do this + efficiently as part of canonicalize_values_star, since we may not + have determined or even seen the canonical value of a set when we + get to a variable that references another member of the set. */ + +static int +canonicalize_vars_star (void **slot, void *data) +{ + dataflow_set *set = (dataflow_set *)data; + variable var = (variable) *slot; + decl_or_value dv = var->dv; + location_chain node; + rtx cval; + decl_or_value cdv; + void **cslot; + variable cvar; + location_chain cnode; + + if (!dv_onepart_p (dv) || dv_is_value_p (dv)) + return 1; + + gcc_assert (var->n_var_parts == 1); + + node = var->var_part[0].loc_chain; + + if (GET_CODE (node->loc) != VALUE) + return 1; + + gcc_assert (!node->next); + cval = node->loc; + + /* Push values to the canonical one. */ + cdv = dv_from_value (cval); + cslot = shared_hash_find_slot_noinsert (set->vars, cdv); + if (!cslot) + return 1; + cvar = (variable)*cslot; + gcc_assert (cvar->n_var_parts == 1); + + cnode = cvar->var_part[0].loc_chain; + + /* CVAL is canonical if its value list contains non-VALUEs or VALUEs + that are not “more canonical” than it. */ + if (GET_CODE (cnode->loc) != VALUE + || !canon_value_cmp (cnode->loc, cval)) + return 1; + + /* CVAL was found to be non-canonical. Change the variable to point + to the canonical VALUE. */ + gcc_assert (!cnode->next); + cval = cnode->loc; + + slot = set_slot_part (set, cval, slot, dv, 0, + node->init, node->set_src); + slot = clobber_slot_part (set, cval, slot, 0, node->set_src); + + return 1; +} + /* Combine variable or value in *S1SLOT (in DSM->cur) with the corresponding entry in DSM->src. Multi-part variables are combined with variable_union, whereas onepart dvs are combined with @@ -3830,6 +3891,7 @@ dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp) htab_traverse (shared_hash_htab ((*permp)->vars), variable_post_merge_perm_vals, &dfpm); htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set); + htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set); } /* Return a node whose loc is a MEM that refers to EXPR in the |