diff mbox

4.7 backports

Message ID 20130403082509.GB4201@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek April 3, 2013, 8:25 a.m. UTC
Hi!

I've backported, bootstrapped/regtested and committed the following two
patches to 4.7 branch.

	Jakub
2013-04-03  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-03-05  Jakub Jelinek  <jakub@redhat.com>

	PR debug/56510
	* cfgexpand.c (expand_debug_parm_decl): Call copy_rtx on incoming.
	(avoid_complex_debug_insns): New function.
	(expand_debug_locations): Call it.

	* gcc.dg/pr56510.c: New test.
2013-04-03  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2013-03-06  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56539
	* tree-tailcall.c (adjust_return_value_with_ops): Use GSI_SAME_STMT
	instead of GSI_CONTINUE_LINKING as last argument to
	force_gimple_operand_gsi.  Adjust function comment.

	* gcc.c-torture/compile/pr56539.c: New test.

--- gcc/tree-tailcall.c	(revision 196510)
+++ gcc/tree-tailcall.c	(revision 196511)
@@ -601,8 +601,8 @@ add_successor_phi_arg (edge e, tree var,
 }
 
 /* Creates a GIMPLE statement which computes the operation specified by
-   CODE, OP0 and OP1 to a new variable with name LABEL and inserts the
-   statement in the position specified by GSI and UPDATE.  Returns the
+   CODE, ACC and OP1 to a new variable with name LABEL and inserts the
+   statement in the position specified by GSI.  Returns the
    tree node of the statement's result.  */
 
 static tree
@@ -627,7 +627,7 @@ adjust_return_value_with_ops (enum tree_
 					    fold_convert (TREE_TYPE (op1), acc),
 					    op1));
       rhs = force_gimple_operand_gsi (&gsi, rhs,
-				      false, NULL, true, GSI_CONTINUE_LINKING);
+				      false, NULL, true, GSI_SAME_STMT);
       stmt = gimple_build_assign (NULL_TREE, rhs);
     }
 
--- gcc/testsuite/gcc.c-torture/compile/pr56539.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr56539.c	(revision 196511)
@@ -0,0 +1,7 @@
+/* PR tree-optimization/56539 */
+
+short
+foo (const char *x, unsigned y)
+{
+  return y > 1 ? (x[y - 1] - '0') + 10 * foo (x, y - 1) : (*x - '0');
+}
diff mbox

Patch

--- gcc/cfgexpand.c	(revision 196478)
+++ gcc/cfgexpand.c	(revision 196479)
@@ -2622,6 +2622,8 @@  expand_debug_parm_decl (tree decl)
 	      reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
 	      incoming = replace_equiv_address_nv (incoming, reg);
 	    }
+	  else
+	    incoming = copy_rtx (incoming);
 	}
 #endif
 
@@ -2637,7 +2639,7 @@  expand_debug_parm_decl (tree decl)
 	  || (GET_CODE (XEXP (incoming, 0)) == PLUS
 	      && XEXP (XEXP (incoming, 0), 0) == virtual_incoming_args_rtx
 	      && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
-    return incoming;
+    return copy_rtx (incoming);
 
   return NULL_RTX;
 }
@@ -3704,6 +3706,56 @@  expand_debug_source_expr (tree exp)
   return op0;
 }
 
+/* Ensure INSN_VAR_LOCATION_LOC (insn) doesn't have unbound complexity.
+   Allow 4 levels of rtl nesting for most rtl codes, and if we see anything
+   deeper than that, create DEBUG_EXPRs and emit DEBUG_INSNs before INSN.  */
+
+static void
+avoid_complex_debug_insns (rtx insn, rtx *exp_p, int depth)
+{
+  rtx exp = *exp_p;
+
+  if (exp == NULL_RTX)
+    return;
+
+  if ((OBJECT_P (exp) && !MEM_P (exp)) || GET_CODE (exp) == CLOBBER)
+    return;
+
+  if (depth == 4)
+    {
+      /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
+      rtx dval = make_debug_expr_from_rtl (exp);
+
+      /* Emit a debug bind insn before INSN.  */
+      rtx bind = gen_rtx_VAR_LOCATION (GET_MODE (exp),
+				       DEBUG_EXPR_TREE_DECL (dval), exp,
+				       VAR_INIT_STATUS_INITIALIZED);
+
+      emit_debug_insn_before (bind, insn);
+      *exp_p = dval;
+      return;
+    }
+
+  const char *format_ptr = GET_RTX_FORMAT (GET_CODE (exp));
+  int i, j;
+  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
+    switch (*format_ptr++)
+      {
+      case 'e':
+	avoid_complex_debug_insns (insn, &XEXP (exp, i), depth + 1);
+	break;
+
+      case 'E':
+      case 'V':
+	for (j = 0; j < XVECLEN (exp, i); j++)
+	  avoid_complex_debug_insns (insn, &XVECEXP (exp, i, j), depth + 1);
+	break;
+
+      default:
+	break;
+      }
+}
+
 /* Expand the _LOCs in debug insns.  We run this after expanding all
    regular insns, so that any variables referenced in the function
    will have their DECL_RTLs set.  */
@@ -3724,7 +3776,7 @@  expand_debug_locations (void)
     if (DEBUG_INSN_P (insn))
       {
 	tree value = (tree)INSN_VAR_LOCATION_LOC (insn);
-	rtx val;
+	rtx val, prev_insn, insn2;
 	enum machine_mode mode;
 
 	if (value == NULL_TREE)
@@ -3753,6 +3805,9 @@  expand_debug_locations (void)
 	  }
 
 	INSN_VAR_LOCATION_LOC (insn) = val;
+	prev_insn = PREV_INSN (insn);
+	for (insn2 = insn; insn2 != prev_insn; insn2 = PREV_INSN (insn2))
+	  avoid_complex_debug_insns (insn2, &INSN_VAR_LOCATION_LOC (insn2), 0);
       }
 
   flag_strict_aliasing = save_strict_alias;
--- gcc/testsuite/gcc.dg/pr56510.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr56510.c	(revision 196479)
@@ -0,0 +1,37 @@ 
+/* PR debug/56510 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+
+struct S { unsigned long s1; void **s2[0]; };
+void **a, **b, **c, **d, **e, **f;
+
+static void **
+baz (long x, long y)
+{
+  void **s = f;
+  *f = (void **) (y << 8 | (x & 0xff));
+  f += y + 1;
+  return s;
+}
+
+void bar (void);
+void
+foo (void)
+{
+  void **g = b[4];
+  a = b[2];
+  b = b[1];
+  g[2] = e;
+  void **h
+    = ((void **************************)
+       a)[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][66];
+  void **i = ((struct S *) h)->s2[4];
+  d = baz (4, 3);
+  d[1] = b;
+  d[2] = a;
+  d[3] = bar;
+  b = d;
+  g[1] = i[2];
+  a = g;
+  ((void (*) (void)) (i[1])) ();
+}