summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-03-12 14:04:37 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2010-03-12 14:04:37 +0100
commit70235ab941c572a4efabd15fcf737c22fc999814 (patch)
tree0b29e6fc9123592f39dc916a03b18fd320d0c99f
parentd76f631a86565e06d58ee1dbf63a386fd5e9fdec (diff)
downloadgcc-70235ab941c572a4efabd15fcf737c22fc999814.tar.gz
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
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/dwarf2out.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr43329-1.c50
-rw-r--r--gcc/tree-cfgcleanup.c10
-rw-r--r--gcc/tree-inline.c5
6 files changed, 93 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f16078ef707..481a2480eb8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2010-03-12 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <davem@davemloft.net>
* configure.ac (gcc_cv_as_cfi_advance_working): Skip a multiple of four.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 460144477eb..c76d54f39c2 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 279f499a238..ceb6d848674 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/43329
+ * gcc.dg/guality/pr43329-1.c: New test.
+
2010-03-11 Martin Jambor <mjambor@suse.cz>
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 00000000000..e80888e40e5
--- /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 68929f8de26..eae0c84cef5 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 de8ca707ce2..f3c420475df 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
{