OSDN Git Service

* emit-rtl.c (remove_unncessary_notes): Remove notes for empty
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Feb 2000 09:51:42 +0000 (09:51 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 28 Feb 2000 09:51:42 +0000 (09:51 +0000)
blocks.
* final.c (next_block_index): Remove.
(max_block_depth): Likewise.
(pending_blocks): Likewise.
(init_final): Don't initialize them.
(final_start_function): Don't set next_block_index.  Set up
BLOCK_NUMBER.
(final_scan_insn): Use BLOCK_NUMBER, not next_block_index.
* function.h (number_blocks): New function.
* function.c (get_block_vector): New function.
(identify_blocks): Use it.
(reorder_blocks): Set NOTE_BLOCK.
(number_blocks): New function.
* tree.def (BLOCK): Add documentation for TREE_ASM_WRITTEN flag.
* tree.h (BLOCK_NUMBER): New macro.
(tree_block): Add block_num field.
* dbxout.c (next_block_number): Remove.
(dbxout_init): Don't set it.
(dbxout_block): Only output blocks that have TREE_ASM_WRITTEN
set.  Use BLOCK_NUMBER, rather than next_block_num, to determine
block numbers.
* toplev.c (rest_of_compilation): Always call
find_loop_tree_blocks.  Fix indentation.
* dwarf2out.c (next_block_number): Remove.
(gen_lexical_block_die): Use BLOCK_NUMBER, not next_block_number,
to determine block numbers.
(gen_inlined_subroutine_die): Likewise.
(gen_block_die): Only output blocks that have TREE_ASM_WRITTEN set.
(decls_for_scope): Don't increment next_block_number.
* dwarfout.c (next_block_number): Remove.
(output_lexical_block_die): Use BLOCK_NUMBER, not next_block_number,
to determine block numbers.
(output_inlined_subroutine_die): Likewise.
(output_block): Only output blocks that have TREE_ASM_WRITTEN set.
(output_decls_for_scope): Don't increment next_block_number.
* sdbout.c (next_block_number): Remove.
(sdbout_block): Use BLOCK_NUMBER.
(sdbout_begin_block): Simplify.
* xcoffout.c (next_block_number): Remove.
(xcoffout_block): Use BLOCK_NUMBER, not next_block_number.
(xcoffout_begin_block): Don't set next_block_number.
(xcoffout_begin_function): Likewise. Use BLOCK_NUMBER, not
next_block_number.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32228 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/dbxout.c
gcc/dwarf2out.c
gcc/dwarfout.c
gcc/emit-rtl.c
gcc/final.c
gcc/function.c
gcc/function.h
gcc/sdbout.c
gcc/toplev.c
gcc/tree.def
gcc/tree.h
gcc/xcoffout.c

index 0059eb0..d777804 100644 (file)
@@ -1,3 +1,50 @@
+2000-02-27  Mark Mitchell  <mark@codesourcery.com>
+
+       * emit-rtl.c (remove_unncessary_notes): Remove notes for empty
+       blocks.
+       * final.c (next_block_index): Remove.
+       (max_block_depth): Likewise.
+       (pending_blocks): Likewise.
+       (init_final): Don't initialize them.
+       (final_start_function): Don't set next_block_index.  Set up
+       BLOCK_NUMBER.
+       (final_scan_insn): Use BLOCK_NUMBER, not next_block_index.
+       * function.h (number_blocks): New function.
+       * function.c (get_block_vector): New function.
+       (identify_blocks): Use it.
+       (reorder_blocks): Set NOTE_BLOCK.
+       (number_blocks): New function.
+       * tree.def (BLOCK): Add documentation for TREE_ASM_WRITTEN flag.
+       * tree.h (BLOCK_NUMBER): New macro.
+       (tree_block): Add block_num field.
+       * dbxout.c (next_block_number): Remove.
+       (dbxout_init): Don't set it.
+       (dbxout_block): Only output blocks that have TREE_ASM_WRITTEN
+       set.  Use BLOCK_NUMBER, rather than next_block_num, to determine
+       block numbers.
+       * toplev.c (rest_of_compilation): Always call
+       find_loop_tree_blocks.  Fix indentation.
+       * dwarf2out.c (next_block_number): Remove.
+       (gen_lexical_block_die): Use BLOCK_NUMBER, not next_block_number,
+       to determine block numbers.
+       (gen_inlined_subroutine_die): Likewise.
+       (gen_block_die): Only output blocks that have TREE_ASM_WRITTEN set.
+       (decls_for_scope): Don't increment next_block_number.
+       * dwarfout.c (next_block_number): Remove.
+       (output_lexical_block_die): Use BLOCK_NUMBER, not next_block_number,
+       to determine block numbers. 
+       (output_inlined_subroutine_die): Likewise.
+       (output_block): Only output blocks that have TREE_ASM_WRITTEN set.
+       (output_decls_for_scope): Don't increment next_block_number.
+       * sdbout.c (next_block_number): Remove.
+       (sdbout_block): Use BLOCK_NUMBER.
+       (sdbout_begin_block): Simplify.
+       * xcoffout.c (next_block_number): Remove.
+       (xcoffout_block): Use BLOCK_NUMBER, not next_block_number.
+       (xcoffout_begin_block): Don't set next_block_number.
+       (xcoffout_begin_function): Likewise. Use BLOCK_NUMBER, not
+       next_block_number.
+       
 Sun Feb 27 16:40:33 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * builtins.c (c_strlen): Use size_diffop and return ssizetype value.
index 7db2070..c09b318 100644 (file)
@@ -273,16 +273,6 @@ static int next_file_number;
 
 #endif /* DBX_USE_BINCL */
 
-/* In dbx output, we must assign symbol-blocks id numbers
-   in the order in which their beginnings are encountered.
-   We output debugging info that refers to the beginning and
-   end of the ranges of code in each block
-   with assembler labels LBBn and LBEn, where n is the block number.
-   The labels are generated in final, which assigns numbers to the
-   blocks in the same way.  */
-
-static int next_block_number;
-
 /* These variables are for dbxout_symbol to communicate to
    dbxout_finish_symbol.
    current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.
@@ -437,7 +427,6 @@ dbxout_init (asm_file, input_file_name, syms)
   lastfile = input_file_name;
 
   next_type_number = 1;
-  next_block_number = 2;
 
 #ifdef DBX_USE_BINCL
   current_file = (struct dbx_file *) xmalloc (sizeof *current_file);
@@ -2630,7 +2619,7 @@ dbxout_block (block, depth, args)
   while (block)
     {
       /* Ignore blocks never expanded or otherwise marked as real.  */
-      if (TREE_USED (block))
+      if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
        {
 #ifndef DBX_LBRAC_FIRST
          /* In dbx format, the syms of a block come before the N_LBRAC.  */
@@ -2647,7 +2636,7 @@ dbxout_block (block, depth, args)
          if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE)
            {
              char buf[20];
-             blocknum = next_block_number++;
+             blocknum = BLOCK_NUMBER (block);
              ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
 
              if (BLOCK_HANDLER_BLOCK (block))
@@ -2680,9 +2669,6 @@ dbxout_block (block, depth, args)
              fprintf (asmfile, "\n");
 #endif
            }
-         else if (depth > 0)
-           /* Count blocks the same way regardless of debug_info_level.  */
-           next_block_number++;
 
 #ifdef DBX_LBRAC_FIRST
          /* On some weird machines, the syms of a block
index 6181cfb..aa1600a 100644 (file)
@@ -2202,13 +2202,6 @@ static unsigned file_table_in_use;
    dwarf2out_init.  */
 static char *primary_filename;
 
-/* For Dwarf output, we must assign lexical-blocks id numbers in the order in
-   which their beginnings are encountered. We output Dwarf debugging info
-   that refers to the beginnings and ends of the ranges of code for each
-   lexical block.  The labels themselves are generated in final.c, which
-   assigns numbers to the blocks in the same way.  */
-static unsigned next_block_number = 2;
-
 /* A pointer to the base of a table of references to DIE's that describe
    declarations.  The table is indexed by DECL_UID() which is a unique
    number identifying each decl.  */
@@ -8534,9 +8527,10 @@ gen_lexical_block_die (stmt, context_die, depth)
   if (! BLOCK_ABSTRACT (stmt))
     {
       ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
-                                  next_block_number);
+                                  BLOCK_NUMBER (stmt));
       add_AT_lbl_id (stmt_die, DW_AT_low_pc, label);
-      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, next_block_number);
+      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
+                                  BLOCK_NUMBER (stmt));
       add_AT_lbl_id (stmt_die, DW_AT_high_pc, label);
     }
 
@@ -8563,9 +8557,10 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
 
       add_abstract_origin_attribute (subr_die, decl);
       ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
-                                  next_block_number);
+                                  BLOCK_NUMBER (stmt));
       add_AT_lbl_id (subr_die, DW_AT_low_pc, label);
-      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL, next_block_number);
+      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
+                                  BLOCK_NUMBER (stmt));
       add_AT_lbl_id (subr_die, DW_AT_high_pc, label);
       decls_for_scope (stmt, subr_die, depth);
       current_function_has_inlines = 1;
@@ -9154,7 +9149,7 @@ gen_block_die (stmt, context_die, depth)
 
   /* Ignore blocks never really used to make RTL.  */
 
-  if (stmt == NULL_TREE || !TREE_USED (stmt))
+  if (stmt == NULL_TREE || !TREE_USED (stmt) || !TREE_ASM_WRITTEN (stmt))
     return;
 
   /* Determine the "ultimate origin" of this block.  This block may be an
@@ -9237,9 +9232,6 @@ decls_for_scope (stmt, context_die, depth)
   if (stmt == NULL_TREE || ! TREE_USED (stmt))
     return;
 
-  if (!BLOCK_ABSTRACT (stmt) && depth > 0)
-    next_block_number++;
-
   /* Output the DIEs to represent all of the data objects and typedefs
      declared directly within this block but not within any nested
      sub-blocks.  Also, nested function and tag DIEs have been
index ab7fef0..08dc41c 100644 (file)
@@ -195,16 +195,6 @@ static char *primary_filename;
 
 static char *last_filename;
 
-/* For Dwarf output, we must assign lexical-blocks id numbers
-   in the order in which their beginnings are encountered.
-   We output Dwarf debugging info that refers to the beginnings
-   and ends of the ranges of code for each lexical block with
-   assembler labels ..Bn and ..Bn.e, where n is the block number.
-   The labels themselves are generated in final.c, which assigns
-   numbers to the blocks in the same way.  */
-
-static unsigned next_block_number = 2;
-
 /* Counter to generate unique names for DIEs.  */
 
 static unsigned next_unused_dienum = 1;
@@ -3601,9 +3591,9 @@ output_lexical_block_die (arg)
       char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
       char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
 
-      sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number);
+      sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, BLOCK_NUMBER (stmt));
       low_pc_attribute (begin_label);
-      sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number);
+      sprintf (end_label, BLOCK_END_LABEL_FMT, BLOCK_NUMBER (stmt));
       high_pc_attribute (end_label);
     }
 }
@@ -3623,9 +3613,9 @@ output_inlined_subroutine_die (arg)
       char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
       char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
 
-      sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number);
+      sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, BLOCK_NUMBER (stmt));
       low_pc_attribute (begin_label);
-      sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number);
+      sprintf (end_label, BLOCK_END_LABEL_FMT, BLOCK_NUMBER (stmt));
       high_pc_attribute (end_label);
     }
 }
@@ -4633,7 +4623,7 @@ output_block (stmt, depth)
 
   /* Ignore blocks never really used to make RTL.  */
 
-  if (! stmt || ! TREE_USED (stmt))
+  if (! stmt || ! TREE_USED (stmt) || !TREE_ASM_WRITTEN (stmt))
     return;
 
   /* Determine the "ultimate origin" of this block.  This block may be an
@@ -4725,9 +4715,6 @@ output_decls_for_scope (stmt, depth)
   if (! stmt || ! TREE_USED (stmt))
     return;
 
-  if (! BLOCK_ABSTRACT (stmt) && depth > 0)
-    next_block_number++;
-
   /* Output the DIEs to represent all of the data objects, functions,
      typedefs, and tagged types declared directly within this block
      but not within any nested sub-blocks.  */
index d6f736e..c6e5cb1 100644 (file)
@@ -2681,6 +2681,48 @@ remove_unncessary_notes ()
 
       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
        remove_insn (insn);
+      else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
+       {
+         /* Scan back to see if there are any non-note instructions
+            between INSN and the beginning of this block.  If not,
+            then there is no PC range in the generated code that will
+            actually be in this block, so there's no point in
+            remembering the existence of the block.  */
+         rtx prev;
+
+         for (prev = PREV_INSN (insn); prev; prev = PREV_INSN (prev))
+           {
+             /* This block contains a real instruction.  Note that we
+                don't include labels; if the only thing in the block
+                is a label, then there are still no PC values that
+                lie within the block.  */
+             if (GET_RTX_CLASS (GET_CODE (prev)) == 'i')
+               break;
+
+             /* We're only interested in NOTEs.  */
+             if (GET_CODE (prev) != NOTE)
+               continue;
+
+             if (NOTE_LINE_NUMBER (prev) == NOTE_INSN_BLOCK_BEG)
+               {
+                 /* If the BLOCKs referred to by these notes don't
+                    match, then something is wrong with our BLOCK
+                    nesting structure.  */
+                 if (NOTE_BLOCK (prev) != NOTE_BLOCK (insn))
+                   abort ();
+                 
+                 remove_insn (prev);
+                 remove_insn (insn);
+                 break;
+               }
+             else if (NOTE_LINE_NUMBER (prev) == NOTE_INSN_BLOCK_END)
+               /* There's a nested block.  We need to leave the
+                  current block in place since otherwise the debugger
+                  wouldn't be able to show symbols from our block in
+                  the nested block.  */
+               break;
+           }
+       }
     }
 }
 
index fc18f3c..1346b37 100644 (file)
@@ -174,22 +174,6 @@ static rtx last_ignored_compare = 0;
 
 static int new_block = 1;
 
-/* All the symbol-blocks (levels of scoping) in the compilation
-   are assigned sequence numbers in order of appearance of the
-   beginnings of the symbol-blocks.  Both final and dbxout do this,
-   and assume that they will both give the same number to each block.
-   Final uses these sequence numbers to generate assembler label names
-   LBBnnn and LBEnnn for the beginning and end of the symbol-block.
-   Dbxout uses the sequence numbers to generate references to the same labels
-   from the dbx debugging information.
-
-   Sdb records this level at the beginning of each function,
-   in order to find the current level when recursing down declarations.
-   It outputs the block beginning and endings
-   at the point in the asm file where the blocks would begin and end.  */
-
-int next_block_index;
-
 /* Assign a unique number to each insn that is output.
    This can be used to generate unique local labels.  */
 
@@ -229,18 +213,7 @@ int frame_pointer_needed;
 
 int profile_label_no;
 
-/* Length so far allocated in PENDING_BLOCKS.  */
-
-static int max_block_depth;
-
-/* Stack of sequence numbers of symbol-blocks of which we have seen the
-   beginning but not yet the end.  Sequence numbers are assigned at
-   the beginning; this stack allows us to find the sequence number
-   of a block that is ending.  */
-
-static int *pending_blocks;
-
-/* Number of elements currently in use in PENDING_BLOCKS.  */
+/* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen.  */
 
 static int block_depth;
 
@@ -320,10 +293,7 @@ void
 init_final (filename)
      const char *filename ATTRIBUTE_UNUSED;
 {
-  next_block_index = 2;
   app_on = 0;
-  max_block_depth = 20;
-  pending_blocks = (int *) xmalloc (20 * sizeof *pending_blocks);
   final_sequence = 0;
 
 #ifdef ASSEMBLER_DIALECT
@@ -1667,16 +1637,23 @@ final_start_function (first, file, optimize)
     dwarf2out_frame_debug (NULL_RTX);
 #endif
 
+  /* If debugging, assign block numbers to all of the blocks in this
+     function.  */
+  if (write_symbols)
+    {
+      number_blocks (current_function_decl);
+      remove_unncessary_notes ();
+      /* We never actually put out begin/end notes for the top-level
+        block in the function.  But, conceptually, that block is
+        always needed.  */
+      TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
+    }
+
 #ifdef FUNCTION_PROLOGUE
   /* First output the function prologue: code to set up the stack frame.  */
   FUNCTION_PROLOGUE (file, get_frame_size ());
 #endif
 
-#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-  if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
-    next_block_index = 1;
-#endif
-
   /* If the machine represents the prologue as RTL, the profiling code must
      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
 #ifdef HAVE_prologue
@@ -2174,45 +2151,35 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
              || write_symbols == DWARF_DEBUG
              || write_symbols == DWARF2_DEBUG))
        {
-         /* Beginning of a symbol-block.  Assign it a sequence number
-            and push the number onto the stack PENDING_BLOCKS.  */
-
-         if (block_depth == max_block_depth)
-           {
-             /* PENDING_BLOCKS is full; make it longer.  */
-             max_block_depth *= 2;
-             pending_blocks
-               = (int *) xrealloc (pending_blocks,
-                                   max_block_depth * sizeof (int));
-           }
-         pending_blocks[block_depth++] = next_block_index;
+         int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
 
+         ++block_depth;
          high_block_linenum = last_linenum;
 
          /* Output debugging info about the symbol-block beginning.  */
-
 #ifdef SDB_DEBUGGING_INFO
          if (write_symbols == SDB_DEBUG)
-           sdbout_begin_block (file, last_linenum, next_block_index);
+           sdbout_begin_block (file, last_linenum, n);
 #endif
 #ifdef XCOFF_DEBUGGING_INFO
          if (write_symbols == XCOFF_DEBUG)
-           xcoffout_begin_block (file, last_linenum, next_block_index);
+           xcoffout_begin_block (file, last_linenum, n);
 #endif
 #ifdef DBX_DEBUGGING_INFO
          if (write_symbols == DBX_DEBUG)
-           ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", next_block_index);
+           ASM_OUTPUT_INTERNAL_LABEL (file, "LBB", n);
 #endif
 #ifdef DWARF_DEBUGGING_INFO
          if (write_symbols == DWARF_DEBUG)
-           dwarfout_begin_block (next_block_index);
+           dwarfout_begin_block (n);
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
          if (write_symbols == DWARF2_DEBUG)
-           dwarf2out_begin_block (next_block_index);
+           dwarf2out_begin_block (n);
 #endif
 
-         next_block_index++;
+         /* Mark this block as output.  */
+         TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
        }
       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END
               && (debug_info_level == DINFO_LEVEL_NORMAL
@@ -2220,8 +2187,9 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                   || write_symbols == DWARF_DEBUG
                   || write_symbols == DWARF2_DEBUG))
        {
-         /* End of a symbol-block.  Pop its sequence number off
-            PENDING_BLOCKS and output debugging info based on that.  */
+         int n = BLOCK_NUMBER (NOTE_BLOCK (insn));
+
+         /* End of a symbol-block.  */
 
          --block_depth;
          if (block_depth < 0)
@@ -2229,26 +2197,23 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
 #ifdef XCOFF_DEBUGGING_INFO
          if (write_symbols == XCOFF_DEBUG)
-           xcoffout_end_block (file, high_block_linenum,
-                               pending_blocks[block_depth]);
+           xcoffout_end_block (file, high_block_linenum, n);
 #endif
 #ifdef DBX_DEBUGGING_INFO
          if (write_symbols == DBX_DEBUG)
-           ASM_OUTPUT_INTERNAL_LABEL (file, "LBE",
-                                      pending_blocks[block_depth]);
+           ASM_OUTPUT_INTERNAL_LABEL (file, "LBE", n);
 #endif
 #ifdef SDB_DEBUGGING_INFO
          if (write_symbols == SDB_DEBUG)
-           sdbout_end_block (file, high_block_linenum,
-                             pending_blocks[block_depth]);
+           sdbout_end_block (file, high_block_linenum, n);
 #endif
 #ifdef DWARF_DEBUGGING_INFO
          if (write_symbols == DWARF_DEBUG)
-           dwarfout_end_block (pending_blocks[block_depth]);
+           dwarfout_end_block (n);
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
          if (write_symbols == DWARF2_DEBUG)
-           dwarf2out_end_block (pending_blocks[block_depth]);
+           dwarf2out_end_block (n);
 #endif
        }
       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL
index dae6996..ce5fef2 100644 (file)
@@ -268,6 +268,7 @@ static tree round_down              PARAMS ((tree, int));
 static rtx round_trampoline_addr PARAMS ((rtx));
 static tree blocks_nreverse    PARAMS ((tree));
 static int all_blocks          PARAMS ((tree, tree *));
+static tree *get_block_vector   PARAMS ((tree, int *));
 /* We always define `record_insns' even if its not used so that we
    can always export `prologue_epilogue_contains'.  */
 static int *record_insns       PARAMS ((rtx)) ATTRIBUTE_UNUSED;
@@ -5489,10 +5490,7 @@ identify_blocks (block, insns)
 
   /* Fill the BLOCK_VECTOR with all of the BLOCKs in this function, in
      depth-first order.  */
-  n_blocks = all_blocks (block, 0);
-  block_vector = (tree *) xmalloc (n_blocks * sizeof (tree));
-  all_blocks (block, block_vector);
-
+  block_vector = get_block_vector (block, &n_blocks);
   block_stack = (tree *) xmalloc (n_blocks * sizeof (tree));
 
   for (insn = insns; insn; insn = NEXT_INSN (insn))
@@ -5522,12 +5520,6 @@ identify_blocks (block, insns)
          }
       }
 
-  /* In whole-function mode, we might not have seen the whole function
-     yet, so we might not use up all the blocks.  */
-  if (n_blocks != current_block_number 
-      && !cfun->x_whole_function_mode_p)
-    abort ();
-
   free (block_vector);
   free (block_stack);
 }
@@ -5544,10 +5536,13 @@ reorder_blocks (block, insns)
 {
   tree current_block = block;
   rtx insn;
+  varray_type block_stack;
 
   if (block == NULL_TREE)
     return NULL_TREE;
 
+  VARRAY_TREE_INIT (block_stack, 10, "block_stack");
+
   /* Prune the old trees away, so that it doesn't get in the way.  */
   BLOCK_SUBBLOCKS (current_block) = 0;
   BLOCK_CHAIN (current_block) = 0;
@@ -5560,16 +5555,22 @@ reorder_blocks (block, insns)
            tree block = NOTE_BLOCK (insn);
            /* If we have seen this block before, copy it.  */
            if (TREE_ASM_WRITTEN (block))
-             block = copy_node (block);
+             {
+               block = copy_node (block);
+               NOTE_BLOCK (insn) = block;
+             }
            BLOCK_SUBBLOCKS (block) = 0;
            TREE_ASM_WRITTEN (block) = 1;
            BLOCK_SUPERCONTEXT (block) = current_block; 
            BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
            BLOCK_SUBBLOCKS (current_block) = block;
            current_block = block;
+           VARRAY_PUSH_TREE (block_stack, block);
          }
-       if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
+       else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
          {
+           NOTE_BLOCK (insn) = VARRAY_TOP_TREE (block_stack);
+           VARRAY_POP (block_stack);
            BLOCK_SUBBLOCKS (current_block)
              = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
            current_block = BLOCK_SUPERCONTEXT (current_block);
@@ -5578,6 +5579,9 @@ reorder_blocks (block, insns)
 
   BLOCK_SUBBLOCKS (current_block)
     = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
+
+  VARRAY_FREE (block_stack);
+
   return current_block;
 }
 
@@ -5598,8 +5602,9 @@ blocks_nreverse (t)
   return prev;
 }
 
-/* Count the subblocks of the list starting with BLOCK, and list them
-   all into the vector VECTOR.  Also clear TREE_ASM_WRITTEN in all
+/* Count the subblocks of the list starting with BLOCK.  If VECTOR is
+   non-NULL, list them all into VECTOR, in a depth-first preorder
+   traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
    blocks.  */
 
 static int
@@ -5627,6 +5632,57 @@ all_blocks (block, vector)
 
   return n_blocks;
 }
+
+/* Return a vector containing all the blocks rooted at BLOCK.  The
+   number of elements in the vector is stored in N_BLOCKS_P.  The
+   vector is dynamically allocated; it is the caller's responsibility
+   to call `free' on the pointer returned.  */
+  
+static tree *
+get_block_vector (block, n_blocks_p)
+     tree block;
+     int *n_blocks_p;
+{
+  tree *block_vector;
+
+  *n_blocks_p = all_blocks (block, NULL);
+  block_vector = (tree *) xmalloc (*n_blocks_p * sizeof (tree));
+  all_blocks (block, block_vector);
+
+  return block_vector;
+}
+
+static int next_block_index = 2;
+
+/* Set BLOCK_NUMBER for all the blocks in FN.  */
+
+void
+number_blocks (fn)
+     tree fn;
+{
+  int i;
+  int n_blocks;
+  tree *block_vector;
+
+  /* For SDB and XCOFF debugging output, we start numbering the blocks
+     from 1 within each function, rather than keeping a running
+     count.  */
+#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
+  next_block_index = 1;
+#endif
+
+  block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks);
+
+  /* The top-level BLOCK isn't numbered at all.  */
+  for (i = 1; i < n_blocks; ++i)
+    /* We number the blocks from two.  */
+    BLOCK_NUMBER (block_vector[i]) = next_block_index++;
+
+  free (block_vector);
+
+  return;
+}
+
 \f
 /* Allocate a function structure and reset its contents to the defaults.  */
 static void
index 7d258b1..fb3ef49 100644 (file)
@@ -548,6 +548,9 @@ extern struct function *outer_function_chain;
    the index of that block in the vector.  */
 extern void identify_blocks PARAMS ((tree, rtx));
 
+/* Set BLOCK_NUMBER for all the blocks in FN.  */
+extern void number_blocks PARAMS ((tree));
+
 /* Return size needed for stack frame based on slots so far allocated.
    This size counts from zero.  It is not rounded to STACK_BOUNDARY;
    the caller may have to do that.  */
index de16c0f..5f6b01b 100644 (file)
@@ -679,15 +679,12 @@ plain_type_1 (type, level)
 }
 \f
 /* Output the symbols defined in block number DO_BLOCK.
-   Set NEXT_BLOCK_NUMBER to 0 before calling.
 
    This function works by walking the tree structure of blocks,
    counting blocks until it finds the desired block.  */
 
 static int do_block = 0;
 
-static int next_block_number;
-
 static void
 sdbout_block (block)
      register tree block;
@@ -698,17 +695,13 @@ sdbout_block (block)
       if (TREE_USED (block))
        {
          /* When we reach the specified block, output its symbols.  */
-         if (next_block_number == do_block)
-           {
-             sdbout_syms (BLOCK_VARS (block));
-           }
+         if (BLOCK_NUMBER (block) == do_block)
+           sdbout_syms (BLOCK_VARS (block));
 
          /* If we are past the specified block, stop the scan.  */
-         if (next_block_number > do_block)
+         if (BLOCK_NUMBER (block) > do_block)
            return;
 
-         next_block_number++;
-
          /* Scan the blocks within this block.  */
          sdbout_block (BLOCK_SUBBLOCKS (block));
        }
@@ -1546,15 +1539,13 @@ sdbout_begin_block (file, line, n)
   if (n == 1)
     {
       /* Include the outermost BLOCK's variables in block 1.  */
-      next_block_number = 0;
-      do_block = 0;
+      do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
       sdbout_block (DECL_INITIAL (decl));
     }
   /* If -g1, suppress all the internal symbols of functions
      except for arguments.  */
   if (debug_info_level != DINFO_LEVEL_TERSE)
     {
-      next_block_number = 0;
       do_block = n;
       sdbout_block (DECL_INITIAL (decl));
     }
index e25fbcd..c8319f8 100644 (file)
@@ -2842,13 +2842,13 @@ rest_of_compilation (decl)
      collector to reclaim the memory used by the notes.  */
   remove_unncessary_notes ();
 
+  /* We need to make sure that NOTE_BLOCK is set correctly
+     for each NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
+  find_loop_tree_blocks ();
   /* In function-at-a-time mode, we do not attempt to keep the BLOCK
      tree in sensible shape.  So, we just recalculate it here.  */
   if (cfun->x_whole_function_mode_p)
-    {
-      find_loop_tree_blocks ();
-      unroll_block_trees ();
-    }
+    unroll_block_trees ();
 
   /* If we are reconsidering an inline function
      at the end of compilation, skip the stuff for making it inline.  */
@@ -3705,8 +3705,8 @@ rest_of_compilation (decl)
             regset_release_memory ();
           });
 
-   if (ggc_p)
-     ggc_collect ();
+  if (ggc_p)
+    ggc_collect ();
 
   /* Write DBX symbols if requested */
 
index eadf1f5..551d5cb 100644 (file)
@@ -1,6 +1,6 @@
 /* This file contains the definitions and documentation for the
    tree codes used in the GNU C compiler.
-   Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -82,7 +82,9 @@ DEFTREECODE (TREE_VEC, "tree_vec", 'x', 2)
    outermost scope of a particular inlining of a function).
    BLOCK_ABSTRACT is non-zero if the block represents an abstract
    instance of a block (i.e. one which is nested within an abstract
-   instance of an inline function). */
+   instance of an inline function). 
+   TREE_ASM_WRITTEN is non-zero if the block was actually referenced
+   in the generated assembly.  */
 DEFTREECODE (BLOCK, "block", 'b', 0)
 \f
 /* Each data type is represented by a tree node whose code is one of
index 27737dc..c472e30 100644 (file)
@@ -797,12 +797,18 @@ struct tree_exp
    listed in the BLOCK_VARS slot.  */
 #define BLOCK_HANDLER_BLOCK(NODE) (BLOCK_CHECK (NODE)->block.handler_block_flag)
 
+/* An index number for this block.  These values are not guaranteed to
+   be unique across functions -- whether or not they are depends on
+   the debugging output format in use.  */
+#define BLOCK_NUMBER(NODE) (BLOCK_CHECK (NODE)->block.block_num)
+
 struct tree_block
 {
   char common[sizeof (struct tree_common)];
 
   unsigned handler_block_flag : 1;
   unsigned abstract_flag : 1;
+  unsigned block_num : 30;
 
   union tree_node *vars;
   union tree_node *subblocks;
index eec7786..2857af4 100644 (file)
@@ -375,15 +375,12 @@ xcoffout_source_line (file, filename, note)
 }
 \f
 /* Output the symbols defined in block number DO_BLOCK.
-   Set NEXT_BLOCK_NUMBER to 0 before calling.
 
    This function works by walking the tree structure of blocks,
    counting blocks until it finds the desired block.  */
 
 static int do_block = 0;
 
-static int next_block_number;
-
 static void
 xcoffout_block (block, depth, args)
      register tree block;
@@ -396,7 +393,7 @@ xcoffout_block (block, depth, args)
       if (TREE_USED (block))
        {
          /* When we reach the specified block, output its symbols.  */
-         if (next_block_number == do_block)
+         if (BLOCK_NUMBER (block) == do_block)
            {
              /* Output the syms of the block.  */
              if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
@@ -408,11 +405,9 @@ xcoffout_block (block, depth, args)
              return;
            }
          /* If we are past the specified block, stop the scan.  */
-         else if (next_block_number >= do_block)
+         else if (BLOCK_NUMBER (block) >= do_block)
            return;
 
-         next_block_number++;
-
          /* Output the subblocks.  */
          xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
        }
@@ -443,7 +438,6 @@ xcoffout_begin_block (file, line, n)
     ASM_OUTPUT_LBB (file, line, n);
 
   do_block = n;
-  next_block_number = 0;
   xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
 }
 
@@ -513,8 +507,7 @@ xcoffout_begin_function (file, last_linenum)
      in sdbout_begin_block, but there is no guarantee that there will be any
      inner block 1, so we must do it here.  This gives a result similar to
      dbxout, so it does make some sense.  */
-  do_block = 0;
-  next_block_number = 0;
+  do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
   xcoffout_block (DECL_INITIAL (current_function_decl), 0,
                  DECL_ARGUMENTS (current_function_decl));