From: Jakub Jelinek Date: Fri, 12 Mar 2010 13:04:37 +0000 (+0100) Subject: re PR debug/43329 (Early inlining causes suboptimal debug info) X-Git-Tag: upstream/12.2.0~94276 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70235ab941c572a4efabd15fcf737c22fc999814;p=platform%2Fupstream%2Fgcc.git re PR debug/43329 (Early inlining causes suboptimal debug info) PR debug/43329 * tree-inline.c (remap_decls): Put old_var rather than origin_var into *nonlocalized_list vector. * dwarf2out.c (gen_formal_parameter_die): Call decl_ultimate_origin even if origin is non-NULL. (gen_variable_die): Likewise. (process_scope_var): Don't change origin. (gen_decl_die): Likewise. * tree-cfgcleanup.c (remove_forwarder_block): Check single_pred_p before adding new edges instead of after it, fix moving over debug stmts. * gcc.dg/guality/pr43329-1.c: New test. From-SVN: r157402 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f16078e..481a248 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-03-12 Jakub Jelinek + + PR debug/43329 + * tree-inline.c (remap_decls): Put old_var rather than origin_var + into *nonlocalized_list vector. + * dwarf2out.c (gen_formal_parameter_die): Call decl_ultimate_origin + even if origin is non-NULL. + (gen_variable_die): Likewise. + (process_scope_var): Don't change origin. + (gen_decl_die): Likewise. + * tree-cfgcleanup.c (remove_forwarder_block): Check single_pred_p + before adding new edges instead of after it, fix moving over + debug stmts. + 2010-03-11 David S. Miller * configure.ac (gcc_cv_as_cfi_advance_working): Skip a multiple of four. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4601444..c76d54f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -17382,14 +17382,16 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p, dw_die_ref context_die) { tree node_or_origin = node ? node : origin; + tree ultimate_origin; dw_die_ref parm_die = new_die (DW_TAG_formal_parameter, context_die, node); switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin))) { case tcc_declaration: - if (!origin) - origin = decl_ultimate_origin (node); + ultimate_origin = decl_ultimate_origin (node_or_origin); + if (node || ultimate_origin) + origin = ultimate_origin; if (origin != NULL) add_abstract_origin_attribute (parm_die, origin); else @@ -18106,15 +18108,16 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) HOST_WIDE_INT off; tree com_decl; tree decl_or_origin = decl ? decl : origin; + tree ultimate_origin; dw_die_ref var_die; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; dw_die_ref origin_die; int declaration = (DECL_EXTERNAL (decl_or_origin) || class_or_namespace_scope_p (context_die)); - if (!origin) - origin = decl_ultimate_origin (decl); - + ultimate_origin = decl_ultimate_origin (decl_or_origin); + if (decl || ultimate_origin) + origin = ultimate_origin; com_decl = fortran_common (decl_or_origin, &off); /* Symbol in common gets emitted as a child of the common block, in the form @@ -19160,10 +19163,6 @@ process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die) { dw_die_ref die; tree decl_or_origin = decl ? decl : origin; - tree ultimate_origin = origin ? decl_ultimate_origin (origin) : NULL; - - if (ultimate_origin) - origin = ultimate_origin; if (TREE_CODE (decl_or_origin) == FUNCTION_DECL) die = lookup_decl_die (decl_or_origin); @@ -19435,7 +19434,7 @@ static void gen_decl_die (tree decl, tree origin, dw_die_ref context_die) { tree decl_or_origin = decl ? decl : origin; - tree class_origin = NULL; + tree class_origin = NULL, ultimate_origin; if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin)) return; @@ -19481,7 +19480,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die) /* If we're emitting a clone, emit info for the abstract instance. */ if (origin || DECL_ORIGIN (decl) != decl) - dwarf2out_abstract_function (origin ? origin : DECL_ABSTRACT_ORIGIN (decl)); + dwarf2out_abstract_function (origin + ? DECL_ORIGIN (origin) + : DECL_ABSTRACT_ORIGIN (decl)); /* If we're emitting an out-of-line copy of an inline function, emit info for the abstract instance and set up to refer to it. */ @@ -19580,9 +19581,9 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die) complicated because of the possibility that the VAR_DECL really represents an inlined instance of a formal parameter for an inline function. */ - if (!origin) - origin = decl_ultimate_origin (decl); - if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL) + ultimate_origin = decl_ultimate_origin (decl_or_origin); + if (ultimate_origin != NULL_TREE + && TREE_CODE (ultimate_origin) == PARM_DECL) gen_formal_parameter_die (decl, origin, true /* Emit name attribute. */, context_die); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 279f499..ceb6d84 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-03-12 Jakub Jelinek + + PR debug/43329 + * gcc.dg/guality/pr43329-1.c: New test. + 2010-03-11 Martin Jambor PR tree-optimization/43257 diff --git a/gcc/testsuite/gcc.dg/guality/pr43329-1.c b/gcc/testsuite/gcc.dg/guality/pr43329-1.c new file mode 100644 index 0000000..e80888e --- /dev/null +++ b/gcc/testsuite/gcc.dg/guality/pr43329-1.c @@ -0,0 +1,50 @@ +/* PR debug/43329 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +static inline void +foo (int argx) +{ + int varx = argx; + __asm__ volatile ("nop"); /* { dg-final { gdb-test 10 "argx" "25" } } */ + __asm__ volatile ("nop" : : "g" (varx)); /* { dg-final { gdb-test 10 "varx" "25" } } */ +} + +int i; + +__attribute__((noinline)) +void baz (int x) +{ + asm volatile ("" : : "r" (x) : "memory"); +} + +static inline void +bar (void) +{ + foo (25); + i = i + 2; + i = i * 2; + i = i - 4; + baz (i); + i = i * 2; + i = i >> 1; + i = i << 6; + baz (i); + i = i + 2; + i = i * 2; + i = i - 4; + baz (i); + i = i * 2; + i = i >> 6; + i = i << 1; + baz (i); +} + +int +main (void) +{ + __asm__ volatile ("" : "=r" (i) : "0" (0)); + bar (); + bar (); + return i; +} diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 68929f8..eae0c84 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -376,6 +376,7 @@ remove_forwarder_block (basic_block bb) gimple label; edge_iterator ei; gimple_stmt_iterator gsi, gsi_to; + bool can_move_debug_stmts; /* We check for infinite loops already in tree_forwarder_block_p. However it may happen that the infinite loop is created @@ -424,6 +425,8 @@ remove_forwarder_block (basic_block bb) } } + can_move_debug_stmts = single_pred_p (dest); + /* Redirect the edges. */ for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) { @@ -480,15 +483,16 @@ remove_forwarder_block (basic_block bb) /* Move debug statements if the destination has just a single predecessor. */ - if (single_pred_p (dest)) + if (can_move_debug_stmts) { gsi_to = gsi_after_labels (dest); for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); ) { - if (!is_gimple_debug (gsi_stmt (gsi))) + gimple debug = gsi_stmt (gsi); + if (!is_gimple_debug (debug)) break; gsi_remove (&gsi, false); - gsi_insert_before (&gsi_to, label, GSI_SAME_STMT); + gsi_insert_before (&gsi_to, debug, GSI_SAME_STMT); } } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index de8ca70..f3c4204 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -533,7 +533,6 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id) for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var)) { tree new_var; - tree origin_var = DECL_ORIGIN (old_var); if (can_be_nonlocal (old_var, id)) { @@ -545,7 +544,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id) if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE) && !DECL_IGNORED_P (old_var) && nonlocalized_list) - VEC_safe_push (tree, gc, *nonlocalized_list, origin_var); + VEC_safe_push (tree, gc, *nonlocalized_list, old_var); continue; } @@ -563,7 +562,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id) if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE) && !DECL_IGNORED_P (old_var) && nonlocalized_list) - VEC_safe_push (tree, gc, *nonlocalized_list, origin_var); + VEC_safe_push (tree, gc, *nonlocalized_list, old_var); } else {