Commit 864ddef7 by Jakub Jelinek Committed by Jakub Jelinek

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
parent c4137918
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> 2010-03-07 Bernd Schmidt <bernd.schmidt@analog.com>
PR rtl-optimization/42220 PR rtl-optimization/42220
......
...@@ -3031,7 +3031,7 @@ var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ ...@@ -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) \ $(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) \ $(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) \ $(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) \ 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) \ $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
$(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \ $(TOPLEV_H) $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
......
...@@ -69,6 +69,7 @@ struct expand_value_data ...@@ -69,6 +69,7 @@ struct expand_value_data
bitmap regs_active; bitmap regs_active;
cselib_expand_callback callback; cselib_expand_callback callback;
void *callback_arg; void *callback_arg;
bool dummy;
}; };
static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int); 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) ...@@ -1069,6 +1070,7 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth)
evd.regs_active = regs_active; evd.regs_active = regs_active;
evd.callback = NULL; evd.callback = NULL;
evd.callback_arg = NULL; evd.callback_arg = NULL;
evd.dummy = false;
return cselib_expand_value_rtx_1 (orig, &evd, max_depth); 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, ...@@ -1088,10 +1090,29 @@ cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth,
evd.regs_active = regs_active; evd.regs_active = regs_active;
evd.callback = cb; evd.callback = cb;
evd.callback_arg = data; evd.callback_arg = data;
evd.dummy = false;
return cselib_expand_value_rtx_1 (orig, &evd, max_depth); 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 /* Internal implementation of cselib_expand_value_rtx and
cselib_expand_value_rtx_cb. */ cselib_expand_value_rtx_cb. */
...@@ -1249,7 +1270,10 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, ...@@ -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 that all fields need copying, and then clear the fields that should
not be copied. That is the sensible default behavior, and forces not be copied. That is the sensible default behavior, and forces
us to explicitly document why we are *not* copying a flag. */ 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); format_ptr = GET_RTX_FORMAT (code);
...@@ -1263,7 +1287,8 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, ...@@ -1263,7 +1287,8 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
max_depth - 1); max_depth - 1);
if (!result) if (!result)
return NULL; return NULL;
XEXP (copy, i) = result; if (copy)
XEXP (copy, i) = result;
} }
break; break;
...@@ -1271,14 +1296,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, ...@@ -1271,14 +1296,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
case 'V': case 'V':
if (XVEC (orig, i) != NULL) if (XVEC (orig, i) != NULL)
{ {
XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); if (copy)
for (j = 0; j < XVECLEN (copy, i); j++) 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), rtx result = cselib_expand_value_rtx_1 (XVECEXP (orig, i, j),
evd, max_depth - 1); evd, max_depth - 1);
if (!result) if (!result)
return NULL; return NULL;
XVECEXP (copy, i, j) = result; if (copy)
XVECEXP (copy, i, j) = result;
} }
} }
break; break;
...@@ -1299,6 +1326,9 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, ...@@ -1299,6 +1326,9 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
gcc_unreachable (); gcc_unreachable ();
} }
if (evd->dummy)
return orig;
mode = GET_MODE (copy); mode = GET_MODE (copy);
/* If an operand has been simplified into CONST_INT, which doesn't /* 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, 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); ...@@ -81,7 +81,9 @@ extern int references_value_p (const_rtx, int);
extern rtx cselib_expand_value_rtx (rtx, bitmap, int); extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *); typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int, 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 rtx cselib_subst_to_values (rtx);
extern void cselib_invalidate_rtx (rtx); extern void cselib_invalidate_rtx (rtx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment