backport: re PR debug/56510 (More var-tracking scalability problems)

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.

From-SVN: r197391
This commit is contained in:
Jakub Jelinek 2013-04-03 10:19:56 +02:00 committed by Jakub Jelinek
parent 8e21c6cff2
commit 85e7769dc2
4 changed files with 112 additions and 2 deletions

View File

@ -1,3 +1,13 @@
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.
2013-04-02 Wei Mi <wmi@google.com>
* config/i386/i386.c (ix86_rtx_costs): Set proper rtx cost for

View File

@ -2588,6 +2588,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
@ -2603,7 +2605,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;
}
@ -3636,6 +3638,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. */
@ -3656,7 +3708,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)
@ -3686,6 +3738,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;

View File

@ -1,3 +1,11 @@
2013-04-03 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2013-03-05 Jakub Jelinek <jakub@redhat.com>
PR debug/56510
* gcc.dg/pr56510.c: New test.
2013-04-02 Richard Biener <rguenther@suse.de>
* gcc.dg/pr45472.c: Remove copies.

View File

@ -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])) ();
}