diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-03-07 15:44:11 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-03-07 15:44:11 +0000 |
commit | bc95df68c1c6f0128599531b728463564200fbeb (patch) | |
tree | 025d8a7128b27b9e7c0a077d3565137986a733d0 /gcc/cselib.c | |
parent | 6581d87d26e38e43dd7bb7c1e6656c184495d6b9 (diff) | |
download | gcc-bc95df68c1c6f0128599531b728463564200fbeb.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@157264 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index deac835f933..515fc328463 100644 --- a/gcc/cselib.c +++ b/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, |