re PR debug/81307 (g++.dg/debug/debug9.C -gstabs FAILs)
authorJakub Jelinek <jakub@redhat.com>
Mon, 27 Nov 2017 08:48:56 +0000 (09:48 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 27 Nov 2017 08:48:56 +0000 (09:48 +0100)
PR debug/81307
* dbxout.c (lastlineno): New variable.
(dbx_debug_hooks): Use dbxout_switch_text_section as
switch_text_section debug hook.
(dbxout_function_end): Switch to current_function_section
rather than function_section.  If crtl->has_bb_partition,
output just one N_FUN, depending on in_cold_section_p.
(dbxout_source_line): Remember last lineno in lastlineno.
(dbxout_switch_text_section): New function.
(dbxout_function_decl): Adjust dbxout_block caller.
(dbx_block_with_cold_children): New function.
(dbxout_block): Return true if any LBRAC/RBRAC have been
emitted.  Use dbx_block_with_cold_children at depth == 0
in second partition.  Add PARENT_BLOCKNUM argument, pass
it optionally adjusted to children.  Output LBRAC/RBRAC
around recursive call only if the block is in the current
partition, if not and anything was output, emit empty
range LBRAC/RBRAC.
* final.c (final_scan_insn): Compute cold_function_name
before calling switch_text_section debug hook.  Call
that hook even if dwarf2out_do_frame if not emitting
dwarf debug info.

* g++.dg/debug/debug9.C: Remove -fno-reorder-blocks-and-partition
workaround.

From-SVN: r255161

gcc/ChangeLog
gcc/dbxout.c
gcc/final.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/debug/debug9.C

index 7189a66ed8395f29406c9356470eab244ff0d0d0..75a860e3f814493e8776167327105bc63e70d9d0 100644 (file)
@@ -1,5 +1,28 @@
 2017-11-27  Jakub Jelinek  <jakub@redhat.com>
 
+       PR debug/81307
+       * dbxout.c (lastlineno): New variable.
+       (dbx_debug_hooks): Use dbxout_switch_text_section as
+       switch_text_section debug hook.
+       (dbxout_function_end): Switch to current_function_section
+       rather than function_section.  If crtl->has_bb_partition,
+       output just one N_FUN, depending on in_cold_section_p.
+       (dbxout_source_line): Remember last lineno in lastlineno.
+       (dbxout_switch_text_section): New function.
+       (dbxout_function_decl): Adjust dbxout_block caller.
+       (dbx_block_with_cold_children): New function.
+       (dbxout_block): Return true if any LBRAC/RBRAC have been
+       emitted.  Use dbx_block_with_cold_children at depth == 0
+       in second partition.  Add PARENT_BLOCKNUM argument, pass
+       it optionally adjusted to children.  Output LBRAC/RBRAC
+       around recursive call only if the block is in the current
+       partition, if not and anything was output, emit empty
+       range LBRAC/RBRAC.
+       * final.c (final_scan_insn): Compute cold_function_name
+       before calling switch_text_section debug hook.  Call
+       that hook even if dwarf2out_do_frame if not emitting
+       dwarf debug info.
+
        PR target/83100
        * varasm.c (bss_initializer_p): Return true for DECL_COMMON
        TREE_READONLY decls.
index 49a858339f8c4eeead48b30d5a050085e2f5c554..89f2d1f0cd4ace29e8c882acd2d320c7bc3f14dd 100644 (file)
@@ -244,6 +244,10 @@ static GTY(()) int source_label_number = 1;
 
 static GTY(()) const char *lastfile;
 
+/* Last line number mentioned in a NOTE insn.  */
+
+static GTY(()) unsigned int lastlineno;
+
 /* Used by PCH machinery to detect if 'lastfile' should be reset to
    base_input_file.  */
 static GTY(()) int lastfile_is_base;
@@ -334,6 +338,7 @@ static void debug_free_queue (void);
 
 static void dbxout_source_line (unsigned int, unsigned int, const char *,
                                int, bool);
+static void dbxout_switch_text_section (void);
 static void dbxout_begin_prologue (unsigned int, unsigned int, const char *);
 static void dbxout_source_file (const char *);
 static void dbxout_function_end (tree);
@@ -380,7 +385,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   dbxout_handle_pch,                    /* handle_pch */
   debug_nothing_rtx_insn,               /* var_location */
   debug_nothing_tree,                   /* size_function */
-  debug_nothing_void,                    /* switch_text_section */
+  dbxout_switch_text_section,            /* switch_text_section */
   debug_nothing_tree_tree,              /* set_name */
   0,                                     /* start_end_main_source_file */
   TYPE_SYMTAB_IS_ADDRESS                 /* tree_type_symtab_field */
@@ -902,7 +907,7 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
 
   /* The Lscope label must be emitted even if we aren't doing anything
      else; dbxout_block needs it.  */
-  switch_to_section (function_section (current_function_decl));
+  switch_to_section (current_function_section ());
 
   /* Convert Lscope into the appropriate format for local labels in case
      the system doesn't insert underscores in front of user generated
@@ -923,11 +928,12 @@ dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
   if (crtl->has_bb_partition)
     {
       dbxout_begin_empty_stabs (N_FUN);
-      dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
-                                   crtl->subsections.hot_section_label);
-      dbxout_begin_empty_stabs (N_FUN);
-      dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
-                                   crtl->subsections.cold_section_label);
+      if (in_cold_section_p)
+       dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
+                                     crtl->subsections.cold_section_label);
+      else
+       dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
+                                     crtl->subsections.hot_section_label);
     }
   else
     {
@@ -1215,7 +1221,7 @@ dbxout_handle_pch (unsigned at_end)
 
 #if defined (DBX_DEBUGGING_INFO)
 
-static void dbxout_block (tree, int, tree);
+static bool dbxout_block (tree, int, tree, int);
 
 /* Output debugging info to FILE to switch to sourcefile FILENAME.  */
 
@@ -1289,6 +1295,60 @@ dbxout_source_line (unsigned int lineno, unsigned int column ATTRIBUTE_UNUSED,
   else
     dbxout_stabd (N_SLINE, lineno);
 #endif
+  lastlineno = lineno;
+}
+
+/* Unfortunately, at least when emitting relative addresses, STABS
+   has no way to express multiple partitions.  Represent a function
+   as two functions in this case.  */
+
+static void
+dbxout_switch_text_section (void)
+{
+  /* The N_FUN tag at the end of the function is a GNU extension,
+     which may be undesirable, and is unnecessary if we do not have
+     named sections.  */
+  in_cold_section_p = !in_cold_section_p;
+  switch_to_section (current_function_section ());
+  dbxout_block (DECL_INITIAL (current_function_decl), 0,
+               DECL_ARGUMENTS (current_function_decl), -1);
+  dbxout_function_end (current_function_decl);
+  in_cold_section_p = !in_cold_section_p;
+
+  switch_to_section (current_function_section ());
+
+  tree context = decl_function_context (current_function_decl);
+  extern tree cold_function_name;
+
+  dbxout_begin_complex_stabs ();
+  stabstr_I (cold_function_name);
+  stabstr_S (":f");
+
+  tree type = TREE_TYPE (current_function_decl);
+  if (TREE_TYPE (type))
+    dbxout_type (TREE_TYPE (type), 0);
+  else
+    dbxout_type (void_type_node, 0);
+
+  if (context != 0)
+    {
+      stabstr_C (',');
+      stabstr_I (cold_function_name);
+      stabstr_C (',');
+      stabstr_I (DECL_NAME (context));
+    }
+
+  dbxout_finish_complex_stabs (current_function_decl, N_FUN, 0,
+                              crtl->subsections.cold_section_label, 0);
+
+  /* pre-increment the scope counter */
+  scope_labelno++;
+
+  dbxout_source_line (lastlineno, 0, lastfile, 0, true);
+  /* Output function begin block at function scope, referenced
+     by dbxout_block, dbxout_source_line and dbxout_function_end.  */
+  emit_pending_bincls_if_required ();
+  targetm.asm_out.internal_label (asm_out_file, "LFBB", scope_labelno);
 }
 
 /* Describe the beginning of an internal block within a function.  */
@@ -1322,7 +1382,7 @@ dbxout_function_decl (tree decl)
 #ifndef DBX_FUNCTION_FIRST
   dbxout_begin_function (decl);
 #endif
-  dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
+  dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl), -1);
   dbxout_function_end (decl);
 }
 
@@ -3664,6 +3724,26 @@ dbx_output_rbrac (const char *label,
     dbxout_stab_value_label (label);
 }
 
+/* Return true is at least one block among BLOCK, its children or siblings
+   which has TREE_USED, TREE_ASM_WRITTEN and BLOCK_IN_COLD_SECTION_P
+   set.  If there is none, clear TREE_USED bit on such blocks.  */
+
+static bool
+dbx_block_with_cold_children (tree block)
+{
+  bool ret = false;
+  for (; block; block = BLOCK_CHAIN (block))
+    if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
+      {
+       bool children = dbx_block_with_cold_children (BLOCK_SUBBLOCKS (block));
+       if (BLOCK_IN_COLD_SECTION_P (block) || children)
+         ret = true;
+       else
+         TREE_USED (block) = false;
+      }
+  return ret;
+}
+
 /* Output everything about a symbol block (a BLOCK node
    that represents a scope level),
    including recursive output of contained blocks.
@@ -3679,22 +3759,31 @@ dbx_output_rbrac (const char *label,
    except for the outermost block.
 
    Actually, BLOCK may be several blocks chained together.
-   We handle them all in sequence.  */
+   We handle them all in sequence.
 
-static void
-dbxout_block (tree block, int depth, tree args)
+   Return true if we emitted any LBRAC/RBRAC.  */
+
+static bool
+dbxout_block (tree block, int depth, tree args, int parent_blocknum)
 {
+  bool ret = false;
   char begin_label[20];
   /* Reference current function start using LFBB.  */
   ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno);
 
-  while (block)
+  /* If called for the second partition, ignore blocks that don't have
+     any children in the second partition.  */
+  if (crtl->has_bb_partition && in_cold_section_p && depth == 0)
+    dbx_block_with_cold_children (block);
+
+  for (; block; block = BLOCK_CHAIN (block))
     {
       /* Ignore blocks never expanded or otherwise marked as real.  */
       if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
        {
          int did_output;
          int blocknum = BLOCK_NUMBER (block);
+         int this_parent = parent_blocknum;
 
          /* In dbx format, the syms of a block come before the N_LBRAC.
             If nothing is output, we don't need the N_LBRAC, either.  */
@@ -3708,11 +3797,13 @@ dbxout_block (tree block, int depth, tree args)
             the block.  Use the block's tree-walk order to generate
             the assembler symbols LBBn and LBEn
             that final will define around the code in this block.  */
-         if (did_output)
+         if (did_output
+             && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
            {
              char buf[20];
              const char *scope_start;
 
+             ret = true;
              if (depth == 0)
                /* The outermost block doesn't get LBB labels; use
                   the LFBB local symbol emitted by dbxout_begin_prologue.  */
@@ -3721,16 +3812,21 @@ dbxout_block (tree block, int depth, tree args)
                {
                  ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
                  scope_start = buf;
+                 this_parent = blocknum;
                }
 
              dbx_output_lbrac (scope_start, begin_label);
            }
 
          /* Output the subblocks.  */
-         dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
+         bool children
+           = dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE,
+                           this_parent);
+         ret |= children;
 
          /* Refer to the marker for the end of the block.  */
-         if (did_output)
+         if (did_output
+             && BLOCK_IN_COLD_SECTION_P (block) == in_cold_section_p)
            {
              char buf[100];
              if (depth == 0)
@@ -3743,9 +3839,29 @@ dbxout_block (tree block, int depth, tree args)
 
              dbx_output_rbrac (buf, begin_label);
            }
+         else if (did_output && !children)
+           {
+             /* If we emitted any vars and didn't output any LBRAC/RBRAC,
+                either at this level or any lower level, we need to emit
+                an empty LBRAC/RBRAC pair now.  */
+             char buf[20];
+             const char *scope_start;
+
+             ret = true;
+             if (parent_blocknum == -1)
+               scope_start = begin_label;
+             else
+               {
+                 ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", parent_blocknum);
+                 scope_start = buf;
+               }
+
+             dbx_output_lbrac (scope_start, begin_label);
+             dbx_output_rbrac (scope_start, begin_label);
+           }
        }
-      block = BLOCK_CHAIN (block);
     }
+  return ret;
 }
 
 /* Output the information about a function and its arguments and result.
index 672c5bbc49c3d7eaf2ec7a56156a813107e9476b..fdae241bc832246c257677db8f3870b5144f6fdc 100644 (file)
@@ -2210,8 +2210,17 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
        case NOTE_INSN_SWITCH_TEXT_SECTIONS:
          in_cold_section_p = !in_cold_section_p;
 
+         if (in_cold_section_p)
+           cold_function_name
+             = clone_function_name (current_function_decl, "cold");
+
          if (dwarf2out_do_frame ())
-           dwarf2out_switch_text_section ();
+           {
+             dwarf2out_switch_text_section ();
+             if (!dwarf2_debug_info_emitted_p (current_function_decl)
+                 && !DECL_IGNORED_P (current_function_decl))
+               debug_hooks->switch_text_section ();
+           }
          else if (!DECL_IGNORED_P (current_function_decl))
            debug_hooks->switch_text_section ();
 
@@ -2223,8 +2232,6 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
             suffixing "cold" to the original function's name.  */
          if (in_cold_section_p)
            {
-             cold_function_name
-               = clone_function_name (current_function_decl, "cold");
 #ifdef ASM_DECLARE_COLD_FUNCTION_NAME
              ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
                                              IDENTIFIER_POINTER
index ff40f3657e34140b56f8307dda4ede4e9f4aa974..87e930a3a0a133bbd40fced1f8769014ded6f707 100644 (file)
@@ -1,5 +1,9 @@
 2017-11-27  Jakub Jelinek  <jakub@redhat.com>
 
+       PR debug/81307
+       * g++.dg/debug/debug9.C: Remove -fno-reorder-blocks-and-partition
+       workaround.
+
        PR target/83100
        * gcc.dg/pr83100-1.c: New test.
        * gcc.dg/pr83100-2.c: New test.
index 8cf2327e0693d982a13ad60a5367ef80224a34a1..aa328ee6f79abe7ead17bd06fb1a793f91d68aeb 100644 (file)
@@ -1,9 +1,4 @@
 /* { dg-do assemble } */
-/* Partitioning causes hot/cold section emission and breaks stabs
-   debugging.  */
-/* { dg-additional-options "-fno-reorder-blocks-and-partition" } */
-
-
 /* This testcase requires entries in the debug_range section in DWARF which
    refer to a vague linkage function.  */