This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PR debug/41343] introduce debug expr temps


On Oct  7, 2009, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Oct  6, 2009, Richard Guenther <richard.guenther@gmail.com> wrote:
>>> Anyhow, if we find it not to be true, it shouldn't be too hard to get
>>> debug temps into SSA operands, especially if we're to add vops to debug
>>> bind stmts as well.

>> Gah.  Over my dead body!

> :-)

>> Fair enough.  Mind adding a comment here?  Mind adding
>> a DEBUG_DECL_UID macro that encapsulates the negation?

> Will do.

The patch below introduces DEBUG_TEMP_UID, it removes debug temp bind
stmts without values during SSA updates (removing them upon reset would
invalidate iterators), and it avoids the creation of debug temp bind
stmts when the expressions are safe to move, i.e., if they refer to SSA
names or to constants.

So, given:

  a_1 = b_2;
  c_3 = -d_4;
  e_5 = f_6 + g_7;
  # DEBUG h => a_1
  # DEBUG i => c_3
  # DEBUG j => e_5
  # DEBUG k => a_1 + c_3
  # DEBUG l => -e_5

if a_1, c_3 and e_5 are removed, we'll emit:

  ;; (nothing for a_1 = b_2)
  # DEBUG D#1 => -d_4
  # DEBUG D#2 => f_6 + g_7
  # DEBUG h => b_2
  # DEBUG i => -d_4
  # DEBUG j => f_6 + g_7
  # DEBUG k => b_2 + D#1
  # DEBUG l => -D#2

i.e., if the SSA name whose DEF is being removed is by itself in a debug
bind stmt's value, we'll use the expression formerly assigned to the
DEF.  If it's not by itself, we'll only use the expression if it's an
SSA name or constant.

I also added the testcases from the bug reports, and I realized cselib
did not distinguish between different DEBUG_EXPR_DECLs, so I fixed that.

Here's the patch I'm testing now.  Ok to install if it regstraps?

for  gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41343
	PR debug/41447
	PR debug/41264
	PR debug/41338
	* tree.def (DEBUG_EXPR_DECL): New.
	* rtl.def (DEBUG_EXPR): New.
	* gengtype.c (adjust_field_rtx_def): Handle it.
	* tree-ssa.c (propagate_var_def_into_debug_stmts): Rename to...
	(insert_debug_temp_for_var_def): ... this.  Drop support for
	moving.  Take iterator for def stmt; insert debug stmt before it.
	(propagate_defs_into_debug_stmts): Rename to...
	(insert_debug_temps_for_defs): ... this.  Likewise.
	* tree.h (DEBUG_TEMP_UID): New.
	* tree.c (next_debug_decl_uid): New.
	(make_node_stat): Count debug decls separately.
	(copy_node_stat): Likewise.
	* cfgexpand.c (expand_debug_expr): Handle DEBUG_EXPR_DECL.
	* var-tracking.c (dv_is_decl_p): Recognize it.
	(VALUE_RECURSED_INTO): Apply to DEBUG_EXPRs too.
	(track_expr_p): Track expanded DEBUG_EXPR_DECLs.
	(vt_expand_loc_callback): Expand DEBUG_EXPRs.
	(emit_note_insn_var_location): Don't emit notes for DEBUG_EXPR_DECLs.
	* cselib.c (cselib_expand_value_rtx_1): Use callback for DEBUG_EXPR.
	* tree-ssa-operands.c (get_expr_operands): Skip DEBUG_EXPR_DECLs in
	debug bind stmts.
	* emit-rtl.c (verify_rtx_sharing): Handle DEBUG_EXPR and VALUE.
	(copy_rtx_if_shared_1, reset_used_flags, set_used_flags): Likewise.
	* rtl.c (copy_rtx): Likewise.
	(rtx_equal_p_cb, rtx_equal_p): Handle DEBUG_EXPR.
	* print-rtl.c (print_rtx): Likewise.
	* sched-vis.c (print_value): Likewise.
	(print_insn): Handle DEBUG_EXPR_DECL.
	* tree-dump.c (dequeue_and_dump): Likewise.
	* tree-pretty-print.c (dump_decl_name, dump_generic_node): Likewise.
	* gimple-iterator (gsi_replace, gsi_remove): Insert debug temps.
	* tree-ssa-loop-im.c (rewrite_bittest, move_computations_stmt): Drop
	propagation into debug stmts.
	* tree-ssa-reassoc.c (rewrite_expr_tree, linearize_expr): Likewise.
	* tree-ssa-sink.c (statement_sink_location): Likewise.
	* tree-ssa-forwprop (forward_propagate_addr_expr): Likewise.
	* tree-ssanames.c (release_ssa_name): Adjust for rename.
	* tree-flow.h: Likewise.
	* tree-ssa-dce.c (eliminate_unnecessary_stmts): Don't discard
	just-inserted debug stmts.

for  gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/41343
	PR debug/41447
	PR debug/41264
	PR debug/41338
	* gcc.dg/guality/pr41447-1.c: New.
	* gcc.dg/debug/pr41264-1.c: New.
	* gcc.dg/debug/pr41343-1.c: New.

Index: gcc/tree.def
===================================================================
--- gcc/tree.def.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree.def	2009-10-08 16:58:29.000000000 -0300
@@ -351,6 +351,10 @@ DEFTREECODE (PARM_DECL, "parm_decl", tcc
 DEFTREECODE (TYPE_DECL, "type_decl", tcc_declaration, 0)
 DEFTREECODE (RESULT_DECL, "result_decl", tcc_declaration, 0)
 
+/* A "declaration" of a debug temporary.  It should only appear in
+   DEBUG stmts.  */
+DEFTREECODE (DEBUG_EXPR_DECL, "debug_expr_decl", tcc_declaration, 0)
+
 /* A namespace declaration.  Namespaces appear in DECL_CONTEXT of other
    _DECLs, providing a hierarchy of names.  */
 DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0)
Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/rtl.def	2009-10-08 16:58:29.000000000 -0300
@@ -88,6 +88,10 @@ DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", RT
    DECL codes in trees.  */
 DEF_RTL_EXPR(VALUE, "value", "0", RTX_OBJ)
 
+/* The RTL generated for a DEBUG_EXPR_DECL.  It links back to the
+   DEBUG_EXPR_DECL in the first operand.  */
+DEF_RTL_EXPR(DEBUG_EXPR, "debug_expr", "0", RTX_OBJ)
+
 /* ---------------------------------------------------------------------
    Expressions used in constructing lists.
    --------------------------------------------------------------------- */
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/gengtype.c	2009-10-08 16:58:29.000000000 -0300
@@ -1117,6 +1117,8 @@ adjust_field_rtx_def (type_p t, options_
 		t = scalar_tp, subname = "rt_int";
 	      else if (i == VALUE && aindex == 0)
 		t = scalar_tp, subname = "rt_int";
+	      else if (i == DEBUG_EXPR && aindex == 0)
+		t = tree_tp, subname = "rt_tree";
 	      else if (i == REG && aindex == 1)
 		t = scalar_tp, subname = "rt_int";
 	      else if (i == REG && aindex == 2)
Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa.c	2009-10-09 01:29:17.000000000 -0300
@@ -295,70 +295,44 @@ find_released_ssa_name (tree *tp, int *w
   return NULL_TREE;
 }
 
-/* Given a VAR whose definition STMT is to be moved to the iterator
-   position TOGSIP in the TOBB basic block, verify whether we're
-   moving it across any of the debug statements that use it, and
-   adjust them as needed.  If TOBB is NULL, then the definition is
-   understood as being removed, and TOGSIP is unused.  */
+/* Insert a DEBUG BIND stmt before the DEF of VAR if VAR is referenced
+   by other DEBUG stmts, and replace uses of the DEF with the
+   newly-created debug temp.  */
+
 void
-propagate_var_def_into_debug_stmts (tree var,
-				    basic_block tobb,
-				    const gimple_stmt_iterator *togsip)
+insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
 {
   imm_use_iterator imm_iter;
   gimple stmt;
   use_operand_p use_p;
   tree value = NULL;
+  tree vexpr = NULL;
   bool no_value = false;
+  bool vsafe = false;
+  gimple def_stmt = NULL;
 
   if (!MAY_HAVE_DEBUG_STMTS)
     return;
 
   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, var)
     {
-      basic_block bb;
-      gimple_stmt_iterator si;
-
       if (!is_gimple_debug (stmt))
 	continue;
 
-      if (tobb)
-	{
-	  bb = gimple_bb (stmt);
-
-	  if (bb != tobb)
-	    {
-	      gcc_assert (dom_info_available_p (CDI_DOMINATORS));
-	      if (dominated_by_p (CDI_DOMINATORS, bb, tobb))
-		continue;
-	    }
-	  else
-	    {
-	      si = *togsip;
-
-	      if (gsi_end_p (si))
-		continue;
-
-	      do
-		{
-		  gsi_prev (&si);
-		  if (gsi_end_p (si))
-		    break;
-		}
-	      while (gsi_stmt (si) != stmt);
-
-	      if (gsi_end_p (si))
-		continue;
-	    }
-	}
-
       /* Here we compute (lazily) the value assigned to VAR, but we
 	 remember if we tried before and failed, so that we don't try
 	 again.  */
       if (!value && !no_value)
 	{
-	  gimple def_stmt = SSA_NAME_DEF_STMT (var);
+	  if (gsi)
+	    def_stmt = gsi_stmt (*gsi);
+	  else
+	    def_stmt = SSA_NAME_DEF_STMT (var);
 
+	  /* If we didn't get an insertion point, and the stmt has
+	     already been removed, we won't be able to insert the
+	     debug bind stmt, so we'll have to drop debug
+	     information.  */
 	  if (is_gimple_assign (def_stmt))
 	    {
 	      if (!dom_info_available_p (CDI_DOMINATORS))
@@ -395,7 +369,9 @@ propagate_var_def_into_debug_stmts (tree
 		     wrong order, so we don't even check for dead SSA
 		     NAMEs.  SSA verification shall catch any
 		     errors.  */
-		  if (!walk_gimple_op (def_stmt, find_released_ssa_name, &wi))
+		  if ((!gsi && !gimple_bb (def_stmt))
+		      || !walk_gimple_op (def_stmt, find_released_ssa_name,
+					  &wi))
 		    no_value = true;
 		}
 
@@ -405,42 +381,111 @@ propagate_var_def_into_debug_stmts (tree
 
 	  if (!value)
 	    no_value = true;
+	  else if (is_gimple_min_invariant (value)
+		   || is_gimple_reg (value))
+	    {
+	      vsafe = true;
+	      vexpr = value;
+	    }
+	  else
+	    {
+	      switch (get_gimple_rhs_class (TREE_CODE (value)))
+		{
+		case GIMPLE_BINARY_RHS:
+		  vsafe
+		    = ((is_gimple_min_invariant (TREE_OPERAND (value, 0))
+			|| is_gimple_reg (TREE_OPERAND (value, 0)))
+		       && (is_gimple_min_invariant (TREE_OPERAND (value, 1))
+			   || is_gimple_reg (TREE_OPERAND (value, 1))));
+		  break;
+
+		case GIMPLE_UNARY_RHS:
+		  vsafe
+		    = (is_gimple_min_invariant (TREE_OPERAND (value, 0))
+		       || is_gimple_reg (TREE_OPERAND (value, 0)));
+		  break;
+
+		case GIMPLE_SINGLE_RHS:
+		  vsafe
+		    = (is_gimple_min_invariant (value)
+		       || is_gimple_reg (value));
+		  if (vsafe)
+		    vexpr = value;
+		  break;
+
+		default:
+		  gcc_unreachable ();
+		}
+	    }
 	}
 
       if (no_value)
 	gimple_debug_bind_reset_value (stmt);
+      /* If VAR is the entire value expression, and the definition of
+	 VAR is safe to move about, use it.  */
+      else if (vsafe && gimple_debug_bind_get_value (stmt) == var)
+	gimple_debug_bind_set_value (stmt, unshare_expr (value));
+      /* Otherwise, create a debug temp expression and use it.  */
       else
 	FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-	  SET_USE (use_p, unshare_expr (value));
+	  {
+	    if (!vexpr)
+	      {
+		gimple def_temp;
+
+		vexpr = make_node (DEBUG_EXPR_DECL);
+		def_temp = gimple_build_debug_bind (vexpr,
+						    unshare_expr (value),
+						    def_stmt);
+
+		DECL_ARTIFICIAL (vexpr) = 1;
+		TREE_TYPE (vexpr) = TREE_TYPE (value);
+		if (DECL_P (value))
+		  DECL_MODE (vexpr) = DECL_MODE (value);
+		else
+		  DECL_MODE (vexpr) = TYPE_MODE (TREE_TYPE (value));
+
+		if (gsi)
+		  gsi_insert_before (gsi, def_temp, GSI_SAME_STMT);
+		else
+		  {
+		    gimple_stmt_iterator ngsi = gsi_for_stmt (def_stmt);
+		    gsi_insert_before (&ngsi, def_temp, GSI_SAME_STMT);
+		  }
+	      }
+
+	    SET_USE (use_p, unshare_expr (vexpr));
+	  }
 
       update_stmt (stmt);
     }
 }
 
 
-/* Given a STMT to be moved to the iterator position TOBSIP in the
-   TOBB basic block, verify whether we're moving it across any of the
-   debug statements that use it.  If TOBB is NULL, then the definition
-   is understood as being removed, and TOBSIP is unused.  */
+/* Insert a DEBUG BIND stmt before STMT for each DEF referenced by
+   other DEBUG stmts, and replace uses of the DEF with the
+   newly-created debug temp.  */
 
 void
-propagate_defs_into_debug_stmts (gimple def, basic_block tobb,
-				 const gimple_stmt_iterator *togsip)
+insert_debug_temps_for_defs (gimple_stmt_iterator *gsi)
 {
+  gimple stmt;
   ssa_op_iter op_iter;
   def_operand_p def_p;
 
   if (!MAY_HAVE_DEBUG_STMTS)
     return;
 
-  FOR_EACH_SSA_DEF_OPERAND (def_p, def, op_iter, SSA_OP_DEF)
+  stmt = gsi_stmt (*gsi);
+
+  FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, op_iter, SSA_OP_DEF)
     {
       tree var = DEF_FROM_PTR (def_p);
 
       if (TREE_CODE (var) != SSA_NAME)
 	continue;
 
-      propagate_var_def_into_debug_stmts (var, tobb, togsip);
+      insert_debug_temp_for_var_def (gsi, var);
     }
 }
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree.h	2009-10-08 16:58:29.000000000 -0300
@@ -2455,6 +2455,10 @@ struct function;
 /* Every ..._DECL node gets a unique number.  */
 #define DECL_UID(NODE) (DECL_MINIMAL_CHECK (NODE)->decl_minimal.uid)
 
+/* DEBUG_EXPR_DECLs get negative UID numbers, to catch erroneous
+   uses.  */
+#define DEBUG_TEMP_UID(NODE) (-DECL_UID (TREE_CHECK ((NODE), DEBUG_EXPR_DECL)))
+
 /* These two fields describe where in the source code the declaration
    was.  If the declaration appears in several places (as for a C
    function that is declared first and then defined later), this
Index: gcc/tree.c
===================================================================
--- gcc/tree.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree.c	2009-10-08 16:58:29.000000000 -0300
@@ -152,6 +152,9 @@ static const char * const tree_node_kind
 static GTY(()) int next_decl_uid;
 /* Unique id for next type created.  */
 static GTY(()) int next_type_uid = 1;
+/* Unique id for next debug decl created.  Use negative numbers,
+   to catch erroneous uses.  */
+static GTY(()) int next_debug_decl_uid;
 
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
@@ -872,7 +875,10 @@ make_node_stat (enum tree_code code MEM_
 	    DECL_ALIGN (t) = 1;
 	}
       DECL_SOURCE_LOCATION (t) = input_location;
-      DECL_UID (t) = next_decl_uid++;
+      if (TREE_CODE (t) == DEBUG_EXPR_DECL)
+	DECL_UID (t) = --next_debug_decl_uid;
+      else
+	DECL_UID (t) = next_decl_uid++;
       if (TREE_CODE (t) == LABEL_DECL)
 	LABEL_DECL_UID (t) = -1;
 
@@ -948,7 +954,10 @@ copy_node_stat (tree node MEM_STAT_DECL)
 
   if (TREE_CODE_CLASS (code) == tcc_declaration)
     {
-      DECL_UID (t) = next_decl_uid++;
+      if (code == DEBUG_EXPR_DECL)
+	DECL_UID (t) = --next_debug_decl_uid;
+      else
+	DECL_UID (t) = next_decl_uid++;
       if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL)
 	  && DECL_HAS_VALUE_EXPR_P (node))
 	{
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/cfgexpand.c	2009-10-08 16:58:29.000000000 -0300
@@ -2361,6 +2361,18 @@ expand_debug_expr (tree exp)
       op1 = wrap_constant (GET_MODE_INNER (mode), op1);
       return gen_rtx_CONCAT (mode, op0, op1);
 
+    case DEBUG_EXPR_DECL:
+      op0 = DECL_RTL_IF_SET (exp);
+
+      if (op0)
+	return op0;
+
+      op0 = gen_rtx_DEBUG_EXPR (mode);
+      XTREE (op0, 0) = exp;
+      SET_DECL_RTL (exp, op0);
+
+      return op0;
+
     case VAR_DECL:
     case PARM_DECL:
     case FUNCTION_DECL:
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/var-tracking.c	2009-10-08 16:58:29.000000000 -0300
@@ -732,6 +732,7 @@ dv_is_decl_p (decl_or_value dv)
     case (int)PARM_DECL:
     case (int)RESULT_DECL:
     case (int)FUNCTION_DECL:
+    case (int)DEBUG_EXPR_DECL:
     case (int)COMPONENT_REF:
       return true;
 
@@ -2222,7 +2223,7 @@ dataflow_set_union (dataflow_set *dst, d
 
 /* Whether the value is currently being expanded.  */
 #define VALUE_RECURSED_INTO(x) \
-  (RTL_FLAG_CHECK1 ("VALUE_RECURSED_INTO", (x), VALUE)->used)
+  (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)
 /* Whether the value is in changed_variables hash table.  */
 #define VALUE_CHANGED(x) \
   (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
@@ -4112,6 +4113,9 @@ track_expr_p (tree expr, bool need_rtl)
   rtx decl_rtl;
   tree realdecl;
 
+  if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
+    return DECL_RTL_SET_P (expr);
+
   /* If EXPR is not a parameter or a variable do not track it.  */
   if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
     return 0;
@@ -6271,11 +6275,12 @@ vt_expand_loc_callback (rtx x, bitmap re
   decl_or_value dv;
   variable var;
   location_chain loc;
-  rtx result;
+  rtx result, subreg, xret;
 
-  if (GET_CODE (x) == SUBREG)
+  switch (GET_CODE (x))
     {
-      rtx subreg = SUBREG_REG (x);
+    case SUBREG:
+      subreg = SUBREG_REG (x);
 
       if (GET_CODE (SUBREG_REG (x)) != VALUE)
 	return x;
@@ -6297,22 +6302,31 @@ vt_expand_loc_callback (rtx x, bitmap re
 	result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
 
       return result;
-    }
 
-  if (GET_CODE (x) != VALUE)
-    return x;
+    case DEBUG_EXPR:
+      dv = dv_from_decl (XTREE (x, 0));
+      xret = NULL;
+      break;
+
+    case VALUE:
+      dv = dv_from_value (x);
+      xret = x;
+      break;
+
+    default:
+      return x;
+    }
 
   if (VALUE_RECURSED_INTO (x))
-    return x;
+    return NULL;
 
-  dv = dv_from_value (x);
   var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
 
   if (!var)
-    return x;
+    return xret;
 
   if (var->n_var_parts == 0)
-    return x;
+    return xret;
 
   gcc_assert (var->n_var_parts == 1);
 
@@ -6332,7 +6346,7 @@ vt_expand_loc_callback (rtx x, bitmap re
   if (result)
     return result;
   else
-    return x;
+    return xret;
 }
 
 /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence
@@ -6382,6 +6396,9 @@ emit_note_insn_var_location (void **varp
 
   decl = dv_as_decl (var->dv);
 
+  if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
+    goto clear;
+
   gcc_assert (decl);
 
   complete = true;
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/cselib.c	2009-10-09 04:29:50.000000000 -0300
@@ -585,6 +585,7 @@ rtx_equal_for_cselib_p (rtx x, rtx y)
     {
     case CONST_DOUBLE:
     case CONST_FIXED:
+    case DEBUG_EXPR:
       return 0;
 
     case LABEL_REF:
@@ -703,6 +704,10 @@ cselib_hash_rtx (rtx x, int create)
 
       return e->value;
 
+    case DEBUG_EXPR:
+      hash += ((unsigned) DEBUG_EXPR << 7) + DEBUG_TEMP_UID (XTREE (x, 0));
+      return hash ? hash : (unsigned int) DEBUG_EXPR;
+
     case CONST_INT:
       hash += ((unsigned) CONST_INT << 7) + INTVAL (x);
       return hash ? hash : (unsigned int) CONST_INT;
@@ -1213,6 +1218,13 @@ cselib_expand_value_rtx_1 (rtx orig, str
 	result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth);
 	return result;
       }
+
+    case DEBUG_EXPR:
+      if (evd->callback)
+	return evd->callback (orig, evd->regs_active, max_depth,
+			      evd->callback_arg);
+      return orig;
+
     default:
       break;
     }
Index: gcc/tree-ssa-operands.c
===================================================================
--- gcc/tree-ssa-operands.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-operands.c	2009-10-08 16:58:29.000000000 -0300
@@ -894,6 +894,10 @@ get_expr_operands (gimple stmt, tree *ex
       add_stmt_operand (expr_p, stmt, flags);
       return;
 
+    case DEBUG_EXPR_DECL:
+      gcc_assert (gimple_debug_bind_p (stmt));
+      return;
+
     case MISALIGNED_INDIRECT_REF:
       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
       /* fall through */
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/emit-rtl.c	2009-10-08 16:58:29.000000000 -0300
@@ -2393,6 +2393,8 @@ verify_rtx_sharing (rtx orig, rtx insn)
   switch (code)
     {
     case REG:
+    case DEBUG_EXPR:
+    case VALUE:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_FIXED:
@@ -2593,6 +2595,8 @@ repeat:
   switch (code)
     {
     case REG:
+    case DEBUG_EXPR:
+    case VALUE:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_FIXED:
@@ -2712,6 +2716,8 @@ repeat:
   switch (code)
     {
     case REG:
+    case DEBUG_EXPR:
+    case VALUE:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_FIXED:
@@ -2783,6 +2789,8 @@ set_used_flags (rtx x)
   switch (code)
     {
     case REG:
+    case DEBUG_EXPR:
+    case VALUE:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_FIXED:
Index: gcc/rtl.c
===================================================================
--- gcc/rtl.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/rtl.c	2009-10-08 16:58:29.000000000 -0300
@@ -232,6 +232,8 @@ copy_rtx (rtx orig)
   switch (code)
     {
     case REG:
+    case DEBUG_EXPR:
+    case VALUE:
     case CONST_INT:
     case CONST_DOUBLE:
     case CONST_FIXED:
@@ -381,6 +383,7 @@ rtx_equal_p_cb (const_rtx x, const_rtx y
     case SYMBOL_REF:
       return XSTR (x, 0) == XSTR (y, 0);
 
+    case DEBUG_EXPR:
     case VALUE:
     case SCRATCH:
     case CONST_DOUBLE:
@@ -496,6 +499,7 @@ rtx_equal_p (const_rtx x, const_rtx y)
     case SYMBOL_REF:
       return XSTR (x, 0) == XSTR (y, 0);
 
+    case DEBUG_EXPR:
     case VALUE:
     case SCRATCH:
     case CONST_DOUBLE:
Index: gcc/print-rtl.c
===================================================================
--- gcc/print-rtl.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/print-rtl.c	2009-10-08 16:58:29.000000000 -0300
@@ -318,6 +318,12 @@ print_rtx (const_rtx in_rtx)
 	    dump_addr (outfile, "/", (void*)val);
 #endif
 	  }
+	else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
+	  {
+#ifndef GENERATOR_FILE
+	    fprintf (outfile, " D#%i", DEBUG_TEMP_UID (XTREE (in_rtx, 0)));
+#endif
+	  }
 	break;
 
       case 'e':
Index: gcc/sched-vis.c
===================================================================
--- gcc/sched-vis.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/sched-vis.c	2009-10-08 16:58:29.000000000 -0300
@@ -521,6 +521,10 @@ print_value (char *buf, const_rtx x, int
       cur = safe_concat (buf, cur, t);
       cur = safe_concat (buf, cur, "]");
       break;
+    case DEBUG_EXPR:
+      sprintf (t, "D#%i", DEBUG_TEMP_UID (XTREE (x, 0)));
+      cur = safe_concat (buf, cur, t);
+      break;
     default:
       print_exp (t, x, verbose);
       cur = safe_concat (buf, cur, t);
@@ -670,11 +674,18 @@ print_insn (char *buf, const_rtx x, int 
 	if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
 	  {
 	    tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
+	    char idbuf[32];
 	    if (id)
 	      name = IDENTIFIER_POINTER (id);
+	    else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn))
+		     == DEBUG_EXPR_DECL)
+	      {
+		sprintf (idbuf, "D#%i",
+			 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn)));
+		name = idbuf;
+	      }
 	    else
 	      {
-		char idbuf[32];
 		sprintf (idbuf, "D.%i",
 			 DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
 		name = idbuf;
Index: gcc/tree-dump.c
===================================================================
--- gcc/tree-dump.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-dump.c	2009-10-08 16:58:29.000000000 -0300
@@ -511,6 +511,10 @@ dequeue_and_dump (dump_info_p di)
       dump_child ("cnst", DECL_INITIAL (t));
       break;
 
+    case DEBUG_EXPR_DECL:
+      dump_int (di, "-uid", DEBUG_TEMP_UID (t));
+      /* Fall through.  */
+
     case VAR_DECL:
     case PARM_DECL:
     case FIELD_DECL:
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-pretty-print.c	2009-10-08 16:58:29.000000000 -0300
@@ -183,6 +183,8 @@ dump_decl_name (pretty_printer *buffer, 
     {
       if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
         pp_printf (buffer, "L.%d", (int) LABEL_DECL_UID (node));
+      else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
+	pp_printf (buffer, "D#%i", DEBUG_TEMP_UID (node));
       else
 	{
 	  char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
@@ -1051,6 +1053,7 @@ dump_generic_node (pretty_printer *buffe
     case VAR_DECL:
     case PARM_DECL:
     case FIELD_DECL:
+    case DEBUG_EXPR_DECL:
     case NAMESPACE_DECL:
       dump_decl_name (buffer, node, flags);
       break;
Index: gcc/gimple-iterator.c
===================================================================
--- gcc/gimple-iterator.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/gimple-iterator.c	2009-10-08 16:58:29.000000000 -0300
@@ -368,6 +368,8 @@ gsi_replace (gimple_stmt_iterator *gsi, 
   if (stmt == orig_stmt)
     return;
 
+  insert_debug_temps_for_defs (gsi);
+
   gimple_set_location (stmt, gimple_location (orig_stmt));
   gimple_set_bb (stmt, gsi_bb (*gsi));
 
@@ -470,6 +472,8 @@ gsi_remove (gimple_stmt_iterator *i, boo
   gimple_seq_node cur, next, prev;
   gimple stmt = gsi_stmt (*i);
 
+  insert_debug_temps_for_defs (i);
+
   /* Free all the data flow information for STMT.  */
   gimple_set_bb (stmt, NULL);
   delink_stmt_imm_use (stmt);
Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-loop-im.c	2009-10-08 16:58:29.000000000 -0300
@@ -879,7 +879,6 @@ rewrite_bittest (gimple_stmt_iterator *b
       gimple_cond_set_rhs (use_stmt, build_int_cst_type (TREE_TYPE (name), 0));
 
       gsi_insert_before (bsi, stmt1, GSI_SAME_STMT);
-      propagate_defs_into_debug_stmts (gsi_stmt (*bsi), NULL, NULL);
       gsi_replace (bsi, stmt2, true);
 
       return stmt1;
@@ -1060,7 +1059,6 @@ move_computations_stmt (struct dom_walk_
 
       mark_virtual_ops_for_renaming (stmt);
       gsi_insert_on_edge (loop_preheader_edge (level), stmt);
-      propagate_defs_into_debug_stmts (gsi_stmt (bsi), NULL, NULL);
       gsi_remove (&bsi, false);
     }
 }
Index: gcc/tree-ssa-reassoc.c
===================================================================
--- gcc/tree-ssa-reassoc.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-reassoc.c	2009-10-08 16:58:29.000000000 -0300
@@ -1405,7 +1405,6 @@ rewrite_expr_tree (gimple stmt, unsigned
 	    {
 	      stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt1));
 	      gsirhs1 = gsi_for_stmt (stmt2);
-	      propagate_defs_into_debug_stmts (stmt2, gimple_bb (stmt), &gsinow);
 	      gsi_move_before (&gsirhs1, &gsinow);
 	      gsi_prev (&gsinow);
 	      stmt1 = stmt2;
@@ -1452,7 +1451,6 @@ linearize_expr (gimple stmt)
 
   gsinow = gsi_for_stmt (stmt);
   gsirhs = gsi_for_stmt (binrhs);
-  propagate_defs_into_debug_stmts (binrhs, gimple_bb (stmt), &gsinow);
   gsi_move_before (&gsirhs, &gsinow);
 
   gimple_assign_set_rhs2 (stmt, gimple_assign_rhs1 (binrhs));
Index: gcc/tree-ssa-sink.c
===================================================================
--- gcc/tree-ssa-sink.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-sink.c	2009-10-08 16:58:29.000000000 -0300
@@ -385,9 +385,6 @@ statement_sink_location (gimple stmt, ba
 
       *togsi = gsi_after_labels (commondom);
 
-      if (debug_stmts)
-	propagate_defs_into_debug_stmts (stmt, commondom, togsi);
-
       return true;
     }
 
@@ -406,8 +403,6 @@ statement_sink_location (gimple stmt, ba
 
       *togsi = gsi_for_stmt (use);
 
-      propagate_defs_into_debug_stmts (stmt, sinkbb, togsi);
-
       return true;
     }
 
@@ -441,8 +436,6 @@ statement_sink_location (gimple stmt, ba
 
   *togsi = gsi_after_labels (sinkbb);
 
-  propagate_defs_into_debug_stmts (stmt, sinkbb, togsi);
-
   return true;
 }
 
Index: gcc/tree-ssa-forwprop.c
===================================================================
--- gcc/tree-ssa-forwprop.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-forwprop.c	2009-10-08 16:58:29.000000000 -0300
@@ -939,7 +939,6 @@ forward_propagate_addr_expr (tree name, 
   gimple use_stmt;
   bool all = true;
   bool single_use_p = has_single_use (name);
-  bool debug = false;
 
   FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
     {
@@ -950,9 +949,7 @@ forward_propagate_addr_expr (tree name, 
 	 there is nothing we can do.  */
       if (gimple_code (use_stmt) != GIMPLE_ASSIGN)
 	{
-	  if (is_gimple_debug (use_stmt))
-	    debug = true;
-	  else
+	  if (!is_gimple_debug (use_stmt))
 	    all = false;
 	  continue;
 	}
@@ -995,9 +992,6 @@ forward_propagate_addr_expr (tree name, 
 	}
     }
 
-  if (all && debug)
-    propagate_var_def_into_debug_stmts (name, NULL, NULL);
-
   return all;
 }
 
Index: gcc/tree-ssanames.c
===================================================================
--- gcc/tree-ssanames.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssanames.c	2009-10-08 16:58:29.000000000 -0300
@@ -206,7 +206,7 @@ release_ssa_name (tree var)
       use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));
 
       if (MAY_HAVE_DEBUG_STMTS)
-	propagate_var_def_into_debug_stmts (var, NULL, NULL);
+	insert_debug_temp_for_var_def (NULL, var);
 
 #ifdef ENABLE_CHECKING
       verify_imm_links (stderr, var);
Index: gcc/tree-flow.h
===================================================================
--- gcc/tree-flow.h.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-flow.h	2009-10-08 16:58:29.000000000 -0300
@@ -637,10 +637,8 @@ typedef bool (*walk_use_def_chains_fn) (
 
 extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
 
-void propagate_defs_into_debug_stmts (gimple, basic_block,
-				      const gimple_stmt_iterator *);
-void propagate_var_def_into_debug_stmts (tree, basic_block,
-					 const gimple_stmt_iterator *);
+void insert_debug_temps_for_defs (gimple_stmt_iterator *);
+void insert_debug_temp_for_var_def (gimple_stmt_iterator *, tree);
 void release_defs_bitset (bitmap toremove);
 
 /* In tree-into-ssa.c  */
Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c.orig	2009-10-08 16:45:22.000000000 -0300
+++ gcc/tree-ssa-dce.c	2009-10-08 16:58:29.000000000 -0300
@@ -1071,7 +1071,7 @@ eliminate_unnecessary_stmts (void)
 {
   bool something_changed = false;
   basic_block bb;
-  gimple_stmt_iterator gsi;
+  gimple_stmt_iterator gsi, psi;
   gimple stmt;
   tree call;
   VEC (basic_block, heap) *h;
@@ -1111,10 +1111,13 @@ eliminate_unnecessary_stmts (void)
       bb = VEC_pop (basic_block, h);
 
       /* Remove dead statements.  */
-      for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
+      for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi = psi)
 	{
 	  stmt = gsi_stmt (gsi);
 
+	  psi = gsi;
+	  gsi_prev (&psi);
+
 	  stats.total++;
 
 	  /* If GSI is not necessary then remove it.  */
@@ -1122,14 +1125,6 @@ eliminate_unnecessary_stmts (void)
 	    {
 	      remove_dead_stmt (&gsi, bb);
 	      something_changed = true;
-
-	      /* If stmt was the last stmt in the block, we want to
-		 move gsi to the stmt that became the last stmt, but
-		 gsi_prev would crash.  */
-	      if (gsi_end_p (gsi))
-		gsi = gsi_last_bb (bb);
-	      else
-		gsi_prev (&gsi);
 	    }
 	  else if (is_gimple_call (stmt))
 	    {
@@ -1159,10 +1154,7 @@ eliminate_unnecessary_stmts (void)
 		    }
 		  notice_special_calls (stmt);
 		}
-	      gsi_prev (&gsi);
 	    }
-	  else
-	    gsi_prev (&gsi);
 	}
     }
 
Index: gcc/tree-into-ssa.c
===================================================================
--- gcc/tree-into-ssa.c.orig	2009-10-08 17:59:27.000000000 -0300
+++ gcc/tree-into-ssa.c	2009-10-09 04:29:53.000000000 -0300
@@ -2079,11 +2079,29 @@ rewrite_update_enter_block (struct dom_w
 
   /* Step 2.  Rewrite every variable used in each statement in the block.  */
   if (TEST_BIT (interesting_blocks, bb->index))
-   {
-     gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-        rewrite_update_stmt (gsi_stmt (gsi));
-   }
+    {
+      gcc_assert (bitmap_bit_p (blocks_to_update, bb->index));
+      gsi = gsi_start_bb (bb);
+      while (!gsi_end_p (gsi))
+	{
+	  gimple stmt = gsi_stmt (gsi);
+
+	  if (gimple_debug_bind_p (stmt)
+	      && !gimple_debug_bind_has_value_p (stmt)
+	      && TREE_CODE (gimple_debug_bind_get_var (stmt)) == DEBUG_EXPR_DECL)
+	    {
+	      gimple_stmt_iterator gsic = gsi;
+
+	      gsi_next (&gsi);
+	      gsi_remove (&gsic, true);
+	    }
+	  else
+	    {
+	      rewrite_update_stmt (stmt);
+	      gsi_next (&gsi);
+	    }
+	}
+    }
 
   /* Step 3.  Update PHI nodes.  */
   rewrite_update_phi_arguments (bb);
Index: gcc/testsuite/gcc.dg/guality/pr41447-1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/guality/pr41447-1.c	2009-10-08 21:27:20.000000000 -0300
@@ -0,0 +1,25 @@
+/* { dg-do run { xfail *-*-* } } */
+/* { dg-options "-g -O2" } */
+
+#include "guality.h"
+
+int a;
+
+int foo()
+{
+  int tmp = a;
+  int tmp2 = a;
+  int tmp3;
+  int res;
+  GUALCHKVAL (a);
+  GUALCHKVAL (tmp);
+  GUALCHKVAL (tmp2);
+  a = 0;
+  tmp3 = tmp2;
+  GUALCHKVAL (a);
+  GUALCHKVAL (tmp);
+  GUALCHKVAL (tmp2);
+  GUALCHKVAL (tmp3);
+  res = tmp - tmp2 + 1;
+  return res;
+}
Index: gcc/testsuite/gcc.dg/debug/pr41264-1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/debug/pr41264-1.c	2009-10-09 01:26:51.000000000 -0300
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+
+typedef unsigned int hashval_t;
+static hashval_t __attribute__((always_inline))
+iterative_hash_host_wide_int (long val, hashval_t val2)
+{
+  hashval_t a = (hashval_t) val;
+  int zero = 0;
+  hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 8 + zero));
+
+  a -= b; a -= val2; a ^= (val2>>13);
+  b -= val2; b -= a; b ^= (a<< 8);
+  val2 -= a; val2 -= b; val2 ^= ((b&0xffffffff)>>13);
+  a -= b; a -= val2; a ^= ((val2&0xffffffff)>>12);
+  b -= val2; b -= a; b = (b ^ (a<<16)) & 0xffffffff;
+  val2 -= a; val2 -= b; val2 = (val2 ^ (b>> 5)) & 0xffffffff;
+  a -= b; a -= val2; a = (a ^ (val2>> 3)) & 0xffffffff;
+  b -= val2; b -= a; b = (b ^ (a<<10)) & 0xffffffff;
+  val2 -= a; val2 -= b; val2 = (val2 ^ (b>>15)) & 0xffffffff;
+  return val2;
+}
+
+hashval_t
+bla (int nunits, int mode)
+{
+  hashval_t hashcode = 0;
+
+
+  hashcode = iterative_hash_host_wide_int (14, hashcode);
+  hashcode = iterative_hash_host_wide_int (nunits, hashcode);
+  hashcode = iterative_hash_host_wide_int (mode, hashcode);
+  if (nunits)
+    return 0;
+  else
+    return hashcode;
+}
Index: gcc/testsuite/gcc.dg/debug/pr41343-1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/debug/pr41343-1.c	2009-10-09 04:13:40.000000000 -0300
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+#define X(new,old) int i ## new = i ## old + i ## old;
+#define Y(pfx) X(pfx ## 1, pfx) \
+  X(pfx ## 2, pfx ## 1) \
+  X(pfx ## 3, pfx ## 2) \
+  X(pfx ## 4, pfx ## 3) \
+  X(pfx ## 5, pfx ## 4) \
+  X(pfx ## 6, pfx ## 5) \
+  X(pfx ## 7, pfx ## 6) \
+  X(pfx ## 8, pfx ## 7) \
+  X(pfx ## 9, pfx ## 8)
+
+void foo (int i1)
+{
+  Y(1)
+  Y(11)
+  Y(111)
+  asm ("" : : "X" (i1));
+}

-- 
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 Compiler Engineer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]