summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog47
-rw-r--r--gcc/dbxout.c18
-rw-r--r--gcc/dwarf2out.c22
-rw-r--r--gcc/dwarfout.c23
-rw-r--r--gcc/emit-rtl.c42
-rw-r--r--gcc/final.c95
-rw-r--r--gcc/function.c84
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/sdbout.c17
-rw-r--r--gcc/toplev.c12
-rw-r--r--gcc/tree.def6
-rw-r--r--gcc/tree.h6
-rw-r--r--gcc/xcoffout.c13
13 files changed, 229 insertions, 159 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0059eb0e895..d77780484d0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 7db2070fcd5..c09b31835df 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6181cfb7ce2..aa1600aa7b1 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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
diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c
index ab7fef006d1..08dc41cfdb7 100644
--- a/gcc/dwarfout.c
+++ b/gcc/dwarfout.c
@@ -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. */
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index d6f736e707b..c6e5cb1b7d2 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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;
+ }
+ }
}
}
diff --git a/gcc/final.c b/gcc/final.c
index fc18f3c3971..1346b37675f 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -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
diff --git a/gcc/function.c b/gcc/function.c
index dae6996f8ac..ce5fef21e29 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
+}
+
/* Allocate a function structure and reset its contents to the defaults. */
static void
diff --git a/gcc/function.h b/gcc/function.h
index 7d258b112f3..fb3ef497563 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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. */
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index de16c0f0939..5f6b01b22a9 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -679,15 +679,12 @@ plain_type_1 (type, level)
}
/* 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));
}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e25fbcdd1a0..c8319f8d9b3 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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 */
diff --git a/gcc/tree.def b/gcc/tree.def
index eadf1f50d67..551d5cb1758 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -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)
/* Each data type is represented by a tree node whose code is one of
diff --git a/gcc/tree.h b/gcc/tree.h
index 27737dcc123..c472e307685 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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;
diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c
index eec778610ff..2857af4f492 100644
--- a/gcc/xcoffout.c
+++ b/gcc/xcoffout.c
@@ -375,15 +375,12 @@ xcoffout_source_line (file, filename, note)
}
/* 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));