re PR debug/43176 (var-tracking fails to notice a value change)
PR debug/43176 * Makefile.in (var-tracking.o): Depend on pointer-set.h. * cselib.c (struct expand_value_data): Add dummy field. (cselib_expand_value_rtx, cselib_expand_value_rtx_cb): Initialize dummy to false. (cselib_dummy_expand_value_rtx_cb): New function. (cselib_expand_value_rtx_1): If evd->dummy is true, don't allocate any rtl. * cselib.h (cselib_dummy_expand_value_rtx_cb): New prototype. * var-tracking.c: Include pointer-set.h. (variable): Change n_var_parts to char from int. Add cur_loc_changed and in_changed_variables fields. (variable_canonicalize): Remove. (shared_var_p): New inline function. (unshare_variable): Maintain cur_loc_changed and in_changed_variables fields. If var was in changed_variables, replace it there with new_var. Just copy cur_loc instead of resetting it to something else. (variable_union): Don't recompute cur_loc. Use shared_var_p. (dataflow_set_union): Don't call variable_canonicalize. (loc_cmp): If both x and y are DEBUG_EXPRs, compare uids of their DEBUG_EXPR_TREE_DECLs. (canonicalize_loc_order_check): Verify that cur_loc is NULL and in_changed_variables and cur_loc_changed is false. (variable_merge_over_cur): Clear cur_loc, in_changed_variables and cur_loc_changed. Don't update cur_loc here. (variable_merge_over_src): Don't call variable_canonicalize. (dataflow_set_preserve_mem_locs): Use shared_var_p. When removing loc that is equal to cur_loc, clear cur_loc, set cur_loc_changed and ensure variable_was_changed is called. (dataflow_set_remove_mem_locs): Use shared_var_p. Only compare pointers in cur_loc check, if it is equal to loc, clear cur_loc and set cur_loc_changed. Don't recompute cur_loc here. (variable_different_p): Remove compare_current_location argument, don't compare cur_loc. (dataflow_set_different_1): Adjust variable_different_p caller. (variable_was_changed): If dv had some var in changed_variables already, reset in_changed_variables flag for it and propagate cur_loc_changed over to the new variable. On empty var always set cur_loc_changed. Set in_changed_variables on whatever var is added to changed_variables. (set_slot_part): Clear cur_loc_changed and in_changed_variables. Use shared_var_p. When removing loc that is equal to cur_loc, clear cur_loc and set cur_loc_changed. If cur_loc is NULL at the end, don't set it to something else, just call variable_was_changed. (delete_slot_part): Use shared_var_p. When cur_loc equals to loc being removed, clear cur_loc and set cur_loc_changed. Set cur_loc_changed if all locations have been removed. (struct expand_loc_callback_data): New type. (vt_expand_loc_callback): Add dummy mode in which no rtxes are allocated. Always create SUBREGs if simplify_subreg failed. Prefer to use cur_loc, when that fails and still in changed_variables (and seen first time) recompute it. Set cur_loc_changed of variables which had to change cur_loc and compute elcd->cur_loc_changed if any of the subexpressions used had to change cur_loc. (vt_expand_loc): Adjust to pass arguments in expand_loc_callback_data structure. (vt_expand_loc_dummy): New function. (emitted_notes): New variable. (emit_note_insn_var_location): For VALUEs and DEBUG_EXPR_DECLs that weren't used for any other decl in current emit_notes_for_changes call call vt_expand_loc_dummy to update cur_loc. For -fno-var-tracking-assignments, set cur_loc to first loc_chain location if NULL before. Always use just cur_loc instead of first loc_chain location. When cur_loc_changed is false, when not --enable-checking=rtl just don't emit any note. When rtl checking, compute the note and assert it is the same as previous note. Clear cur_loc_changed and in_changed_variables at the end before removing from changed_variables. (check_changed_vars_3): New function. (emit_notes_for_changes): Traverse changed_vars to call check_changed_vars_3 on each changed var. (emit_notes_for_differences_1): Clear cur_loc_changed and in_changed_variables. Recompute cur_loc of new_var. (emit_notes_for_differences_2): Clear cur_loc if new variable appears. (vt_emit_notes): Initialize and destroy emitted_notes. From-SVN: r157264
This commit is contained in:
parent
c41379182b
commit
864ddef716
5 changed files with 560 additions and 193 deletions
|
@ -1,3 +1,84 @@
|
|||
2010-03-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/43176
|
||||
* Makefile.in (var-tracking.o): Depend on pointer-set.h.
|
||||
* cselib.c (struct expand_value_data): Add dummy field.
|
||||
(cselib_expand_value_rtx, cselib_expand_value_rtx_cb): Initialize
|
||||
dummy to false.
|
||||
(cselib_dummy_expand_value_rtx_cb): New function.
|
||||
(cselib_expand_value_rtx_1): If evd->dummy is true, don't allocate
|
||||
any rtl.
|
||||
* cselib.h (cselib_dummy_expand_value_rtx_cb): New prototype.
|
||||
* var-tracking.c: Include pointer-set.h.
|
||||
(variable): Change n_var_parts to char from int. Add
|
||||
cur_loc_changed and in_changed_variables fields.
|
||||
(variable_canonicalize): Remove.
|
||||
(shared_var_p): New inline function.
|
||||
(unshare_variable): Maintain cur_loc_changed and
|
||||
in_changed_variables fields. If var was in changed_variables,
|
||||
replace it there with new_var. Just copy cur_loc instead of
|
||||
resetting it to something else.
|
||||
(variable_union): Don't recompute cur_loc. Use shared_var_p.
|
||||
(dataflow_set_union): Don't call variable_canonicalize.
|
||||
(loc_cmp): If both x and y are DEBUG_EXPRs, compare uids
|
||||
of their DEBUG_EXPR_TREE_DECLs.
|
||||
(canonicalize_loc_order_check): Verify that cur_loc is NULL
|
||||
and in_changed_variables and cur_loc_changed is false.
|
||||
(variable_merge_over_cur): Clear cur_loc, in_changed_variables
|
||||
and cur_loc_changed. Don't update cur_loc here.
|
||||
(variable_merge_over_src): Don't call variable_canonicalize.
|
||||
(dataflow_set_preserve_mem_locs): Use shared_var_p. When
|
||||
removing loc that is equal to cur_loc, clear cur_loc,
|
||||
set cur_loc_changed and ensure variable_was_changed is called.
|
||||
(dataflow_set_remove_mem_locs): Use shared_var_p. Only
|
||||
compare pointers in cur_loc check, if it is equal to loc,
|
||||
clear cur_loc and set cur_loc_changed. Don't recompute cur_loc here.
|
||||
(variable_different_p): Remove compare_current_location argument,
|
||||
don't compare cur_loc.
|
||||
(dataflow_set_different_1): Adjust variable_different_p caller.
|
||||
(variable_was_changed): If dv had some var in changed_variables
|
||||
already, reset in_changed_variables flag for it and propagate
|
||||
cur_loc_changed over to the new variable. On empty var
|
||||
always set cur_loc_changed. Set in_changed_variables on whatever
|
||||
var is added to changed_variables.
|
||||
(set_slot_part): Clear cur_loc_changed and in_changed_variables.
|
||||
Use shared_var_p. When removing loc that is equal to cur_loc,
|
||||
clear cur_loc and set cur_loc_changed. If cur_loc is NULL at the
|
||||
end, don't set it to something else, just call variable_was_changed.
|
||||
(delete_slot_part): Use shared_var_p. When cur_loc equals to
|
||||
loc being removed, clear cur_loc and set cur_loc_changed.
|
||||
Set cur_loc_changed if all locations have been removed.
|
||||
(struct expand_loc_callback_data): New type.
|
||||
(vt_expand_loc_callback): Add dummy mode in which no rtxes are
|
||||
allocated. Always create SUBREGs if simplify_subreg failed.
|
||||
Prefer to use cur_loc, when that fails and still in
|
||||
changed_variables (and seen first time) recompute it. Set
|
||||
cur_loc_changed of variables which had to change cur_loc and
|
||||
compute elcd->cur_loc_changed if any of the subexpressions used
|
||||
had to change cur_loc.
|
||||
(vt_expand_loc): Adjust to pass arguments in
|
||||
expand_loc_callback_data structure.
|
||||
(vt_expand_loc_dummy): New function.
|
||||
(emitted_notes): New variable.
|
||||
(emit_note_insn_var_location): For VALUEs and DEBUG_EXPR_DECLs
|
||||
that weren't used for any other decl in current
|
||||
emit_notes_for_changes call call vt_expand_loc_dummy to update
|
||||
cur_loc. For -fno-var-tracking-assignments, set cur_loc to
|
||||
first loc_chain location if NULL before. Always use just
|
||||
cur_loc instead of first loc_chain location. When cur_loc_changed
|
||||
is false, when not --enable-checking=rtl just don't emit any note.
|
||||
When rtl checking, compute the note and assert it is the same
|
||||
as previous note. Clear cur_loc_changed and in_changed_variables
|
||||
at the end before removing from changed_variables.
|
||||
(check_changed_vars_3): New function.
|
||||
(emit_notes_for_changes): Traverse changed_vars to call
|
||||
check_changed_vars_3 on each changed var.
|
||||
(emit_notes_for_differences_1): Clear cur_loc_changed and
|
||||
in_changed_variables. Recompute cur_loc of new_var.
|
||||
(emit_notes_for_differences_2): Clear cur_loc if new variable
|
||||
appears.
|
||||
(vt_emit_notes): Initialize and destroy emitted_notes.
|
||||
|
||||
2010-03-07 Bernd Schmidt <bernd.schmidt@analog.com>
|
||||
|
||||
PR rtl-optimization/42220
|
||||
|
|
|
@ -3031,7 +3031,7 @@ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
|||
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
|
||||
$(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
|
||||
$(REGS_H) $(EXPR_H) $(TIMEVAR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
|
||||
cselib.h $(TARGET_H) $(TOPLEV_H) $(PARAMS_H) $(DIAGNOSTIC_H)
|
||||
cselib.h $(TARGET_H) $(TOPLEV_H) $(PARAMS_H) $(DIAGNOSTIC_H) pointer-set.h
|
||||
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
|
||||
$(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
|
||||
|
|
40
gcc/cselib.c
40
gcc/cselib.c
|
@ -69,6 +69,7 @@ struct expand_value_data
|
|||
bitmap regs_active;
|
||||
cselib_expand_callback callback;
|
||||
void *callback_arg;
|
||||
bool dummy;
|
||||
};
|
||||
|
||||
static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int);
|
||||
|
@ -1069,6 +1070,7 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth)
|
|||
evd.regs_active = regs_active;
|
||||
evd.callback = NULL;
|
||||
evd.callback_arg = NULL;
|
||||
evd.dummy = false;
|
||||
|
||||
return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
|
||||
}
|
||||
|
@ -1088,10 +1090,29 @@ cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
|
|||
evd.regs_active = regs_active;
|
||||
evd.callback = cb;
|
||||
evd.callback_arg = data;
|
||||
evd.dummy = false;
|
||||
|
||||
return cselib_expand_value_rtx_1 (orig, &evd, max_depth);
|
||||
}
|
||||
|
||||
/* Similar to cselib_expand_value_rtx_cb, but no rtxs are actually copied
|
||||
or simplified. Useful to find out whether cselib_expand_value_rtx_cb
|
||||
would return NULL or non-NULL, without allocating new rtx. */
|
||||
|
||||
bool
|
||||
cselib_dummy_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
|
||||
cselib_expand_callback cb, void *data)
|
||||
{
|
||||
struct expand_value_data evd;
|
||||
|
||||
evd.regs_active = regs_active;
|
||||
evd.callback = cb;
|
||||
evd.callback_arg = data;
|
||||
evd.dummy = true;
|
||||
|
||||
return cselib_expand_value_rtx_1 (orig, &evd, max_depth) != NULL;
|
||||
}
|
||||
|
||||
/* Internal implementation of cselib_expand_value_rtx and
|
||||
cselib_expand_value_rtx_cb. */
|
||||
|
||||
|
@ -1249,7 +1270,10 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
|
|||
that all fields need copying, and then clear the fields that should
|
||||
not be copied. That is the sensible default behavior, and forces
|
||||
us to explicitly document why we are *not* copying a flag. */
|
||||
copy = shallow_copy_rtx (orig);
|
||||
if (evd->dummy)
|
||||
copy = NULL;
|
||||
else
|
||||
copy = shallow_copy_rtx (orig);
|
||||
|
||||
format_ptr = GET_RTX_FORMAT (code);
|
||||
|
||||
|
@ -1263,7 +1287,8 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
|
|||
max_depth - 1);
|
||||
if (!result)
|
||||
return NULL;
|
||||
XEXP (copy, i) = result;
|
||||
if (copy)
|
||||
XEXP (copy, i) = result;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1271,14 +1296,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
|
|||
case 'V':
|
||||
if (XVEC (orig, i) != NULL)
|
||||
{
|
||||
XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
|
||||
for (j = 0; j < XVECLEN (copy, i); j++)
|
||||
if (copy)
|
||||
XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
|
||||
for (j = 0; j < XVECLEN (orig, i); j++)
|
||||
{
|
||||
rtx result = cselib_expand_value_rtx_1 (XVECEXP (orig, i, j),
|
||||
evd, max_depth - 1);
|
||||
if (!result)
|
||||
return NULL;
|
||||
XVECEXP (copy, i, j) = result;
|
||||
if (copy)
|
||||
XVECEXP (copy, i, j) = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1299,6 +1326,9 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
|
|||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (evd->dummy)
|
||||
return orig;
|
||||
|
||||
mode = GET_MODE (copy);
|
||||
/* If an operand has been simplified into CONST_INT, which doesn't
|
||||
have a mode and the mode isn't derivable from whole rtx's mode,
|
||||
|
|
|
@ -81,7 +81,9 @@ extern int references_value_p (const_rtx, int);
|
|||
extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
|
||||
typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
|
||||
extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int,
|
||||
cselib_expand_callback, void*);
|
||||
cselib_expand_callback, void *);
|
||||
extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int,
|
||||
cselib_expand_callback, void *);
|
||||
extern rtx cselib_subst_to_values (rtx);
|
||||
extern void cselib_invalidate_rtx (rtx);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue