Commit 878eef4a by Jakub Jelinek Committed by Jakub Jelinek

re PR debug/54519 (Debug info quality regression due to (pointless) partial inlining)

	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.

From-SVN: r192139
parent 3b1cd14d
2012-10-05 Jakub Jelinek <jakub@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.
2012-10-05 Georg-Johann Lay <avr@gjlay.de> 2012-10-05 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.md: Fix indentations of insn C snippets. * config/avr/avr.md: Fix indentations of insn C snippets.
......
...@@ -1059,6 +1059,7 @@ split_function (struct split_point *split_point) ...@@ -1059,6 +1059,7 @@ split_function (struct split_point *split_point)
gimple last_stmt = NULL; gimple last_stmt = NULL;
unsigned int i; unsigned int i;
tree arg, ddef; tree arg, ddef;
VEC(tree, gc) **debug_args = NULL;
if (dump_file) if (dump_file)
{ {
...@@ -1232,6 +1233,83 @@ split_function (struct split_point *split_point) ...@@ -1232,6 +1233,83 @@ split_function (struct split_point *split_point)
gimple_set_block (call, DECL_INITIAL (current_function_decl)); gimple_set_block (call, DECL_INITIAL (current_function_decl));
VEC_free (tree, heap, args_to_pass); 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, /* We avoid address being taken on any variable used by split part,
so return slot optimization is always possible. Moreover this is so return slot optimization is always possible. Moreover this is
required to make DECL_BY_REFERENCE work. */ required to make DECL_BY_REFERENCE work. */
......
2012-10-05 Jakub Jelinek <jakub@redhat.com>
PR debug/54519
* 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.
2012-10-05 Paolo Carlini <paolo.carlini@oracle.com> 2012-10-05 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/50893 PR c++/50893
......
/* 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;
}
/* 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;
}
/* 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;
}
/* 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;
}
/* 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;
}
/* 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;
}
...@@ -2374,6 +2374,31 @@ copy_debug_stmt (gimple stmt, copy_body_data *id) ...@@ -2374,6 +2374,31 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
gimple_debug_source_bind_set_var (stmt, t); gimple_debug_source_bind_set_var (stmt, t);
walk_tree (gimple_debug_source_bind_get_value_ptr (stmt), walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
remap_gimple_op_r, &wi, NULL); 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; processing_debug_stmt = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment