This patch introduces a number of new macros and functions that will
be used to distinguish between different kinds of debug stmts, insns
and notes, namely, preexisting debug bind ones and to-be-introduced
nonbind markers.
In a seemingly mechanical way, it adjusts several uses of the macros
and functions, so that they refer to narrower categories when
appropriate.
These changes, by themselves, should not have any visible effect in
the compiler behavior, since the upcoming debug markers are never
created with this patch alone.
for gcc/ChangeLog
* gimple.h (enum gimple_debug_subcode): Add
GIMPLE_DEBUG_BEGIN_STMT.
(gimple_debug_begin_stmt_p): New.
(gimple_debug_nonbind_marker_p): New.
* tree.h (MAY_HAVE_DEBUG_MARKER_STMTS): New.
(MAY_HAVE_DEBUG_BIND_STMTS): Renamed from....
(MAY_HAVE_DEBUG_STMTS): ... this. Check both.
* insn-notes.def (BEGIN_STMT): New.
* rtl.h (MAY_HAVE_DEBUG_MARKER_INSNS): New.
(MAY_HAVE_DEBUG_BIND_INSNS): Renamed from....
(MAY_HAVE_DEBUG_INSNS): ... this. Check both.
(NOTE_MARKER_LOCATION, NOTE_MARKER_P): New.
(DEBUG_BIND_INSN_P, DEBUG_MARKER_INSN_P): New.
(INSN_DEBUG_MARKER_KIND): New.
(GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT): New.
(INSN_VAR_LOCATION): Check for VAR_LOCATION.
(INSN_VAR_LOCATION_PTR): New.
* cfgexpand.c (expand_debug_locations): Handle debug bind insns
only.
(expand_gimple_basic_block): Likewise. Emit debug temps for TER
deps only if debug bind insns are enabled.
(pass_expand::execute): Avoid deep TER and expand
debug locations for debug bind insns only.
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Narrow
debug stmts special handling down to debug bind stmts.
* combine.c (try_combine): Narrow debug insns special handling
down to debug bind insns.
* cse.c (delete_trivially_dead_insns): Handle debug bindings.
Narrow debug insns preexisting special handling down to debug
bind insns.
* dce.c (rest_of_handle_ud_dce): Narrow debug insns special
handling down to debug bind insns.
* function.c (instantiate_virtual_regs): Skip debug markers,
adjust handling of debug binds.
* gimple-ssa-backprop.c (backprop::prepare_change): Try debug
temp insertion iff MAY_HAVE_DEBUG_BIND_STMTS.
* haifa-sched.c (schedule_insn): Narrow special handling of debug
insns to debug bind insns.
* ipa-param-manipulation.c (ipa_modify_call_arguments): Narrow
special handling of debug stmts to debug bind stmts.
* ipa-split.c (split_function): Likewise.
* ira.c (combine_and_move_insns): Adjust debug bind insns only.
* loop-unroll.c (apply_opt_in_copies): Adjust tests on bind
debug insns.
* reg-stack.c (convert_regs_1): Use DEBUG_BIND_INSN_P.
* regrename.c (build_def_use): Likewise.
* regcprop.c (copyprop_hardreg_forward_1): Likewise.
(pass_cprop_hardreg): Narrow special casing of debug insns to
debug bind insns.
* regstat.c (regstat_init_n_sets_and_refs): Likewise.
* reload1.c (reload): Likewise.
* sese.c (sese_insert_phis_for_liveouts): Narrow special
casing of debug stmts to debug bind stmts.
* shrink-wrap.c (move_insn_for_shrink_wrap): Likewise.
* ssa-iterators.h (num_imm_uses): Likewise.
* tree-cfg.c (gimple_merge_blocks): Narrow special casing of
debug stmts to debug bind stmts.
* tree-inline.c (tree_function_versioning): Narrow special casing
of debug stmts to debug bind stmts.
* tree-loop-distribution.c (generate_loops_for_partition):
Narrow special casing of debug stmts to debug bind stmts.
* tree-sra.c (analyze_access_subtree): Narrow special casing
of debug stmts to debug bind stmts.
* tree-ssa-dce.c (remove_dead_stmt): Narrow special casing of debug
stmts to debug bind stmts.
* tree-ssa-loop-ivopt.c (remove_unused_ivs): Narrow special
casing of debug stmts to debug bind stmts.
* tree-ssa-reassoc.c (reassoc_remove_stmt): Likewise.
* tree-ssa-tail-merge.c (tail_merge_optimize): Narrow special
casing of debug stmts to debug bind stmts.
* tree-ssa-threadedge.c (propagate_threaded_block_debug_info):
Likewise.
* tree-ssa.c (flush_pending_stmts): Narrow special casing of
debug stmts to debug bind stmts.
(gimple_replace_ssa_lhs): Likewise.
(insert_debug_temp_for_var_def): Likewise.
(insert_debug_temps_for_defs): Likewise.
(reset_debug_uses): Likewise.
* tree-ssanames.c (release_ssa_name_fn): Likewise.
* tree-vect-loop-manip.c (adjust_debug_stmts_now): Likewise.
(adjust_debug_stmts): Likewise.
(adjust_phi_and_debug_stmts): Likewise.
(vect_do_peeling): Likewise.
* tree-vect-loop.c (vect_transform_loop): Likewise.
* valtrack.c (propagate_for_debug): Use BIND_DEBUG_INSN_P.
* var-tracking.c (adjust_mems): Narrow special casing of debug
insns to debug bind insns.
(dv_onepart_p, dataflow_set_clar_at_call, use_type): Likewise.
(compute_bb_dataflow, vt_find_locations): Likewise.
(vt_expand_loc, emit_notes_for_changes): Likewise.
(vt_init_cfa_base): Likewise.
(vt_emit_notes): Likewise.
(vt_initialize): Likewise.
(vt_finalize): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@255565
138bc75d-0d04-0410-961f-
82ee72b054a4
2017-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * gimple.h (enum gimple_debug_subcode): Add
+ GIMPLE_DEBUG_BEGIN_STMT.
+ (gimple_debug_begin_stmt_p): New.
+ (gimple_debug_nonbind_marker_p): New.
+ * tree.h (MAY_HAVE_DEBUG_MARKER_STMTS): New.
+ (MAY_HAVE_DEBUG_BIND_STMTS): Renamed from....
+ (MAY_HAVE_DEBUG_STMTS): ... this. Check both.
+ * insn-notes.def (BEGIN_STMT): New.
+ * rtl.h (MAY_HAVE_DEBUG_MARKER_INSNS): New.
+ (MAY_HAVE_DEBUG_BIND_INSNS): Renamed from....
+ (MAY_HAVE_DEBUG_INSNS): ... this. Check both.
+ (NOTE_MARKER_LOCATION, NOTE_MARKER_P): New.
+ (DEBUG_BIND_INSN_P, DEBUG_MARKER_INSN_P): New.
+ (INSN_DEBUG_MARKER_KIND): New.
+ (GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT): New.
+ (INSN_VAR_LOCATION): Check for VAR_LOCATION.
+ (INSN_VAR_LOCATION_PTR): New.
+ * cfgexpand.c (expand_debug_locations): Handle debug bind insns
+ only.
+ (expand_gimple_basic_block): Likewise. Emit debug temps for TER
+ deps only if debug bind insns are enabled.
+ (pass_expand::execute): Avoid deep TER and expand
+ debug locations for debug bind insns only.
+ * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Narrow
+ debug stmts special handling down to debug bind stmts.
+ * combine.c (try_combine): Narrow debug insns special handling
+ down to debug bind insns.
+ * cse.c (delete_trivially_dead_insns): Handle debug bindings.
+ Narrow debug insns preexisting special handling down to debug
+ bind insns.
+ * dce.c (rest_of_handle_ud_dce): Narrow debug insns special
+ handling down to debug bind insns.
+ * function.c (instantiate_virtual_regs): Skip debug markers,
+ adjust handling of debug binds.
+ * gimple-ssa-backprop.c (backprop::prepare_change): Try debug
+ temp insertion iff MAY_HAVE_DEBUG_BIND_STMTS.
+ * haifa-sched.c (schedule_insn): Narrow special handling of debug
+ insns to debug bind insns.
+ * ipa-param-manipulation.c (ipa_modify_call_arguments): Narrow
+ special handling of debug stmts to debug bind stmts.
+ * ipa-split.c (split_function): Likewise.
+ * ira.c (combine_and_move_insns): Adjust debug bind insns only.
+ * loop-unroll.c (apply_opt_in_copies): Adjust tests on bind
+ debug insns.
+ * reg-stack.c (convert_regs_1): Use DEBUG_BIND_INSN_P.
+ * regrename.c (build_def_use): Likewise.
+ * regcprop.c (copyprop_hardreg_forward_1): Likewise.
+ (pass_cprop_hardreg): Narrow special casing of debug insns to
+ debug bind insns.
+ * regstat.c (regstat_init_n_sets_and_refs): Likewise.
+ * reload1.c (reload): Likewise.
+ * sese.c (sese_insert_phis_for_liveouts): Narrow special
+ casing of debug stmts to debug bind stmts.
+ * shrink-wrap.c (move_insn_for_shrink_wrap): Likewise.
+ * ssa-iterators.h (num_imm_uses): Likewise.
+ * tree-cfg.c (gimple_merge_blocks): Narrow special casing of
+ debug stmts to debug bind stmts.
+ * tree-inline.c (tree_function_versioning): Narrow special casing
+ of debug stmts to debug bind stmts.
+ * tree-loop-distribution.c (generate_loops_for_partition):
+ Narrow special casing of debug stmts to debug bind stmts.
+ * tree-sra.c (analyze_access_subtree): Narrow special casing
+ of debug stmts to debug bind stmts.
+ * tree-ssa-dce.c (remove_dead_stmt): Narrow special casing of debug
+ stmts to debug bind stmts.
+ * tree-ssa-loop-ivopt.c (remove_unused_ivs): Narrow special
+ casing of debug stmts to debug bind stmts.
+ * tree-ssa-reassoc.c (reassoc_remove_stmt): Likewise.
+ * tree-ssa-tail-merge.c (tail_merge_optimize): Narrow special
+ casing of debug stmts to debug bind stmts.
+ * tree-ssa-threadedge.c (propagate_threaded_block_debug_info):
+ Likewise.
+ * tree-ssa.c (flush_pending_stmts): Narrow special casing of
+ debug stmts to debug bind stmts.
+ (gimple_replace_ssa_lhs): Likewise.
+ (insert_debug_temp_for_var_def): Likewise.
+ (insert_debug_temps_for_defs): Likewise.
+ (reset_debug_uses): Likewise.
+ * tree-ssanames.c (release_ssa_name_fn): Likewise.
+ * tree-vect-loop-manip.c (adjust_debug_stmts_now): Likewise.
+ (adjust_debug_stmts): Likewise.
+ (adjust_phi_and_debug_stmts): Likewise.
+ (vect_do_peeling): Likewise.
+ * tree-vect-loop.c (vect_transform_loop): Likewise.
+ * valtrack.c (propagate_for_debug): Use BIND_DEBUG_INSN_P.
+ * var-tracking.c (adjust_mems): Narrow special casing of debug
+ insns to debug bind insns.
+ (dv_onepart_p, dataflow_set_clar_at_call, use_type): Likewise.
+ (compute_bb_dataflow, vt_find_locations): Likewise.
+ (vt_expand_loc, emit_notes_for_changes): Likewise.
+ (vt_init_cfa_base): Likewise.
+ (vt_emit_notes): Likewise.
+ (vt_initialize): Likewise.
+ (vt_finalize): Likewise.
+
* emit-rtl.c (next_nondebug_insn, prev_nondebug_insn): Reorder.
(next_nonnote_nondebug_insn, prev_nonnote_nondebug_insn): Reorder.
(next_nonnote_nondebug_insn_bb): New.
flag_strict_aliasing = 0;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
tree value = (tree)INSN_VAR_LOCATION_LOC (insn);
rtx val;
a_2 = ...
#DEBUG ... => #D1
*/
- if (MAY_HAVE_DEBUG_INSNS
+ if (MAY_HAVE_DEBUG_BIND_INSNS
&& SA.values
&& !is_gimple_debug (stmt))
{
timevar_pop (TV_OUT_OF_SSA);
SA.partition_to_pseudo = XCNEWVEC (rtx, SA.map->num_partitions);
- if (MAY_HAVE_DEBUG_STMTS && flag_tree_ter)
+ if (MAY_HAVE_DEBUG_BIND_STMTS && flag_tree_ter)
{
gimple_stmt_iterator gsi;
FOR_EACH_BB_FN (bb, cfun)
next_bb)
bb = expand_gimple_basic_block (bb, var_ret_seq != NULL_RTX);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
expand_debug_locations ();
if (deep_ter_debug_map)
stmts and associate D#X with parm in decl_debug_args_lookup
vector to say for debug info that if parameter parm had been passed,
it would have value parm_Y(D). */
- if (e->callee->clone.combined_args_to_skip && MAY_HAVE_DEBUG_STMTS)
+ if (e->callee->clone.combined_args_to_skip && MAY_HAVE_DEBUG_BIND_STMTS)
{
vec<tree, va_gc> **debug_args
= decl_debug_args_lookup (e->callee->decl);
/* *SPLIT may be part of I2SRC, so make sure we have the
original expression around for later debug processing.
We should not need I2SRC any more in other cases. */
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
i2src = copy_rtx (i2src);
else
i2src = NULL;
return 0;
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
struct undo *undo;
if (newi2pat)
{
- if (MAY_HAVE_DEBUG_INSNS && i2scratch)
+ if (MAY_HAVE_DEBUG_BIND_INSNS && i2scratch)
propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
this_basic_block);
INSN_CODE (i2) = i2_code_number;
}
else
{
- if (MAY_HAVE_DEBUG_INSNS && i2src)
+ if (MAY_HAVE_DEBUG_BIND_INSNS && i2src)
propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
this_basic_block);
SET_INSN_DELETED (i2);
{
LOG_LINKS (i1) = NULL;
REG_NOTES (i1) = 0;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
propagate_for_debug (i1, last_combined_insn, i1dest, i1src,
this_basic_block);
SET_INSN_DELETED (i1);
{
LOG_LINKS (i0) = NULL;
REG_NOTES (i0) = 0;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
propagate_for_debug (i0, last_combined_insn, i0dest, i0src,
this_basic_block);
SET_INSN_DELETED (i0);
timevar_push (TV_DELETE_TRIVIALLY_DEAD);
/* First count the number of times each register is used. */
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
counts = XCNEWVEC (int, nreg * 3);
for (insn = insns; insn; insn = NEXT_INSN (insn))
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
NULL_RTX, 1);
else if (INSN_P (insn))
if (! live_insn && dbg_cnt (delete_trivial_dead))
{
if (DEBUG_INSN_P (insn))
- count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
- NULL_RTX, -1);
+ {
+ if (DEBUG_BIND_INSN_P (insn))
+ count_reg_usage (INSN_VAR_LOCATION_LOC (insn), counts + nreg,
+ NULL_RTX, -1);
+ }
else
{
rtx set;
- if (MAY_HAVE_DEBUG_INSNS
+ if (MAY_HAVE_DEBUG_BIND_INSNS
&& (set = single_set (insn)) != NULL_RTX
&& is_dead_reg (SET_DEST (set), counts)
/* Used at least once in some DEBUG_INSN. */
}
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
/* If this debug insn references a dead register that wasn't replaced
with an DEBUG_EXPR, reset the DEBUG_INSN. */
}
worklist.release ();
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
reset_unmarked_insns_debug_uses ();
/* Before any insns are deleted, we must remove the chains since
Fortunately, they shouldn't contain virtual registers either. */
if (GET_CODE (PATTERN (insn)) == USE
|| GET_CODE (PATTERN (insn)) == CLOBBER
- || GET_CODE (PATTERN (insn)) == ASM_INPUT)
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || DEBUG_MARKER_INSN_P (insn))
continue;
- else if (DEBUG_INSN_P (insn))
- instantiate_virtual_regs_in_rtx (&INSN_VAR_LOCATION (insn));
+ else if (DEBUG_BIND_INSN_P (insn))
+ instantiate_virtual_regs_in_rtx (INSN_VAR_LOCATION_PTR (insn));
else
instantiate_virtual_regs_in_insn (insn);
void
backprop::prepare_change (tree var)
{
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
insert_debug_temp_for_var_def (NULL, var);
reset_flow_sensitive_info (var);
}
GF_PREDICT_TAKEN = 1 << 15
};
-/* Currently, there are only two types of gimple debug stmt. Others are
- envisioned, for example, to enable the generation of is_stmt notes
- in line number information, to mark sequence points, etc. This
- subcode is to be used to tell them apart. */
+/* This subcode tells apart different kinds of stmts that are not used
+ for codegen, but rather to retain debug information. */
enum gimple_debug_subcode {
GIMPLE_DEBUG_BIND = 0,
- GIMPLE_DEBUG_SOURCE_BIND = 1
+ GIMPLE_DEBUG_SOURCE_BIND = 1,
+ GIMPLE_DEBUG_BEGIN_STMT = 2
};
/* Masks for selecting a pass local flag (PLF) to work on. These
gimple_set_op (dbg, 1, value);
}
+/* Return true if S is a GIMPLE_DEBUG BEGIN_STMT statement. */
+
+static inline bool
+gimple_debug_begin_stmt_p (const gimple *s)
+{
+ if (is_gimple_debug (s))
+ return s->subcode == GIMPLE_DEBUG_BEGIN_STMT;
+
+ return false;
+}
+
+/* Return true if S is a GIMPLE_DEBUG non-binding marker statement. */
+
+static inline bool
+gimple_debug_nonbind_marker_p (const gimple *s)
+{
+ if (is_gimple_debug (s))
+ return s->subcode == GIMPLE_DEBUG_BEGIN_STMT;
+
+ return false;
+}
+
/* Return the line number for EXPR, or return -1 if we have no line
number information for it. */
static inline int
gcc_assert (sd_lists_empty_p (insn, SD_LIST_HARD_BACK));
/* Reset debug insns invalidated by moving this insn. */
- if (MAY_HAVE_DEBUG_INSNS && !DEBUG_INSN_P (insn))
+ if (MAY_HAVE_DEBUG_BIND_INSNS && !DEBUG_INSN_P (insn))
for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
sd_iterator_cond (&sd_it, &dep);)
{
continue;
}
- gcc_assert (DEBUG_INSN_P (dbg));
+ gcc_assert (DEBUG_BIND_INSN_P (dbg));
if (sched_verbose >= 6)
fprintf (sched_dump, ";;\t\tresetting: debug insn %d\n",
/* The values passed to callee. */
INSN_NOTE (CALL_ARG_LOCATION)
+/* The beginning of a statement. */
+INSN_NOTE (BEGIN_STMT)
+
/* Record the struct for the following basic block. Uses
NOTE_BASIC_BLOCK. FIXME: Redundant with the basic block pointer
now included in every insn. NOTE: If there's no CFG anymore, in other words,
}
vargs.quick_push (expr);
}
- if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
+ if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_BIND_STMTS)
{
unsigned int ix;
tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
{
vec<tree, va_gc> **debug_args = NULL;
unsigned i = 0, len = 0;
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
{
debug_args = decl_debug_args_lookup (node->decl);
if (debug_args)
tree ddecl;
gimple *def_temp;
- /* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
- otherwise if it didn't exist before, we'd end up with
- different SSA_NAME_VERSIONs between -g and -g0. */
+ /* This needs to be done even without
+ MAY_HAVE_DEBUG_BIND_STMTS, otherwise if it didn't exist
+ before, we'd end up with different SSA_NAME_VERSIONs
+ between -g and -g0. */
arg = get_or_create_ssa_default_def (cfun, parm);
- if (!MAY_HAVE_DEBUG_STMTS || debug_args == NULL)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS || debug_args == NULL)
continue;
while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm))
}
/* Last pass - adjust debug insns referencing cleared regs. */
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
rtx old_loc = INSN_VAR_LOCATION_LOC (insn);
INSN_VAR_LOCATION_LOC (insn)
FOR_BB_INSNS_SAFE (bb, insn, next)
{
if (!INSN_P (insn)
- || (DEBUG_INSN_P (insn)
+ || (DEBUG_BIND_INSN_P (insn)
+ && INSN_VAR_LOCATION_DECL (insn)
&& TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL))
continue;
while (!INSN_P (orig_insn)
- || (DEBUG_INSN_P (orig_insn)
+ || (DEBUG_BIND_INSN_P (orig_insn)
+ && INSN_VAR_LOCATION_DECL (orig_insn)
&& (TREE_CODE (INSN_VAR_LOCATION_DECL (orig_insn))
== LABEL_DECL)))
orig_insn = NEXT_INSN (orig_insn);
/* Don't bother processing unless there is a stack reg
mentioned or if it's a CALL_INSN. */
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
if (starting_stack_p)
debug_insns_with_starting_stack++;
for (insn = BB_HEAD (block); debug_insns_with_starting_stack;
insn = NEXT_INSN (insn))
{
- if (!DEBUG_INSN_P (insn))
+ if (!DEBUG_BIND_INSN_P (insn))
continue;
debug_insns_with_starting_stack--;
next = NEXT_INSN (insn);
if (!NONDEBUG_INSN_P (insn))
{
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
rtx loc = INSN_VAR_LOCATION_LOC (insn);
if (!VAR_LOC_UNKNOWN_P (loc))
copyprop_hardreg_forward_1 (bb, all_vd + bb->index);
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
FOR_EACH_BB_FN (bb, fun)
if (bitmap_bit_p (visited, bb->index)
if (REG_NOTE_KIND (note) == REG_CFA_RESTORE)
scan_rtx (insn, &XEXP (note, 0), NO_REGS, mark_all_read, OP_IN);
}
- else if (DEBUG_INSN_P (insn)
+ else if (DEBUG_BIND_INSN_P (insn)
&& !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
{
scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn),
regstat_n_sets_and_refs = XNEWVEC (struct regstat_n_sets_and_refs_t, max_regno);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
for (i = 0; i < max_regno; i++)
{
int use_count;
/* We don't want complex addressing modes in debug insns
if simpler ones will do, so delegitimize equivalences
in debug insns. */
- if (MAY_HAVE_DEBUG_INSNS && reg_renumber[i] < 0)
+ if (MAY_HAVE_DEBUG_BIND_INSNS && reg_renumber[i] < 0)
{
rtx reg = regno_reg_rtx[i];
rtx equiv = 0;
while (next && DF_REF_INSN (next) == insn)
next = DF_REF_NEXT_REG (next);
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
if (!equiv)
{
/* Predicate yielding nonzero iff X is an insn that is not a debug insn. */
#define NONDEBUG_INSN_P(X) (INSN_P (X) && !DEBUG_INSN_P (X))
+/* Nonzero if DEBUG_MARKER_INSN_P may possibly hold. */
+#define MAY_HAVE_DEBUG_MARKER_INSNS 0 /* debug_nonbind_markers_p */
+/* Nonzero if DEBUG_BIND_INSN_P may possibly hold. */
+#define MAY_HAVE_DEBUG_BIND_INSNS flag_var_tracking_assignments
/* Nonzero if DEBUG_INSN_P may possibly hold. */
-#define MAY_HAVE_DEBUG_INSNS (flag_var_tracking_assignments)
+#define MAY_HAVE_DEBUG_INSNS \
+ (MAY_HAVE_DEBUG_MARKER_INSNS || MAY_HAVE_DEBUG_BIND_INSNS)
/* Predicate yielding nonzero iff X is a real insn. */
#define INSN_P(X) \
#define NOTE_EH_HANDLER(INSN) XCINT (INSN, 3, NOTE)
#define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 3, NOTE)
#define NOTE_VAR_LOCATION(INSN) XCEXP (INSN, 3, NOTE)
+#define NOTE_MARKER_LOCATION(INSN) XCUINT (INSN, 3, NOTE)
#define NOTE_CFI(INSN) XCCFI (INSN, 3, NOTE)
#define NOTE_LABEL_NUMBER(INSN) XCINT (INSN, 3, NOTE)
#define NOTE_INSN_BASIC_BLOCK_P(INSN) \
(NOTE_P (INSN) && NOTE_KIND (INSN) == NOTE_INSN_BASIC_BLOCK)
+/* Nonzero if INSN is a debug nonbind marker note,
+ for which NOTE_MARKER_LOCATION can be used. */
+#define NOTE_MARKER_P(INSN) \
+ (NOTE_P (INSN) && \
+ (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT))
+
/* Variable declaration and the location of a variable. */
#define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION))
#define PAT_VAR_LOCATION_LOC(PAT) (XCEXP ((PAT), 1, VAR_LOCATION))
#define NOTE_VAR_LOCATION_STATUS(NOTE) \
PAT_VAR_LOCATION_STATUS (NOTE_VAR_LOCATION (NOTE))
+/* Evaluate to TRUE if INSN is a debug insn that denotes a variable
+ location/value tracking annotation. */
+#define DEBUG_BIND_INSN_P(INSN) \
+ (DEBUG_INSN_P (INSN) \
+ && (GET_CODE (PATTERN (INSN)) \
+ == VAR_LOCATION))
+/* Evaluate to TRUE if INSN is a debug insn that denotes a program
+ source location marker. */
+#define DEBUG_MARKER_INSN_P(INSN) \
+ (DEBUG_INSN_P (INSN) \
+ && (GET_CODE (PATTERN (INSN)) \
+ != VAR_LOCATION))
+/* Evaluate to the marker kind. */
+#define INSN_DEBUG_MARKER_KIND(INSN) \
+ (GET_CODE (PATTERN (INSN)) == DEBUG_MARKER \
+ ? (GET_MODE (PATTERN (INSN)) == VOIDmode \
+ ? NOTE_INSN_BEGIN_STMT \
+ : (enum insn_note)-1) \
+ : (enum insn_note)-1)
+/* Create patterns for debug markers. These and the above abstract
+ the representation, so that it's easier to get rid of the abuse of
+ the mode to hold the marker kind. Other marker types are
+ envisioned, so a single bit flag won't do; maybe separate RTL codes
+ wouldn't be a problem. */
+#define GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT() \
+ gen_rtx_DEBUG_MARKER (VOIDmode)
+
/* The VAR_LOCATION rtx in a DEBUG_INSN. */
-#define INSN_VAR_LOCATION(INSN) PATTERN (INSN)
+#define INSN_VAR_LOCATION(INSN) \
+ (RTL_FLAG_CHECK1 ("INSN_VAR_LOCATION", PATTERN (INSN), VAR_LOCATION))
+/* A pointer to the VAR_LOCATION rtx in a DEBUG_INSN. */
+#define INSN_VAR_LOCATION_PTR(INSN) \
+ (&PATTERN (INSN))
/* Accessors for a tree-expanded var location debug insn. */
#define INSN_VAR_LOCATION_DECL(INSN) \
sese_insert_phis_for_liveouts (sese_info_p region, basic_block bb,
edge false_e, edge true_e)
{
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
sese_reset_debug_liveouts (region);
unsigned i;
move it as far as we can. */
do
{
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
FOR_BB_INSNS_REVERSE (bb, dinsn)
- if (DEBUG_INSN_P (dinsn))
+ if (DEBUG_BIND_INSN_P (dinsn))
{
df_ref use;
FOR_EACH_INSN_USE (use, dinsn)
const ssa_use_operand_t *ptr;
unsigned int num = 0;
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
{
for (ptr = start->next; ptr != start; ptr = ptr->next)
if (USE_STMT (ptr))
gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
}
/* Other user labels keep around in a form of a debug stmt. */
- else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_STMTS)
+ else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_BIND_STMTS)
{
gimple *dbg = gimple_build_debug_bind (label,
integer_zero_node,
&vars);
if (init)
init_stmts.safe_push (init);
- if (MAY_HAVE_DEBUG_STMTS && args_to_skip)
+ if (MAY_HAVE_DEBUG_BIND_STMTS && args_to_skip)
{
if (parm_num == -1)
{
}
}
- if (debug_args_to_skip && MAY_HAVE_DEBUG_STMTS)
+ if (debug_args_to_skip && MAY_HAVE_DEBUG_BIND_STMTS)
{
tree parm;
vec<tree, va_gc> **debug_args = NULL;
/* Remove stmts not in the PARTITION bitmap. */
bbs = get_loop_body_in_dom_order (loop);
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
gcc_checking_assert (!root->grp_scalar_read
&& !root->grp_assignment_read);
sth_created = true;
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
{
root->grp_to_be_debug_replaced = 1;
root->replacement_decl = create_access_replacement (root);
/* If this is a store into a variable that is being optimized away,
add a debug bind stmt if possible. */
- if (MAY_HAVE_DEBUG_STMTS
+ if (MAY_HAVE_DEBUG_BIND_STMTS
&& gimple_assign_single_p (stmt)
&& is_gimple_val (gimple_assign_rhs1 (stmt)))
{
tree def = info->iv->ssa_name;
- if (MAY_HAVE_DEBUG_STMTS && SSA_NAME_DEF_STMT (def))
+ if (MAY_HAVE_DEBUG_BIND_STMTS && SSA_NAME_DEF_STMT (def))
{
imm_use_iterator imm_iter;
use_operand_p use_p;
{
gimple *stmt = gsi_stmt (*gsi);
- if (!MAY_HAVE_DEBUG_STMTS || gimple_code (stmt) == GIMPLE_PHI)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS || gimple_code (stmt) == GIMPLE_PHI)
return gsi_remove (gsi, true);
gimple_stmt_iterator prev = *gsi;
if (nr_bbs_removed_total > 0)
{
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
{
calculate_dominance_info (CDI_DOMINATORS);
update_debug_stmts ();
void
propagate_threaded_block_debug_into (basic_block dest, basic_block src)
{
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return;
if (!single_pred_p (dest))
void
gimple_replace_ssa_lhs (gimple *stmt, tree nlhs)
{
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
{
tree lhs = gimple_get_lhs (stmt);
tree
target_for_debug_bind (tree var)
{
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return NULL_TREE;
if (TREE_CODE (var) == SSA_NAME)
int usecount = 0;
tree value = NULL;
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return;
/* If this name has already been registered for replacement, do nothing
ssa_op_iter op_iter;
def_operand_p def_p;
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return;
stmt = gsi_stmt (*gsi);
imm_use_iterator imm_iter;
gimple *use_stmt;
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return;
FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
int saved_ssa_name_version = SSA_NAME_VERSION (var);
use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
insert_debug_temp_for_var_def (NULL, var);
if (flag_checking)
static void
adjust_vec_debug_stmts (void)
{
- if (!MAY_HAVE_DEBUG_STMTS)
+ if (!MAY_HAVE_DEBUG_BIND_STMTS)
return;
gcc_assert (adjust_vec.exists ());
{
adjust_info ai;
- if (MAY_HAVE_DEBUG_STMTS
+ if (MAY_HAVE_DEBUG_BIND_STMTS
&& TREE_CODE (from) == SSA_NAME
&& ! SSA_NAME_IS_DEFAULT_DEF (from)
&& ! virtual_operand_p (from))
SET_PHI_ARG_DEF (update_phi, e->dest_idx, new_def);
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
adjust_debug_stmts (orig_def, PHI_RESULT (update_phi),
gimple_bb (update_phi));
}
create_lcssa_for_virtual_phi (loop);
update_ssa (TODO_update_ssa_only_virtuals);
- if (MAY_HAVE_DEBUG_STMTS)
+ if (MAY_HAVE_DEBUG_BIND_STMTS)
{
gcc_assert (!adjust_vec.exists ());
adjust_vec.create (32);
if (!stmt_info)
continue;
- if (MAY_HAVE_DEBUG_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
+ if (MAY_HAVE_DEBUG_BIND_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
vect_loop_kill_debug_uses (loop, phi);
if (!STMT_VINFO_RELEVANT_P (stmt_info)
continue;
}
- if (MAY_HAVE_DEBUG_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
+ if (MAY_HAVE_DEBUG_BIND_STMTS && !STMT_VINFO_LIVE_P (stmt_info))
vect_loop_kill_debug_uses (loop, stmt);
if (!STMT_VINFO_RELEVANT_P (stmt_info)
#define VL_EXP_OPERAND_LENGTH(NODE) \
((int)TREE_INT_CST_LOW (VL_EXP_CHECK (NODE)->exp.operands[0]))
+/* Nonzero if gimple_debug_nonbind_marker_p() may possibly hold. */
+#define MAY_HAVE_DEBUG_MARKER_STMTS 0 /* debug_nonbind_markers_p */
+/* Nonzero if gimple_debug_bind_p() (and thus
+ gimple_debug_source_bind_p()) may possibly hold. */
+#define MAY_HAVE_DEBUG_BIND_STMTS flag_var_tracking_assignments
/* Nonzero if is_gimple_debug() may possibly hold. */
-#define MAY_HAVE_DEBUG_STMTS (flag_var_tracking_assignments)
+#define MAY_HAVE_DEBUG_STMTS \
+ (MAY_HAVE_DEBUG_MARKER_STMTS || MAY_HAVE_DEBUG_BIND_STMTS)
/* In a LOOP_EXPR node. */
#define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
{
insn = next;
next = NEXT_INSN (insn);
- if (DEBUG_INSN_P (insn))
+ if (DEBUG_BIND_INSN_P (insn))
{
loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
dest, propagate_for_debug_subst, &p);
if (tem == NULL_RTX)
tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
finish_subreg:
- if (MAY_HAVE_DEBUG_INSNS
+ if (MAY_HAVE_DEBUG_BIND_INSNS
&& GET_CODE (tem) == SUBREG
&& (GET_CODE (SUBREG_REG (tem)) == PLUS
|| GET_CODE (SUBREG_REG (tem)) == MINUS
{
tree decl;
- if (!MAY_HAVE_DEBUG_INSNS)
+ if (!MAY_HAVE_DEBUG_BIND_INSNS)
return NOT_ONEPART;
if (dv_is_value_p (dv))
EXECUTE_IF_SET_IN_HARD_REG_SET (invalidated_regs, 0, r, hrsi)
var_regno_delete (set, r);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
set->traversed_vars = set->vars;
shared_hash_htab (set->vars)
variable names such as VALUEs (never happens) or
DEBUG_EXPRs (only happens in the presence of debug
insns). */
- && (!MAY_HAVE_DEBUG_INSNS
+ && (!MAY_HAVE_DEBUG_BIND_INSNS
|| !rtx_debug_expr_p (XEXP (loc, 0))))
return MO_USE;
else
dataflow_set_copy (&old_out, out);
dataflow_set_copy (out, in);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
local_get_addr_cache = new hash_map<rtx, rtx>;
FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
}
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
delete local_get_addr_cache;
local_get_addr_cache = NULL;
else
oldinsz = oldoutsz = 0;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
bool first = true, adjust = false;
if (htabmax && htabsz > htabmax)
{
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
inform (DECL_SOURCE_LOCATION (cfun->decl),
"variable tracking size limit exceeded with "
"-fvar-tracking-assignments, retrying without");
}
}
- if (success && MAY_HAVE_DEBUG_INSNS)
+ if (success && MAY_HAVE_DEBUG_BIND_INSNS)
FOR_EACH_BB_FN (bb, cfun)
gcc_assert (VTI (bb)->flooded);
struct expand_loc_callback_data data;
rtx result;
- if (!MAY_HAVE_DEBUG_INSNS)
+ if (!MAY_HAVE_DEBUG_BIND_INSNS)
return loc;
INIT_ELCD (data, vars);
if (!changed_variables->elements ())
return;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
process_changed_values (htab);
data.insn = insn;
delete_variable_part). */
emit_notes = true;
- if (MAY_HAVE_DEBUG_INSNS)
- {
- dropped_values = new variable_table_type (cselib_get_next_uid () * 2);
- }
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
+ dropped_values = new variable_table_type (cselib_get_next_uid () * 2);
dataflow_set_init (&cur);
subsequent basic blocks. */
emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
local_get_addr_cache = new hash_map<rtx, rtx>;
/* Emit the notes for the changes in the basic block itself. */
emit_notes_in_bb (bb, &cur);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
delete local_get_addr_cache;
local_get_addr_cache = NULL;
dataflow_set_destroy (&cur);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
delete dropped_values;
dropped_values = NULL;
cfa_base_rtx = NULL_RTX;
return;
}
- if (!MAY_HAVE_DEBUG_INSNS)
+ if (!MAY_HAVE_DEBUG_BIND_INSNS)
return;
/* Tell alias analysis that cfa_base_rtx should share
VTI (bb)->permp = NULL;
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
scratch_regs = BITMAP_ALLOC (NULL);
global_get_addr_cache = NULL;
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
rtx reg, expr;
int ofst;
HOST_WIDE_INT pre, post = 0;
basic_block first_bb, last_bb;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
cselib_record_sets_hook = add_with_sets;
if (dump_file && (dump_flags & TDF_DETAILS))
cselib_hook_called = false;
adjust_insn (bb, insn);
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
if (CALL_P (insn))
prepare_call_arguments (bb, insn);
vt_init_cfa_base ();
hard_frame_pointer_adjustment = fp_cfa_offset;
/* Disassociate sp from fp now. */
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
cselib_val *v;
cselib_invalidate_rtx (stack_pointer_rtx);
bb = last_bb;
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
cselib_preserve_only_values ();
cselib_reset_table (cselib_get_next_uid ());
location_chain_pool.release ();
shared_hash_pool.release ();
- if (MAY_HAVE_DEBUG_INSNS)
+ if (MAY_HAVE_DEBUG_BIND_INSNS)
{
if (global_get_addr_cache)
delete global_get_addr_cache;