aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2012-04-13 15:55:52 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2012-04-13 15:55:52 +0000
commit6a184afa5830e6caccbcc3ef9e4f39d52a095901 (patch)
treeeb26e7096120704d9b8b7d8c18d412e029db4cf9
parentf164e49a3fff54c54055b3be88db64f2ee411a26 (diff)
downloadgcc-6a184afa5830e6caccbcc3ef9e4f39d52a095901.zip
gcc-6a184afa5830e6caccbcc3ef9e4f39d52a095901.tar.gz
gcc-6a184afa5830e6caccbcc3ef9e4f39d52a095901.tar.bz2
re PR debug/51570 (FAIL: gcc.dg/guality/pr45003-[23].c)
PR debug/51570 * var-tracking.c (expand_depth): New type. (onepart_aux, expand_loc_callback_data): Change depth type to it. (loc_exp_dep_alloc): Adjust initializer. (update_depth): Use new type. Add entryvals. (vt_expand_var_loc_chain): Take note of expansions with ENTRY_VALUEs, but don't accept them right away. Run an optional second pass accepting the minimum ENTRY_VALUE count found in the first pass. (vt_expand_loc_callback, INIT_ELCD): Adjust. From-SVN: r186420
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/var-tracking.c86
2 files changed, 80 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 50849efd..1559b9a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2012-04-13 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/51570
+ * var-tracking.c (expand_depth): New type.
+ (onepart_aux, expand_loc_callback_data): Change depth type to it.
+ (loc_exp_dep_alloc): Adjust initializer.
+ (update_depth): Use new type. Add entryvals.
+ (vt_expand_var_loc_chain): Take note of expansions with
+ ENTRY_VALUEs, but don't accept them right away. Run an optional
+ second pass accepting the minimum ENTRY_VALUE count found in the
+ first pass.
+ (vt_expand_loc_callback, INIT_ELCD): Adjust.
+
2012-04-13 Tom de Vries <tom@codesourcery.com>
* tree-ssa-tail-merge.c (gsi_advance_bw_nondebug_nonlocal): Add
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index c6280e2..c3fe428 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -320,6 +320,19 @@ typedef struct loc_exp_dep_s
DEF_VEC_O (loc_exp_dep);
+/* This data structure holds information about the depth of a variable
+ expansion. */
+typedef struct expand_depth_struct
+{
+ /* This measures the complexity of the expanded expression. It
+ grows by one for each level of expansion that adds more than one
+ operand. */
+ int complexity;
+ /* This counts the number of ENTRY_VALUE expressions in an
+ expansion. We want to minimize their use. */
+ int entryvals;
+} expand_depth;
+
/* This data structure is allocated for one-part variables at the time
of emitting notes. */
struct onepart_aux
@@ -338,7 +351,7 @@ struct onepart_aux
a change notification from any of its active dependencies. */
rtx from;
/* The depth of the cur_loc expression. */
- int depth;
+ expand_depth depth;
/* Dependencies actively used when expand FROM into cur_loc. */
VEC (loc_exp_dep, none) deps;
};
@@ -7491,7 +7504,7 @@ struct expand_loc_callback_data
/* The maximum depth among the sub-expressions under expansion.
Zero indicates no expansion so far. */
- int depth;
+ expand_depth depth;
};
/* Allocate the one-part auxiliary data structure for VAR, with enough
@@ -7536,7 +7549,8 @@ loc_exp_dep_alloc (variable var, int count)
VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
*VAR_LOC_DEP_LSTP (var) = NULL;
VAR_LOC_FROM (var) = NULL;
- VAR_LOC_DEPTH (var) = 0;
+ VAR_LOC_DEPTH (var).complexity = 0;
+ VAR_LOC_DEPTH (var).entryvals = 0;
}
VEC_embedded_init (loc_exp_dep, VAR_LOC_DEP_VEC (var), count);
}
@@ -7691,21 +7705,26 @@ static rtx vt_expand_loc_callback (rtx x, bitmap regs,
/* Return the combined depth, when one sub-expression evaluated to
BEST_DEPTH and the previous known depth was SAVED_DEPTH. */
-static inline int
-update_depth (int saved_depth, int best_depth)
+static inline expand_depth
+update_depth (expand_depth saved_depth, expand_depth best_depth)
{
/* If we didn't find anything, stick with what we had. */
- if (!best_depth)
+ if (!best_depth.complexity)
return saved_depth;
/* If we found hadn't found anything, use the depth of the current
expression. Do NOT add one extra level, we want to compute the
maximum depth among sub-expressions. We'll increment it later,
if appropriate. */
- if (!saved_depth)
+ if (!saved_depth.complexity)
return best_depth;
- if (saved_depth < best_depth)
+ /* Combine the entryval count so that regardless of which one we
+ return, the entryval count is accurate. */
+ best_depth.entryvals = saved_depth.entryvals
+ = best_depth.entryvals + saved_depth.entryvals;
+
+ if (saved_depth.complexity < best_depth.complexity)
return best_depth;
else
return saved_depth;
@@ -7727,12 +7746,14 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
bool pending_recursion;
rtx loc_from = NULL;
struct elt_loc_list *cloc = NULL;
- int depth = 0, saved_depth = elcd->depth;
+ expand_depth depth = { 0, 0 }, saved_depth = elcd->depth;
+ int wanted_entryvals, found_entryvals = 0;
/* Clear all backlinks pointing at this, so that we're not notified
while we're active. */
loc_exp_dep_clear (var);
+ retry:
if (var->onepart == ONEPART_VALUE)
{
cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));
@@ -7745,13 +7766,15 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
first_child = result_first_child = last_child
= VEC_length (rtx, elcd->expanding);
+ wanted_entryvals = found_entryvals;
+
/* Attempt to expand each available location in turn. */
for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
loc || cloc; loc = next)
{
result_first_child = last_child;
- if (!loc || (GET_CODE (loc->loc) == ENTRY_VALUE && cloc))
+ if (!loc)
{
loc_from = cloc->loc;
next = loc;
@@ -7767,7 +7790,7 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
gcc_checking_assert (!unsuitable_loc (loc_from));
- elcd->depth = 0;
+ elcd->depth.complexity = elcd->depth.entryvals = 0;
result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
vt_expand_loc_callback, data);
last_child = VEC_length (rtx, elcd->expanding);
@@ -7776,23 +7799,48 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
{
depth = elcd->depth;
- gcc_checking_assert (depth || result_first_child == last_child);
+ gcc_checking_assert (depth.complexity
+ || result_first_child == last_child);
if (last_child - result_first_child != 1)
- depth++;
+ {
+ if (!depth.complexity && GET_CODE (result) == ENTRY_VALUE)
+ depth.entryvals++;
+ depth.complexity++;
+ }
- if (depth <= EXPR_USE_DEPTH)
- break;
+ if (depth.complexity <= EXPR_USE_DEPTH)
+ {
+ if (depth.entryvals <= wanted_entryvals)
+ break;
+ else if (!found_entryvals || depth.entryvals < found_entryvals)
+ found_entryvals = depth.entryvals;
+ }
result = NULL;
}
/* Set it up in case we leave the loop. */
- depth = 0;
+ depth.complexity = depth.entryvals = 0;
loc_from = NULL;
result_first_child = first_child;
}
+ if (!loc_from && wanted_entryvals < found_entryvals)
+ {
+ /* We found entries with ENTRY_VALUEs and skipped them. Since
+ we could not find any expansions without ENTRY_VALUEs, but we
+ found at least one with them, go back and get an entry with
+ the minimum number ENTRY_VALUE count that we found. We could
+ avoid looping, but since each sub-loc is already resolved,
+ the re-expansion should be trivial. ??? Should we record all
+ attempted locs as dependencies, so that we retry the
+ expansion should any of them change, in the hope it can give
+ us a new entry without an ENTRY_VALUE? */
+ VEC_truncate (rtx, elcd->expanding, first_child);
+ goto retry;
+ }
+
/* Register all encountered dependencies as active. */
pending_recursion = loc_exp_dep_set
(var, result, VEC_address (rtx, elcd->expanding) + result_first_child,
@@ -7805,7 +7853,7 @@ vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
VAR_LOC_FROM (var) = loc_from;
VAR_LOC_DEPTH (var) = depth;
- gcc_checking_assert (!depth == !result);
+ gcc_checking_assert (!depth.complexity == !result);
elcd->depth = update_depth (saved_depth, depth);
@@ -7893,7 +7941,7 @@ vt_expand_loc_callback (rtx x, bitmap regs,
gcc_checking_assert (!NO_LOC_P (x));
gcc_checking_assert (var->var_part[0].cur_loc);
gcc_checking_assert (VAR_LOC_1PAUX (var));
- gcc_checking_assert (VAR_LOC_1PAUX (var)->depth);
+ gcc_checking_assert (VAR_LOC_1PAUX (var)->depth.complexity);
elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);
@@ -7967,7 +8015,7 @@ resolve_expansions_pending_recursion (VEC (rtx, stack) *pending)
(d).vars = (v); \
(d).expanding = VEC_alloc (rtx, stack, 4); \
(d).pending = VEC_alloc (rtx, stack, 4); \
- (d).depth = 0; \
+ (d).depth.complexity = (d).depth.entryvals = 0; \
} \
while (0)
/* Finalize expand_loc_callback_data D, resolved to location L. */