From: Jakub Jelinek Date: Tue, 5 Mar 2013 22:31:50 +0000 (+0100) Subject: re PR debug/56510 (More var-tracking scalability problems) X-Git-Tag: releases/gcc-4.8.0~176 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6cfa417faea7efa8783e28ef9780e0c1ba7b407c;p=thirdparty%2Fgcc.git re PR debug/56510 (More var-tracking scalability problems) 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: r196479 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 453c57b042fb..ee1d9fcaf553 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,8 +1,19 @@ -2013-03-05 David Holsgrove +2013-03-05 Jakub Jelinek + + 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. + + PR rtl-optimization/56484 + * ifcvt.c (noce_process_if_block): If else_bb is NULL, avoid extending + lifetimes of hard registers on small register class machines. + +2013-03-05 David Holsgrove - * config/microblaze/microblaze-protos.h: Rename + * config/microblaze/microblaze-protos.h: Rename microblaze_is_interrupt_handler to microblaze_is_interrupt_variant. - * config/microblaze/microblaze.c (microblaze_attribute_table): Add + * config/microblaze/microblaze.c (microblaze_attribute_table): Add fast_interrupt. (microblaze_fast_interrupt_function_p): New function. (microblaze_is_interrupt_handler): Rename to @@ -12,8 +23,8 @@ (compute_frame_size): Likewise. (microblaze_function_prologue): Add FAST_INTERRUPT_NAME. (microblaze_globalize_label): Likewise. - * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME. - * config/microblaze/microblaze.md: Use wrapper + * config/microblaze/microblaze.h: Define FAST_INTERRUPT_NAME. + * config/microblaze/microblaze.md: Use wrapper microblaze_is_interrupt_variant. 2013-03-05 Kai Tietz diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 6af1fa7b9217..5acc42d73f54 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 699702c1cb42..57df6fc2f3f4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-03-05 Jakub Jelinek + + PR debug/56510 + * gcc.dg/pr56510.c: New test. + + PR rtl-optimization/56484 + * gcc.c-torture/compile/pr56484.c: New test. + 2013-03-05 Paolo Carlini PR c++/56530 diff --git a/gcc/testsuite/gcc.dg/pr56510.c b/gcc/testsuite/gcc.dg/pr56510.c new file mode 100644 index 000000000000..1f8e21a57bfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56510.c @@ -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])) (); +}