diff mbox

[PR58479] introduce a param to limit debug stmts count

Message ID orha6vm0rr.fsf@livre.home
State New
Headers show

Commit Message

Alexandre Oliva March 19, 2014, 1:32 a.m. UTC
On Mar 18, 2014, Jakub Jelinek <jakub@redhat.com> wrote:

>> --- 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);

> Dunno how this plays together with __attribute__((optimize(...))),
> I'm afraid not very well.

MAY_HAVE_DEBUG_STMTS (and MAY_HAVE_DEBUG_INSNS) used to be defined like
that, this just saves that status in a per-function data structure.  I
suppose this makes it easier to take other per-function directives into
account, but I haven't done that myself.

>> +  if (code == GIMPLE_DEBUG)
>> +    {  
>> +      gcc_checking_assert (MAY_HAVE_DEBUG_STMTS);
>> +      cfun->debug_stmts++;
>> +    }

> I'd strongly prefer it you could move this hunk to
> gimple_build_debug_bind_stat and gimple_build_debug_source_bind_stat,

That's where I put it at first, but it didn't fix the loop unrolling
testcase, because duplicate_bb, used for loop unrolling, and other paths
use gimple_alloc instead of specific functions to allocate copies of
existing stmts.


After posting the patchset, I got a failure to compile reflect-go with
the limit set to 20 on i686.  The problem was in
maybe_move_debug_stmts_to_successors, that removed debug stmts that were
in the debug_stmts vec, to be remapped later, and when they got
remapped, they were updated (even though they were removed) and SSA DEFs
ended up linking to the removed stmt, that later got GCed.  Oops.
So I went back to an earlier version of that hunk, that moved the stmts
instead of removing them.

This is the fixed patch, that I'm finishing testing along with the other
two unmodified patches, with various limits.  Is this ok to install?

I'm afraid I won't be able to work on this any further, because tomorrow
I'm going to fly to travel to the US for LibrePlanet, and when I return
I'm supposed to get back to glibc.  If this doesn't go in as is and
nobody else picks it up, it will have to wait until I get another time
slot for GCC.
diff mbox

Patch

Optimize debug stmt generation after limit is exceeded

From: Alexandre Oliva <aoliva@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.  Check that debug stmts don't get to where
	we don't expect them.
	(maybe_move_debug_stmts_to_successors): Move trailing debug
	stmts to any successor if we're past the limit.  Avoid
	confusing reuse of variable si.
	(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_debug_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            |   10 +++++-----
 gcc/tree-cfg.c             |    7 ++++++-
 gcc/tree-inline.c          |   30 +++++++++++++++++-------------
 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, 53 insertions(+), 36 deletions(-)

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 9f144fa..0d196b4 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..6d9fc44 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)
@@ -1344,7 +1344,7 @@  split_function (struct split_point *split_point)
 	  while (var != NULL_TREE
 		 && DECL_ABSTRACT_ORIGIN (var) != (**debug_args)[i])
 	    var = TREE_CHAIN (var);
-	  if (var == NULL_TREE)
+	  if (var == NULL_TREE || !BUILD_DEBUG_STMTS_P)
 	    break;
 	  vexpr = make_node (DEBUG_EXPR_DECL);
 	  parm = (**debug_args)[i];
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..a17d47d 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);
@@ -1542,6 +1547,8 @@  remap_gimple_stmt (gimple stmt, copy_body_data *id)
 	  }
     }
 
+  gcc_checking_assert (!is_gimple_debug (copy));
+
   /* If STMT has a block defined, map it to the newly constructed
      block.  */
   if (gimple_block (copy))
@@ -1552,9 +1559,6 @@  remap_gimple_stmt (gimple stmt, copy_body_data *id)
       gimple_set_block (copy, *n);
     }
 
-  if (gimple_debug_bind_p (copy) || gimple_debug_source_bind_p (copy))
-    return copy;
-
   /* Remap all the operands in COPY.  */
   memset (&wi, 0, sizeof (wi));
   wi.info = id;
@@ -1617,7 +1621,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);
@@ -2274,15 +2278,15 @@  maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
 	  tree var;
 	  tree value;
 
-	  /* For the last edge move the debug stmts instead of copying
-	     them.  */
-	  if (ei_one_before_end_p (ei))
+	  /* For the last edge, or if we're not to create more debug
+	     stmts, move the debug stmts instead of copying them.  */
+	  if (ei_one_before_end_p (ei) || !BUILD_DEBUG_STMTS_P)
 	    {
-	      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 +2772,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 +2828,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