@@ -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,65 @@ split_function (struct split_point *spli
gimple_set_block (call, DECL_INITIAL (current_function_decl));
VEC_free (tree, heap, args_to_pass);
+ 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;
+
+ 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, 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);
+ }
+ 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. */
@@ -2355,6 +2355,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) == t
+ && TREE_CODE (VEC_index (tree, *debug_args, i + 1))
+ == DEBUG_EXPR_DECL)
+ {
+ t = VEC_index (tree, *debug_args, i + 1);
+ gimple_debug_source_bind_set_value (stmt, t);
+ stmt->gsbase.subcode = GIMPLE_DEBUG_BIND;
+ break;
+ }
+ }
+ }
}
processing_debug_stmt = 0;
@@ -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;
+}
@@ -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;
+}
@@ -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;
+}
@@ -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;
+}
@@ -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;
+}