aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2010-03-18 20:16:48 +0000
committerJakub Jelinek <jakub@gcc.gnu.org>2010-03-18 21:16:48 +0100
commite999b0c986e49756090018ec7187f2b8b21985c7 (patch)
treeb91b7524e4a0f89e9def1e74be1352bc81093cc0 /gcc
parent5644a3d0e39e5705bbf8bba5ff59f8ae336830d9 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/var-tracking.c62
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