re PR debug/43329 (Early inlining causes suboptimal debug info)
authorJakub Jelinek <jakub@redhat.com>
Fri, 12 Mar 2010 13:04:37 +0000 (14:04 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 12 Mar 2010 13:04:37 +0000 (14:04 +0100)
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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/guality/pr43329-1.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c
gcc/tree-inline.c

index f16078e..481a248 100644 (file)
@@ -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.
index 4601444..c76d54f 100644 (file)
@@ -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);
index 279f499..ceb6d84 100644 (file)
@@ -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 (file)
index 0000000..e80888e
--- /dev/null
@@ -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;
+}
index 68929f8..eae0c84 100644 (file)
@@ -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);
        }
     }
 
index de8ca70..f3c4204 100644 (file)
@@ -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
        {