aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2010-06-10 16:43:46 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2010-06-10 16:43:46 +0000
commitb933b33a188f2189d7402ec99c3394615d8519e2 (patch)
treedf4f7344999e19b077da0b07217c6166a9a2402f
parent0c179631b21d149074ed2606201fe0cede6bf412 (diff)
downloadgcc-b933b33a188f2189d7402ec99c3394615d8519e2.zip
gcc-b933b33a188f2189d7402ec99c3394615d8519e2.tar.gz
gcc-b933b33a188f2189d7402ec99c3394615d8519e2.tar.bz2
re PR debug/41371 (var-tracking is slow and memory hungry)
PR debug/41371 * var-tracking.c (find_loc_in_1pdv): Remove recursion, only tail-recurse into canonical node. Fast-forward over non-canonical VALUEs. From-SVN: r160559
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/var-tracking.c112
2 files changed, 44 insertions, 75 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 725a52d..685a346 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-06-10 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/41371
+ * var-tracking.c (find_loc_in_1pdv): Remove recursion, only
+ tail-recurse into canonical node. Fast-forward over
+ non-canonical VALUEs.
+
2010-06-10 H.J. Lu <hongjiu.lu@intel.com>
PR boostrap/44470
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index eb6144f..5740558 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -2479,125 +2479,81 @@ dv_changed_p (decl_or_value dv)
/* Return a location list node whose loc is rtx_equal to LOC, in the
location list of a one-part variable or value VAR, or in that of
- any values recursively mentioned in the location lists. */
+ any values recursively mentioned in the location lists. VARS must
+ be in star-canonical form. */
static location_chain
find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
{
location_chain node;
enum rtx_code loc_code;
- location_chain ret = NULL;
- int unmark_self = 0;
-#ifdef ENABLE_CHECKING
- static int mark_count;
-#endif
if (!var)
- return ret;
+ return NULL;
#ifdef ENABLE_CHECKING
gcc_assert (dv_onepart_p (var->dv));
#endif
if (!var->n_var_parts)
- return ret;
+ return NULL;
#ifdef ENABLE_CHECKING
gcc_assert (var->var_part[0].offset == 0);
+ gcc_assert (loc != dv_as_opaque (var->dv));
#endif
loc_code = GET_CODE (loc);
for (node = var->var_part[0].loc_chain; node; node = node->next)
{
+ decl_or_value dv;
+ variable rvar;
+
if (GET_CODE (node->loc) != loc_code)
{
if (GET_CODE (node->loc) != VALUE)
continue;
}
else if (loc == node->loc)
- {
- ret = node;
- break;
- }
+ return node;
else if (loc_code != VALUE)
{
if (rtx_equal_p (loc, node->loc))
- {
- ret = node;
- break;
- }
+ return node;
continue;
}
- if (!VALUE_RECURSED_INTO (node->loc))
- {
- decl_or_value dv = dv_from_value (node->loc);
- variable rvar = (variable)
- htab_find_with_hash (vars, dv, dv_htab_hash (dv));
- if (rvar)
+ /* Since we're in star-canonical form, we don't need to visit
+ non-canonical nodes: one-part variables and non-canonical
+ values would only point back to the canonical node. */
+ if (dv_is_value_p (var->dv)
+ && !canon_value_cmp (node->loc, dv_as_value (var->dv)))
+ {
+ /* Skip all subsequent VALUEs. */
+ while (node->next && GET_CODE (node->next->loc) == VALUE)
{
- location_chain where;
-
- if (!unmark_self)
- {
- if (dv_is_value_p (var->dv)
- && !VALUE_RECURSED_INTO (dv_as_value (var->dv)))
- {
- unmark_self = 1;
+ node = node->next;
#ifdef ENABLE_CHECKING
- mark_count++;
-#endif
- VALUE_RECURSED_INTO (dv_as_value (var->dv)) = true;
- }
- else
- unmark_self = -1;
- }
-
-#ifdef ENABLE_CHECKING
- mark_count++;
- /* The recursion count is bounded because we're
- searching in a star-canonicalized set, i.e., each
- equivalence set of values is arranged so that the
- canonical value has all locations and equivalent
- values, whereas equivalent values only point back to
- the canonical. So, if we start at the canonical
- value, we'll recurse at most into each sibling, so
- the recurse limit will be 2. If we start at a
- non-canonical value, we'll recurse into the
- canonical, and from there to other siblings, so
- recurse limit will be 3. If we start at a one-part
- variable, we add one level of recursion, but we don't
- count it. */
- gcc_assert (mark_count <= 3);
-#endif
- VALUE_RECURSED_INTO (node->loc) = true;
- if ((where = find_loc_in_1pdv (loc, rvar, vars)))
- {
-#ifdef ENABLE_CHECKING
- mark_count--;
-#endif
- VALUE_RECURSED_INTO (node->loc) = false;
- ret = where;
- break;
- }
- VALUE_RECURSED_INTO (node->loc) = false;
-#ifdef ENABLE_CHECKING
- mark_count--;
+ gcc_assert (!canon_value_cmp (node->loc,
+ dv_as_value (var->dv)));
#endif
+ if (loc == node->loc)
+ return node;
}
+ continue;
}
- }
- if (unmark_self > 0)
- {
- VALUE_RECURSED_INTO (dv_as_value (var->dv)) = false;
#ifdef ENABLE_CHECKING
- mark_count--;
- gcc_assert (mark_count == 0);
+ gcc_assert (node == var->var_part[0].loc_chain);
+ gcc_assert (!node->next);
#endif
+
+ dv = dv_from_value (node->loc);
+ rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ return find_loc_in_1pdv (loc, rvar, vars);
}
- return ret;
+ return NULL;
}
/* Hash table iteration argument passed to variable_merge. */
@@ -4031,6 +3987,12 @@ variable_post_merge_perm_vals (void **pslot, void *info)
var = shared_hash_find (set->vars, dv);
if (var)
{
+ /* Although variable_post_merge_new_vals may have made decls
+ non-star-canonical, values that pre-existed in canonical form
+ remain canonical, and newly-created values reference a single
+ REG, so they are canonical as well. Since VAR has the
+ location list for a VALUE, using find_loc_in_1pdv for it is
+ fine, since VALUEs don't map back to DECLs. */
if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
return 1;
val_reset (set, dv);