On Fri, Oct 05, 2012 at 03:59:55PM +0200, Richard Guenther wrote: > I don't think we want to rely on that ... so just keep the push/pop_cfun.
Ok, so this is what I'm retesting (basically just comments added and the two lines (subcode and set) swapped: 2012-10-05 Jakub Jelinek <ja...@redhat.com> PR debug/54519 * ipa-split.c (split_function): Add debug args and debug source and normal stmts for args_to_skip which are gimple regs. * tree-inline.c (copy_debug_stmt): When inlining, adjust source debug bind stmts to debug binds of corresponding DEBUG_EXPR_DECL. * gcc.dg/guality/pr54519-1.c: New test. * gcc.dg/guality/pr54519-2.c: New test. * gcc.dg/guality/pr54519-3.c: New test. * gcc.dg/guality/pr54519-4.c: New test. * gcc.dg/guality/pr54519-5.c: New test. * gcc.dg/guality/pr54519-6.c: New test. --- gcc/ipa-split.c.jj 2012-10-05 09:42:54.240259416 +0200 +++ gcc/ipa-split.c 2012-10-05 15:58:01.944786294 +0200 @@ -1059,6 +1059,7 @@ split_function (struct split_point *spli gimple last_stmt = NULL; unsigned int i; tree arg, ddef; + VEC(tree, gc) **debug_args = NULL; if (dump_file) { @@ -1232,6 +1233,83 @@ split_function (struct split_point *spli gimple_set_block (call, DECL_INITIAL (current_function_decl)); VEC_free (tree, heap, args_to_pass); + /* For optimized away parameters, add on the caller side + before the call + DEBUG D#X => parm_Y(D) + stmts and associate D#X with parm in decl_debug_args_lookup + vector to say for debug info that if parameter parm had been passed, + it would have value parm_Y(D). */ + if (args_to_skip) + for (parm = DECL_ARGUMENTS (current_function_decl), num = 0; + parm; parm = DECL_CHAIN (parm), num++) + if (bitmap_bit_p (args_to_skip, num) + && is_gimple_reg (parm)) + { + 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. */ + arg = get_or_create_ssa_default_def (cfun, parm); + if (!MAY_HAVE_DEBUG_STMTS) + continue; + + if (debug_args == NULL) + debug_args = decl_debug_args_insert (node->symbol.decl); + ddecl = make_node (DEBUG_EXPR_DECL); + DECL_ARTIFICIAL (ddecl) = 1; + TREE_TYPE (ddecl) = TREE_TYPE (parm); + DECL_MODE (ddecl) = DECL_MODE (parm); + VEC_safe_push (tree, gc, *debug_args, DECL_ORIGIN (parm)); + VEC_safe_push (tree, gc, *debug_args, ddecl); + def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), + call); + gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT); + } + /* And on the callee side, add + DEBUG D#Y s=> parm + DEBUG var => D#Y + stmts to the first bb where var is a VAR_DECL created for the + optimized away parameter in DECL_INITIAL block. This hints + in the debug info that var (whole DECL_ORIGIN is the parm PARM_DECL) + is optimized away, but could be looked up at the call site + as value of D#X there. */ + if (debug_args != NULL) + { + unsigned int i; + tree var, vexpr; + gimple_stmt_iterator cgsi; + gimple def_temp; + + push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); + var = BLOCK_VARS (DECL_INITIAL (node->symbol.decl)); + i = VEC_length (tree, *debug_args); + cgsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR)); + do + { + i -= 2; + while (var != NULL_TREE + && DECL_ABSTRACT_ORIGIN (var) + != VEC_index (tree, *debug_args, i)) + var = TREE_CHAIN (var); + if (var == NULL_TREE) + break; + vexpr = make_node (DEBUG_EXPR_DECL); + parm = VEC_index (tree, *debug_args, i); + DECL_ARTIFICIAL (vexpr) = 1; + TREE_TYPE (vexpr) = TREE_TYPE (parm); + DECL_MODE (vexpr) = DECL_MODE (parm); + def_temp = gimple_build_debug_source_bind (vexpr, parm, + NULL); + gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT); + def_temp = gimple_build_debug_bind (var, vexpr, NULL); + gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT); + } + while (i); + pop_cfun (); + } + /* We avoid address being taken on any variable used by split part, so return slot optimization is always possible. Moreover this is required to make DECL_BY_REFERENCE work. */ --- gcc/tree-inline.c.jj 2012-10-05 14:57:13.887906317 +0200 +++ gcc/tree-inline.c 2012-10-05 15:03:56.721669052 +0200 @@ -2374,6 +2374,31 @@ copy_debug_stmt (gimple stmt, copy_body_ gimple_debug_source_bind_set_var (stmt, t); walk_tree (gimple_debug_source_bind_get_value_ptr (stmt), remap_gimple_op_r, &wi, NULL); + /* When inlining and source bind refers to one of the optimized + away parameters, change the source bind into normal debug bind + referring to the corresponding DEBUG_EXPR_DECL that should have + been bound before the call stmt. */ + t = gimple_debug_source_bind_get_value (stmt); + if (t != NULL_TREE + && TREE_CODE (t) == PARM_DECL + && id->gimple_call) + { + VEC(tree, gc) **debug_args = decl_debug_args_lookup (id->src_fn); + unsigned int i; + if (debug_args != NULL) + { + for (i = 0; i < VEC_length (tree, *debug_args); i += 2) + if (VEC_index (tree, *debug_args, i) == DECL_ORIGIN (t) + && TREE_CODE (VEC_index (tree, *debug_args, i + 1)) + == DEBUG_EXPR_DECL) + { + t = VEC_index (tree, *debug_args, i + 1); + stmt->gsbase.subcode = GIMPLE_DEBUG_BIND; + gimple_debug_bind_set_value (stmt, t); + break; + } + } + } } processing_debug_stmt = 0; --- gcc/testsuite/gcc.dg/guality/pr54519-2.c.jj 2012-10-02 16:27:24.862658030 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-2.c 2012-10-02 16:27:24.862658030 +0200 @@ -0,0 +1,45 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +__attribute__((noinline, noclone)) void +fn1 (int x) +{ + __asm volatile ("" : "+r" (x) : : "memory"); +} + +static int +fn2 (int x, int y) +{ + if (y) + { + fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */ + fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */ + fn1 (x); + fn1 (x); + y = -2 + x; + y = y * y * y + y; + fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */ + } + return x; +} + +__attribute__((noinline, noclone)) int +fn3 (int x, int y) +{ + return fn2 (x, y) + y; +} + +__attribute__((noinline, noclone)) int +fn4 (int x, int y) +{ + return fn2 (x, y) + y; +} + +int +main () +{ + fn3 (6, 25); + fn4 (4, 117); + return 0; +} --- gcc/testsuite/gcc.dg/guality/pr54519-1.c.jj 2012-10-02 16:27:24.862658030 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-1.c 2012-10-02 16:27:24.862658030 +0200 @@ -0,0 +1,48 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +__attribute__((noinline, noclone)) void +fn1 (int x) +{ + __asm volatile ("" : "+r" (x) : : "memory"); +} + +static int +fn2 (int x, int y, int z) +{ + int a = 8; + if (x != z) + { + fn1 (x); + fn1 (x); /* { dg-final { gdb-test 20 "x" "36" } } */ + if (x == 36) /* { dg-final { gdb-test 20 "y" "25" } } */ + fn1 (x); /* { dg-final { gdb-test 20 "z" "6" } } */ + fn1 (x); /* { dg-final { gdb-test 23 "x" "98" } } */ + if (x == 98) /* { dg-final { gdb-test 23 "y" "117" } } */ + fn1 (x); /* { dg-final { gdb-test 23 "z" "8" } } */ + fn1 (x); + fn1 (x + a); + } + return y; +} + +__attribute__((noinline, noclone)) int +fn3 (int x, int y) +{ + return fn2 (x, y, 6); +} + +__attribute__((noinline, noclone)) int +fn4 (int x, int y) +{ + return fn2 (x, y, 8); +} + +int +main () +{ + fn3 (36, 25); + fn4 (98, 117); + return 0; +} --- gcc/testsuite/gcc.dg/guality/pr54519-3.c.jj 2012-10-02 16:27:24.863658017 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-3.c 2012-10-02 16:27:24.863658017 +0200 @@ -0,0 +1,42 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +__attribute__((noinline, noclone)) void +fn1 (int x) +{ + __asm volatile ("" : "+r" (x) : : "memory"); +} + +static int +fn2 (int x, int y, int z) +{ + int a = 8; + if (x != z) + { + fn1 (x); + fn1 (x); /* { dg-final { gdb-test 20 "x" "36" } } */ + if (x == 36) /* { dg-final { gdb-test 20 "y" "25" } } */ + fn1 (x); /* { dg-final { gdb-test 20 "z" "6" } } */ + fn1 (x); /* { dg-final { gdb-test 23 "x" "98" } } */ + if (x == 98) /* { dg-final { gdb-test 23 "y" "117" } } */ + fn1 (x); /* { dg-final { gdb-test 23 "z" "8" } } */ + fn1 (x); + fn1 (x + a); + } + return y; +} + +int (*p) (int, int, int) = fn2; + +int +main () +{ + __asm volatile ("" : : : "memory"); + int (*q) (int, int, int) = p; + __asm volatile ("" : : : "memory"); + q (36, 25, 6); + q (98, 117, 8); + q (0, 0, 0); + return 0; +} --- gcc/testsuite/gcc.dg/guality/pr54519-4.c.jj 2012-10-02 16:27:24.863658017 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-4.c 2012-10-02 16:27:24.863658017 +0200 @@ -0,0 +1,39 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +__attribute__((noinline, noclone)) void +fn1 (int x) +{ + __asm volatile ("" : "+r" (x) : : "memory"); +} + +static int +fn2 (int x, int y) +{ + if (y) + { + fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */ + fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */ + fn1 (x); + fn1 (x); + y = -2 + x; + y = y * y * y + y; + fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */ + } + return x; +} + +int (*p) (int, int) = fn2; + +int +main () +{ + __asm volatile ("" : : : "memory"); + int (*q) (int, int) = p; + __asm volatile ("" : : : "memory"); + q (6, 25); + q (4, 117); + q (0, 0); + return 0; +} --- gcc/testsuite/gcc.dg/guality/pr54519-5.c.jj 2012-10-02 16:27:24.863658017 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-5.c 2012-10-02 16:27:24.863658017 +0200 @@ -0,0 +1,45 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +__attribute__((noinline, noclone)) void +fn1 (int x) +{ + __asm volatile ("" : "+r" (x) : : "memory"); +} + +static int +fn2 (int x, int y) +{ + if (y) + { + fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */ + fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */ + fn1 (x); + fn1 (x); + y = -2 + x; + y = y * y * y + y; + fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */ + } + return x; +} + +__attribute__((noinline, noclone)) int +fn3 (int x, int y) +{ + return fn2 (x, y); +} + +__attribute__((noinline, noclone)) int +fn4 (int x, int y) +{ + return fn2 (x, y); +} + +int +main () +{ + fn3 (6, 25); + fn4 (4, 117); + return 0; +} --- gcc/testsuite/gcc.dg/guality/pr54519-6.c.jj 2012-10-02 18:03:45.137732997 +0200 +++ gcc/testsuite/gcc.dg/guality/pr54519-6.c 2012-10-02 18:03:19.000000000 +0200 @@ -0,0 +1,27 @@ +/* PR debug/54519 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +#include "../nop.h" + +static inline void +f1 (int x, int y) +{ + asm volatile (NOP); /* { dg-final { gdb-test 11 "x" "2" } } */ + asm volatile (NOP); /* { dg-final { gdb-test 11 "y" "0" } } */ +} + +static inline void +f2 (int z) +{ + f1 (z, 0); + f1 (z, 1); +} + +int +main () +{ + f2 (2); + f2 (3); + return 0; +} Jakub