This bug report had various testcases that had to do with full loop
unrolling with non-automatic iterators and fixed boundaries, which
resulted in duplicating debug stmts in the loop for each iteration.  In
some cases, the resulting executable code is none, but the debug stmts
add up to millions.  Just dropping them on the floor is somewhat
undesirable, even though they're not usable for much with today's
compiler and debugger infrastructure.  I decided to introduce a param to
limit debug stmts, so that this sort of testcase doesn't run nearly
forever, eating up all memory while at that.  This is what this patchset
does.

The first patch introduces the parameter (defaulting to no limit) and
the infrastructure around it.  I decided to only detect that the limit
was exceeded and clean up existing debug stmts at pass boundaries, so
that no pass would be surprised by a failure to create a debug stmt
where it used to be possible to do so.

The second patch addresses the actual problem in some passes,
particularly in the code that copies basic blocks, used by the loop
unroller, by testing regularly whether building more debug stmts is
desirable.  They will still collect debug stmts only at the end of the
pass, since there's not much reason to rush to do that.

The third patch enables the limit by default.  I played a bit with lower
values, and on i686 and x86_64, I could build all of stage3, with all
languages enabled, without any debug info degradation, with the limit
set as low as 25000, so 1 million is a very conservative limit.
fold-const, the largest debug stmt builder, builds a total of 24382
debug stmts, and with the limit at 10000, fold_binary_loc is still the
only function that VTA disabled because the limit is reached.  At 4000,
there are only some 20 functions in the entire stage3 (host and target
libs) that get degradation.  fold-const.c:fold_comparison and
tree-browser.c:browse_tree got my attention because they built a few
hundred debug stmts more than the limit set, indicating there are other
passes that may still benefit from BUILD_DEBUG_STMTS_P testing, but I
haven't investigated any further.

Regstrapped incrementally (first patch alone, first and second, and all
3) on i686- and x86_64-linux-gnu.  Ok to install?

Introduce --param max-vartrack-debug-stmts

From: Alexandre Oliva <aol...@redhat.com>

for  gcc/ChangeLog

	PR debug/58479
	* cfgexpand.c (expand_gimple_basic_block): Check that
	MAY_HAVE_DEBUG_STMTS remains true when expanding debug stmts.
	* doc/invoke.texi (max-vartrack-debug-stmts): New param.
	* function.c (allocate_struct_function): Initialize
	debug_stmts enabler and counter based on
	flag_var_tracking_assignments.
	* function.h (struct function): Add debug_stmts counter.
	* gimple.c (gimple_alloc_stat): Check enablement and increment
	counter when code is GIMPLE_DEBUG.
	(gimple_collect_debug_stmts): New function.
	* gimple.h (gimple_collect_debug_stmts): Declare.
	* lto-streamer-in.c (input_function): Enable debug stmts while
	reading stmts.  Simplify their removal.
	* params.def (PARAM_MAX_DEBUG_STMTS): New.
	* passes.c (execute_one_pass): Collect debug stmts after
	gimple passes if we reached the limit.
	* rtl.h (MAY_HAVE_DEBUG_INSNS): Base on debug_stmts counter.
	* tree.h (MAY_HAVE_DEBUG_STMTS): Likewise.
	(BUILD_DEBUG_STMTS_P, SET_BUILD_DEBUG_STMTS): New macros.
---
 gcc/cfgexpand.c       |    4 ++++
 gcc/doc/invoke.texi   |    8 ++++++++
 gcc/function.c        |    2 ++
 gcc/function.h        |    7 +++++++
 gcc/gimple.c          |   40 +++++++++++++++++++++++++++++++++++++++-
 gcc/gimple.h          |    1 +
 gcc/lto-streamer-in.c |   18 ++++++++++++------
 gcc/params.def        |    8 ++++++++
 gcc/passes.c          |    4 ++++
 gcc/rtl.h             |    2 +-
 gcc/tree.h            |   21 +++++++++++++++++++--
 11 files changed, 105 insertions(+), 10 deletions(-)

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index dd163a5..783b928 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -5024,6 +5024,8 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
 	}
       else if (gimple_debug_bind_p (stmt))
 	{
+	  gcc_checking_assert (MAY_HAVE_DEBUG_STMTS);
+
 	  location_t sloc = curr_insn_location ();
 	  gimple_stmt_iterator nsi = gsi;
 
@@ -5088,6 +5090,8 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
 	}
       else if (gimple_debug_source_bind_p (stmt))
 	{
+	  gcc_checking_assert (MAY_HAVE_DEBUG_STMTS);
+
 	  location_t sloc = curr_insn_location ();
 	  tree var = gimple_debug_source_bind_get_var (stmt);
 	  tree value = gimple_debug_source_bind_get_value (stmt);
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 24bd76e..3e26fc3 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -9950,6 +9950,14 @@ debug information may end up not being used; setting this higher may
 enable the compiler to find more complex debug expressions, but compile
 time and memory use may grow.  The default is 12.
 
+@item max-vartrack-debug-stmts
+Sets a maximum number of debug stmts to be built in a function before
+@option{-fvar-tracking-assignments} is disabled.  After the limit is
+reached, additional debug stmts may be built, until a collection point
+is reached, where all debug stmts in the function are garbage collected
+and no further debug stmts can be built for the function.  The default
+is 0, that stands for no limit.
+
 @item min-nondebug-insn-uid
 Use uids starting at this parameter for nondebug insns.  The range below
 the parameter is reserved exclusively for debug insns created by
diff --git a/gcc/function.c b/gcc/function.c
index e67d3c1..084a966 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4498,6 +4498,8 @@ allocate_struct_function (tree fndecl, bool abstract_p)
 
   cfun = ggc_alloc_cleared_function ();
 
+  SET_BUILD_DEBUG_STMTS (cfun, flag_var_tracking_assignments);
+
   init_eh_for_function ();
 
   if (init_machine_status)
diff --git a/gcc/function.h b/gcc/function.h
index 38a0fc4..09df936 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -555,6 +555,13 @@ struct GTY(()) function {
   /* In a Cilk function, the VAR_DECL for the frame descriptor. */
   tree cilk_frame_decl;
 
+  /* The number of debug_stmts ever emitted in a function.  Minus one
+     if flag_var_tracking_assignments is disabled, from the command
+     line or because PARAM_MAX_DEBUG_STMTS was exceeded and
+     previously-emitted debug stmts have been cleaned up by
+     gimple_collect_debug_stmts.  */
+  int debug_stmts;
+
   /* For md files.  */
 
   /* tm.h can use this to store whatever it likes.  */
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e9851ca..6da89d2f 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -47,7 +47,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "demangle.h"
 #include "langhooks.h"
 #include "bitmap.h"
-
+#include "params.h"
 
 /* All the tuples have their operand vector (if present) at the very bottom
    of the structure.  Therefore, the offset required to find the
@@ -121,6 +121,12 @@ gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL)
   size_t size;
   gimple stmt;
 
+  if (code == GIMPLE_DEBUG)
+    {  
+      gcc_checking_assert (MAY_HAVE_DEBUG_STMTS);
+      cfun->debug_stmts++;
+    }
+
   size = gimple_size (code);
   if (num_ops > 0)
     size += sizeof (tree) * (num_ops - 1);
@@ -799,6 +805,38 @@ gimple_build_debug_source_bind_stat (tree var, tree value,
 }
 
 
+/* If the debug stmts limit was exceeded, clean them all up and make
+   sure we don't have any more of these in the function.  */
+
+void
+gimple_collect_debug_stmts (void)
+{
+  if (!MAY_HAVE_DEBUG_STMTS || BUILD_DEBUG_STMTS_P)
+    return;
+
+  inform (DECL_SOURCE_LOCATION (current_function_decl),
+	  "disabling -fvar-tracking-assignments after %i debug stmts",
+	  cfun->debug_stmts);
+
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, cfun)
+    {
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
+	   !gsi_end_p (gsi);)
+	{
+	  gimple stmt = gsi_stmt (gsi);
+	  if (is_gimple_debug (stmt))
+	    gsi_remove (&gsi, true);
+	  else
+	    gsi_next (&gsi);
+	}
+    }
+
+  cfun->debug_stmts = -1;
+}
+
+
 /* Build a GIMPLE_OMP_CRITICAL statement.
 
    BODY is the sequence of statements for which only one thread can execute.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 0e80d2e..d943d72 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1264,6 +1264,7 @@ extern bool infer_nonnull_range (gimple, tree, bool, bool);
 extern void sort_case_labels (vec<tree> );
 extern void preprocess_case_label_vec_for_gimple (vec<tree> , tree, tree *);
 extern void gimple_seq_set_location (gimple_seq , location_t);
+extern void gimple_collect_debug_stmts (void);
 
 /* Formal (expression) temporary table handling: multiple occurrences of
    the same scalar expression are evaluated into the same temporary.  */
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index da248b9..a834749 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -943,6 +943,13 @@ input_function (tree fn_decl, struct data_in *data_in,
   gcc_assert (DECL_INITIAL (fn_decl));
   DECL_SAVED_TREE (fn_decl) = NULL_TREE;
 
+  /* If we're reading streamed stmts with debug stmts, but we don't
+     want them, we have to temporarily enable them so that they can be
+     allocated without assertion failures.  We'll */
+  bool debug_stmts = MAY_HAVE_DEBUG_STMTS;
+  if (!debug_stmts)
+    SET_BUILD_DEBUG_STMTS (cfun, true);
+
   /* Read all the basic blocks.  */
   tag = streamer_read_record_start (ib);
   while (tag)
@@ -988,12 +995,8 @@ input_function (tree fn_decl, struct data_in *data_in,
 	     We can't remove them earlier because this would cause uid
 	     mismatches in fixups, but we can do it at this point, as
 	     long as debug stmts don't require fixups.  */
-	  if (!MAY_HAVE_DEBUG_STMTS && is_gimple_debug (stmt))
-	    {
-	      gimple_stmt_iterator gsi = bsi;
-	      gsi_next (&bsi);
-	      gsi_remove (&gsi, true);
-	    }
+	  if (!debug_stmts && is_gimple_debug (stmt))
+	    gsi_remove (&bsi, true);
 	  else
 	    {
 	      gsi_next (&bsi);
@@ -1002,6 +1005,9 @@ input_function (tree fn_decl, struct data_in *data_in,
 	}
     }
 
+  if (!debug_stmts)
+    SET_BUILD_DEBUG_STMTS (cfun, false);
+
   /* Set the gimple body to the statement sequence in the entry
      basic block.  FIXME lto, this is fairly hacky.  The existence
      of a gimple body is used by the cgraph routines, but we should
diff --git a/gcc/params.def b/gcc/params.def
index dd2e2cd..47d3900 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -909,6 +909,14 @@ DEFPARAM (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE,
 	  "Max. size of loc list for which reverse ops should be added",
 	  50, 0, 0)
 
+/* Set maximum number of debug stmts to be emitted in a function.
+   Zero disables the limit.  */
+
+DEFPARAM (PARAM_MAX_DEBUG_STMTS,
+	  "max-vartrack-debug-stmts",
+	  "Max. per-function number of debug stmts before VTA is disabled",
+	  0, 0, 0)
+
 /* Set minimum insn uid for non-debug insns.  */
 
 DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
diff --git a/gcc/passes.c b/gcc/passes.c
index 60fb135..3f460d7 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2234,6 +2234,10 @@ execute_one_pass (opt_pass *pass)
   if (pass->tv_id != TV_NONE)
     timevar_pop (pass->tv_id);
 
+  if (pass->type == GIMPLE_PASS && MAY_HAVE_DEBUG_STMTS
+      && !BUILD_DEBUG_STMTS_P)
+    gimple_collect_debug_stmts ();
+
   do_per_function (update_properties_after_pass, pass);
 
   if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
diff --git a/gcc/rtl.h b/gcc/rtl.h
index f1cda4c0..9209b2c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -457,7 +457,7 @@ struct GTY((variable_size)) rtvec_def {
 #define NONDEBUG_INSN_P(X) (INSN_P (X) && !DEBUG_INSN_P (X))
 
 /* Nonzero if DEBUG_INSN_P may possibly hold.  */
-#define MAY_HAVE_DEBUG_INSNS (flag_var_tracking_assignments)
+#define MAY_HAVE_DEBUG_INSNS (cfun->debug_stmts >= 0)
 
 /* Predicate yielding nonzero iff X is a real insn.  */
 #define INSN_P(X) \
diff --git a/gcc/tree.h b/gcc/tree.h
index 0dc8d0d..c257926 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1010,8 +1010,25 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define VL_EXP_OPERAND_LENGTH(NODE) \
   ((int)TREE_INT_CST_LOW (VL_EXP_CHECK (NODE)->exp.operands[0]))
 
-/* Nonzero if is_gimple_debug() may possibly hold.  */
-#define MAY_HAVE_DEBUG_STMTS    (flag_var_tracking_assignments)
+/* True iff is_gimple_debug() may possibly hold.  Testing for strictly
+   positive values might make sense, but there may still be code that
+   uses MAY_HAVE_DEBUG_STMTS, instead of BUILD_DEBUG_STMTS_P, to
+   decide whether to build debug stmts, and this keeps it working.
+   BUILD_DEBUG_STMTS_P itself uses this macro, so that this is not
+   changed lightly.  */
+#define MAY_HAVE_DEBUG_STMTS    (cfun->debug_stmts >= 0)
+/* True iff more debug stmts should be built.
+   Users of this macro must #include "params.h".  */
+#define BUILD_DEBUG_STMTS_P						\
+  (MAY_HAVE_DEBUG_STMTS							\
+   && (!PARAM_VALUE (PARAM_MAX_DEBUG_STMTS)				\
+       || cfun->debug_stmts <= PARAM_VALUE (PARAM_MAX_DEBUG_STMTS)))
+/* Initialize debug_stmts so that MAY_HAVE_DEBUG_STMTS evaluates to
+   VAL within CFUN.  This will enable debug stmts to be built, even
+   temporarily, and will get BUILD_DEBUG_STMTS_P to evaluate to VAL at
+   least once before the limit is reached.  */
+#define SET_BUILD_DEBUG_STMTS(cfun, val) \
+  do (cfun)->debug_stmts = (val) ? 0 : -1; while (0)
 
 /* In a LOOP_EXPR node.  */
 #define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
Optimize debug stmt generation after limit is exceeded

From: Alexandre Oliva <aol...@redhat.com>

for  gcc/ChangeLog

	PR debug/58479
	* ipa-prop.c (ipa_modify_call_arguments): Don't build new
	debug stmts if BUILD_DEBUG_STMTS_P doesn't hold any more.
	* ipa-split.c (split_function): Likewise.
	* tree-cfg.c (gimple_merge_blocks): Likewise.
	(gimple_duplicate_bb): Likewise.
	* tree-inline.c (remap_ssa_name): Likewise.
	(remap_gimple_seq, copy_bb): Tolerate that...
	(remap_gimple_stmt): ... return NULL after the debug stmt
	limit is reached.
	(maybe_move_debug_stmts_to_successors): Delete trailing debug
	stmts needing cleanup if we're past the limit.  Avoid
	confusing reuse of variable.
	(insert_init_debug_bind): Don't build debug stmts past the
	limit.
	(insert_init_stmt): Likewise.
	* tree-into-ssa.c (insert_phi_nodes_for): Likewise.
	(rewrite_debug_stmt_uses): Likewise.
	(rewrite_stmt): Likewise.
	(maybe_register_def): Likewise.
	* tree-sra.c (generate_subtree_copies): Likewise.
	(init_subtree_with_zero): Likewise.
	(sra_modify_expr): Likewise.
	(load_assign_lhs_subreplacements): Likewise.
	(sra_modify_assign): Likewise.
	(sra_ipa_reset_dbeug_stmts): Likewise.
	* tree-ssa-dce.c (remove_dead_stmt): Likewise.
	* tree-ssa-loop-ivopts.c (remove_unused_ivs): Likewise.
	* tree-ssa.c (insert_debug_temp_for_var_def): Likewise.
---
 gcc/ipa-prop.c             |    2 +-
 gcc/ipa-split.c            |    8 ++++----
 gcc/tree-cfg.c             |    7 ++++++-
 gcc/tree-inline.c          |   31 ++++++++++++++++++++++++-------
 gcc/tree-into-ssa.c        |   17 ++++++++++-------
 gcc/tree-sra.c             |   15 +++++++++------
 gcc/tree-ssa-dce.c         |    3 ++-
 gcc/tree-ssa-loop-ivopts.c |    2 +-
 gcc/tree-ssa.c             |    3 ++-
 9 files changed, 59 insertions(+), 29 deletions(-)

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 4fb916a..a175ae3 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -3823,7 +3823,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
 	    }
 	  vargs.quick_push (expr);
 	}
-      if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
+      if (adj->op != IPA_PARM_OP_COPY && BUILD_DEBUG_STMTS_P)
 	{
 	  unsigned int ix;
 	  tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 38bd8836..75fc9d6 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1300,11 +1300,11 @@ split_function (struct split_point *split_point)
 	  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 debug 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)
+	  if (!BUILD_DEBUG_STMTS_P)
 	    continue;
 
 	  if (debug_args == NULL)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 56b6c35..d869c3a 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-live.h"
 #include "omp-low.h"
 #include "tree-cfgcleanup.h"
+#include "params.h"
 
 /* This file contains functions for building the Control Flow Graph (CFG)
    for a function tree.  */
@@ -1841,7 +1842,7 @@ gimple_merge_blocks (basic_block a, basic_block b)
 	      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) && BUILD_DEBUG_STMTS_P)
 	    {
 	      gimple dbg = gimple_build_debug_bind (label,
 						    integer_zero_node,
@@ -5702,6 +5703,10 @@ gimple_duplicate_bb (basic_block bb)
       if (gimple_code (stmt) == GIMPLE_LABEL)
 	continue;
 
+      /* Don't copy debug stmts if we have too many of them already.  */
+      if (is_gimple_debug (stmt) && !BUILD_DEBUG_STMTS_P)
+	continue;
+
       /* Don't duplicate label debug stmts.  */
       if (gimple_debug_bind_p (stmt)
 	  && TREE_CODE (gimple_debug_bind_get_var (stmt))
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index fc83097..aef8dbd 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -202,7 +202,7 @@ remap_ssa_name (tree name, copy_body_data *id)
 
   if (processing_debug_stmt)
     {
-      if (SSA_NAME_IS_DEFAULT_DEF (name)
+      if (BUILD_DEBUG_STMTS_P && SSA_NAME_IS_DEFAULT_DEF (name)
 	  && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL
 	  && id->entry_bb == NULL
 	  && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
@@ -733,7 +733,8 @@ remap_gimple_seq (gimple_seq body, copy_body_data *id)
   for (si = gsi_start (body); !gsi_end_p (si); gsi_next (&si))
     {
       gimple new_stmt = remap_gimple_stmt (gsi_stmt (si), id);
-      gimple_seq_add_stmt (&new_body, new_stmt);
+      if (new_stmt)
+	gimple_seq_add_stmt (&new_body, new_stmt);
     }
 
   return new_body;
@@ -1467,6 +1468,8 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
 
       if (gimple_debug_bind_p (stmt))
 	{
+	  if (!BUILD_DEBUG_STMTS_P)
+	    return NULL;
 	  copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
 					  gimple_debug_bind_get_value (stmt),
 					  stmt);
@@ -1475,6 +1478,8 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
 	}
       if (gimple_debug_source_bind_p (stmt))
 	{
+	  if (!BUILD_DEBUG_STMTS_P)
+	    return NULL;
 	  copy = gimple_build_debug_source_bind
 		   (gimple_debug_source_bind_get_var (stmt),
 		    gimple_debug_source_bind_get_value (stmt), stmt);
@@ -1617,7 +1622,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
 
       id->regimplify = false;
       stmt = remap_gimple_stmt (stmt, id);
-      if (gimple_nop_p (stmt))
+      if (!stmt || gimple_nop_p (stmt))
 	continue;
 
       gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
@@ -2264,6 +2269,18 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
 	   || stmt_can_make_abnormal_goto (gsi_stmt (si))))
     return;
 
+  /* If we're going to just drop all debug stmts at the end,
+     don't bother with copying or moving them.  We can't leave
+     them in place, though, so remove them right away.  */
+  if (!BUILD_DEBUG_STMTS_P)
+    {
+      gsi_next (&si);
+      do
+	gsi_remove (&si, true);
+      while (!gsi_end_p (si));
+      return;
+    }
+
   FOR_EACH_EDGE (e, ei, new_bb->succs)
     {
       gimple_stmt_iterator ssi = gsi_last_bb (new_bb);
@@ -2278,11 +2295,11 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
 	     them.  */
 	  if (ei_one_before_end_p (ei))
 	    {
-	      si = ssi;
+	      gimple_stmt_iterator rsi = ssi;
 	      gsi_prev (&ssi);
 	      if (!single_pred_p (e->dest) && gimple_debug_bind_p (stmt))
 		gimple_debug_bind_reset_value (stmt);
-	      gsi_remove (&si, false);
+	      gsi_remove (&rsi, false);
 	      gsi_insert_before (&dsi, stmt, GSI_SAME_STMT);
 	      continue;
 	    }
@@ -2768,7 +2785,7 @@ insert_init_debug_bind (copy_body_data *id,
   if (!gimple_in_ssa_p (id->src_cfun))
     return NULL;
 
-  if (!MAY_HAVE_DEBUG_STMTS)
+  if (!BUILD_DEBUG_STMTS_P)
     return NULL;
 
   tracked_var = target_for_debug_bind (var);
@@ -2824,7 +2841,7 @@ insert_init_stmt (copy_body_data *id, basic_block bb, gimple init_stmt)
       gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
       gimple_regimplify_operands (init_stmt, &si);
 
-      if (!is_gimple_debug (init_stmt) && MAY_HAVE_DEBUG_STMTS)
+      if (!is_gimple_debug (init_stmt) && BUILD_DEBUG_STMTS_P)
 	{
 	  tree def = gimple_assign_lhs (init_stmt);
 	  insert_init_debug_bind (id, bb, def, def, init_stmt);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 3ca2bd1..5741f55 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1042,12 +1042,13 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
 	}
       else
 	{
-	  tree tracked_var;
+	  tree tracked_var = NULL_TREE;
 
 	  gcc_checking_assert (DECL_P (var));
 	  phi = create_phi_node (var, bb);
 
-	  tracked_var = target_for_debug_bind (var);
+	  if (BUILD_DEBUG_STMTS_P)
+	    tracked_var = target_for_debug_bind (var);
 	  if (tracked_var)
 	    {
 	      gimple note = gimple_build_debug_bind (tracked_var,
@@ -1221,7 +1222,7 @@ rewrite_debug_stmt_uses (gimple stmt)
       def = info->current_def;
       if (!def)
 	{
-	  if (TREE_CODE (var) == PARM_DECL
+	  if (BUILD_DEBUG_STMTS_P && TREE_CODE (var) == PARM_DECL
 	      && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
 	    {
 	      gimple_stmt_iterator gsi
@@ -1351,7 +1352,7 @@ rewrite_stmt (gimple_stmt_iterator *si)
       {
 	tree var = DEF_FROM_PTR (def_p);
 	tree name;
-	tree tracked_var;
+	tree tracked_var = NULL_TREE;
 
 	gcc_checking_assert (DECL_P (var));
 
@@ -1371,7 +1372,8 @@ rewrite_stmt (gimple_stmt_iterator *si)
 	SET_DEF (def_p, name);
 	register_new_def (DEF_FROM_PTR (def_p), var);
 
-	tracked_var = target_for_debug_bind (var);
+	if (BUILD_DEBUG_STMTS_P)
+	  tracked_var = target_for_debug_bind (var);
 	if (tracked_var)
 	  {
 	    gimple note = gimple_build_debug_bind (tracked_var, name, stmt);
@@ -1837,12 +1839,13 @@ maybe_register_def (def_operand_p def_p, gimple stmt,
     {
       if (DECL_P (def))
 	{
-	  tree tracked_var;
+	  tree tracked_var = NULL_TREE;
 
 	  def = make_ssa_name (def, stmt);
 	  SET_DEF (def_p, def);
 
-	  tracked_var = target_for_debug_bind (sym);
+	  if (BUILD_DEBUG_STMTS_P)
+	    tracked_var = target_for_debug_bind (sym);
 	  if (tracked_var)
 	    {
 	      gimple note = gimple_build_debug_bind (tracked_var, def, stmt);
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 284d544..09b4f73 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2630,6 +2630,7 @@ generate_subtree_copies (struct access *access, tree agg,
 	}
       else if (write
 	       && access->grp_to_be_debug_replaced
+	       && BUILD_DEBUG_STMTS_P
 	       && (chunk_size == 0
 		   || access->offset + access->size > start_offset))
 	{
@@ -2680,7 +2681,7 @@ init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
       update_stmt (stmt);
       gimple_set_location (stmt, loc);
     }
-  else if (access->grp_to_be_debug_replaced)
+  else if (access->grp_to_be_debug_replaced && BUILD_DEBUG_STMTS_P)
     {
       gimple ds = gimple_build_debug_bind (get_access_replacement (access),
 					   build_zero_cst (access->type),
@@ -2796,7 +2797,7 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
 	*expr = repl;
       sra_stats.exprs++;
     }
-  else if (write && access->grp_to_be_debug_replaced)
+  else if (write && access->grp_to_be_debug_replaced && BUILD_DEBUG_STMTS_P)
     {
       gimple ds = gimple_build_debug_bind (get_access_replacement (access),
 					   NULL_TREE,
@@ -2928,7 +2929,8 @@ load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
 	      && lacc->grp_read && !lacc->grp_covered)
 	    *refreshed = handle_unscalarized_data_in_subtree (top_racc,
 							      old_gsi);
-	  if (lacc && lacc->grp_to_be_debug_replaced)
+	  if (lacc && lacc->grp_to_be_debug_replaced
+	      && BUILD_DEBUG_STMTS_P)
 	    {
 	      gimple ds;
 	      tree drhs;
@@ -3157,7 +3159,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
 	}
     }
 
-  if (lacc && lacc->grp_to_be_debug_replaced)
+  if (lacc && lacc->grp_to_be_debug_replaced && BUILD_DEBUG_STMTS_P)
     {
       tree dlhs = get_access_replacement (lacc);
       tree drhs = unshare_expr (rhs);
@@ -4693,7 +4695,7 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
 	    /* All other users must have been removed by
 	       ipa_sra_modify_function_body.  */
 	    gcc_assert (is_gimple_debug (stmt));
-	    if (vexpr == NULL && gsip != NULL)
+	    if (vexpr == NULL && gsip != NULL && BUILD_DEBUG_STMTS_P)
 	      {
 		gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
 		vexpr = make_node (DEBUG_EXPR_DECL);
@@ -4737,7 +4739,8 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
 	    BLOCK_VARS (DECL_INITIAL (current_function_decl));
 	  BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
 	}
-      if (gsip != NULL && copy && target_for_debug_bind (adj->base))
+      if (gsip != NULL && copy && BUILD_DEBUG_STMTS_P
+	  && target_for_debug_bind (adj->base))
 	{
 	  gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
 	  if (vexpr)
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 13a71ce..e0c6a60 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
+#include "params.h"
 
 static struct stmt_stats
 {
@@ -1109,7 +1110,7 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb)
 
   /* 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 (BUILD_DEBUG_STMTS_P
       && gimple_assign_single_p (stmt)
       && is_gimple_val (gimple_assign_rhs1 (stmt)))
     {
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 14ba20f..dfe49bf 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -6566,7 +6566,7 @@ remove_unused_ivs (struct ivopts_data *data)
 	  
 	  tree def = info->iv->ssa_name;
 
-	  if (MAY_HAVE_DEBUG_STMTS && SSA_NAME_DEF_STMT (def))
+	  if (BUILD_DEBUG_STMTS_P && SSA_NAME_DEF_STMT (def))
 	    {
 	      imm_use_iterator imm_iter;
 	      use_operand_p use_p;
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 20f061f..40c758c 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "cfgloop.h"
 #include "cfgexpand.h"
+#include "params.h"
 
 /* Pointer map of variable mappings, keyed by edge.  */
 static struct pointer_map_t *edge_var_maps;
@@ -356,7 +357,7 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
   int usecount = 0;
   tree value = NULL;
 
-  if (!MAY_HAVE_DEBUG_STMTS)
+  if (!BUILD_DEBUG_STMTS_P)
     return;
 
   /* If this name has already been registered for replacement, do nothing
Limit max debug stmts by default

From: Alexandre Oliva <aol...@redhat.com>

for  gcc/ChangeLog

	PR debug/58479
	* params.def (PARAM_MAX_DEBUG_STMTS): Set default to 1,000,000.
	* doc/invoke.texi (max-vartrack-debug-stmts): Document it.
---
 gcc/doc/invoke.texi |    2 +-
 gcc/params.def      |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3e26fc3..0e2d714 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -9956,7 +9956,7 @@ Sets a maximum number of debug stmts to be built in a function before
 reached, additional debug stmts may be built, until a collection point
 is reached, where all debug stmts in the function are garbage collected
 and no further debug stmts can be built for the function.  The default
-is 0, that stands for no limit.
+is 1,000,000.  Setting it to zero makes it unlimited.
 
 @item min-nondebug-insn-uid
 Use uids starting at this parameter for nondebug insns.  The range below
diff --git a/gcc/params.def b/gcc/params.def
index 47d3900..398448c 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -915,7 +915,7 @@ DEFPARAM (PARAM_MAX_VARTRACK_REVERSE_OP_SIZE,
 DEFPARAM (PARAM_MAX_DEBUG_STMTS,
 	  "max-vartrack-debug-stmts",
 	  "Max. per-function number of debug stmts before VTA is disabled",
-	  0, 0, 0)
+	  1000000, 0, 0)
 
 /* Set minimum insn uid for non-debug insns.  */
 

-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist     Red Hat Brazil Toolchain Engineer

Reply via email to