This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to block removal optimization
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to block removal optimization
- From: Jason Merrill <jason at cygnus dot com>
- Date: Fri, 3 Mar 2000 16:42:22 -0800
We were crashing left and right on the g++ testsuite with -g -O2,
because we were faced with orphaned local classes; the same problem
occurred with nested functions in C. This patch fixes things so that:
1) We don't consider a local class from a deleted block to be an orphan.
2) We set NOTE_BLOCK before referring to it.
3) We don't try to remove blocks in final if we've done insn
scheduling, since that moves block notes around arbitrarily;
otherwise, we end up throwing away information for code that wasn't
deleted at all. Perhaps we should fix the scheduler so that block
notes are preserved better...
2000-03-03 Jason Merrill <jason@casey.cygnus.com>
* toplev.c (rest_of_compilation): find_loop_tree_blocks before
remove_unnecessary_notes.
(debug_ignore_block): New fn.
* toplev.h: Declare it.
* emit-rtl.c (remove_unncessary_notes): Call it.
* dwarf2out.c (dwarf2out_ignore_block): New fn.
* dwarf2out.h: Declare it.
* final.c (final_start_function): Don't call remove_unnecessary_notes
if we did insn scheduling.
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.155
diff -c -p -r1.155 dwarf2out.c
*** dwarf2out.c 2000/02/29 23:33:48 1.155
--- dwarf2out.c 2000/03/03 23:55:50
*************** dwarf2out_end_block (blocknum)
*** 9592,9597 ****
--- 9576,9608 ----
{
function_section (current_function_decl);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
+ }
+
+ /* We've decided not to emit any debugging information for BLOCK; make
+ sure that we don't end up with orphans as a result. */
+
+ void
+ dwarf2out_ignore_block (block)
+ tree block;
+ {
+ tree decl;
+ for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
+ {
+ dw_die_ref die;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ die = lookup_decl_die (decl);
+ else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
+ die = lookup_type_die (TREE_TYPE (decl));
+ else
+ die = NULL;
+
+ /* Just give them a dummy value for parent so dwarf2out_finish
+ doesn't blow up; we would use add_child_die if we really
+ wanted to add them to comp_unit_die's children. */
+ if (die && die->die_parent == 0)
+ die->die_parent = comp_unit_die;
+ }
}
/* Output a marker (i.e. a label) at a point in the assembly code which
Index: dwarf2out.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.h,v
retrieving revision 1.6
diff -c -p -r1.6 dwarf2out.h
*** dwarf2out.h 2000/02/06 03:40:45 1.6
--- dwarf2out.h 2000/03/03 23:55:50
*************** dwarf2out.h P
*** 29,34 ****
--- 29,35 ----
extern void dwarf2out_begin_block PARAMS ((unsigned));
extern void dwarf2out_end_block PARAMS ((unsigned));
+ extern void dwarf2out_ignore_block PARAMS ((tree));
extern void dwarf2out_label PARAMS ((rtx));
extern void dwarf2out_decl PARAMS ((tree));
extern void dwarf2out_line PARAMS ((const char *, unsigned));
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.111
diff -c -p -r1.111 emit-rtl.c
*** emit-rtl.c 2000/02/28 09:51:40 1.111
--- emit-rtl.c 2000/03/03 23:55:58
*************** remove_unncessary_notes ()
*** 2710,2715 ****
--- 2710,2717 ----
nesting structure. */
if (NOTE_BLOCK (prev) != NOTE_BLOCK (insn))
abort ();
+
+ debug_ignore_block (NOTE_BLOCK (insn));
remove_insn (prev);
remove_insn (insn);
Index: final.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/final.c,v
retrieving revision 1.114
diff -c -p -r1.114 final.c
*** final.c 2000/02/29 23:33:48 1.114
--- final.c 2000/03/03 23:56:00
*************** final_start_function (first, file, optim
*** 1644,1650 ****
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. */
--- 1644,1653 ----
if (write_symbols)
{
number_blocks (current_function_decl);
! /* Scheduling packs block notes together at the top of a basic block,
! so we can't learn anything from them. */
! if (! flag_schedule_insns && ! flag_schedule_insns_after_reload)
! 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. */
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.297
diff -c -p -r1.297 toplev.c
*** toplev.c 2000/02/29 23:33:48 1.297
--- toplev.c 2000/03/03 23:56:10
*************** rest_of_compilation (decl)
*** 2845,2858 ****
have been run to re-initialize it. */
cse_not_expected = ! optimize;
! /* First, remove any notes we don't need. That will make iterating
over the instruction sequence faster, and allow the garbage
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)
--- 2845,2859 ----
have been run to re-initialize it. */
cse_not_expected = ! optimize;
! /* First, make sure that NOTE_BLOCK is set correctly for each
! NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
! find_loop_tree_blocks ();
!
! /* Then remove any notes we don't need. That will make iterating
over the instruction sequence faster, and allow the garbage
collector to reclaim the memory used by the notes. */
remove_unncessary_notes ();
/* 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)
*************** debug_undef (lineno, buffer)
*** 5159,5162 ****
--- 5158,5175 ----
&& write_symbols == DWARF2_DEBUG)
dwarf2out_undef (lineno, buffer);
#endif /* DWARF2_DEBUGGING_INFO */
+ }
+
+ /* Tell the debugging backend that we've decided not to emit any
+ debugging information for BLOCK, so it can clean up after any local
+ classes or nested functions. */
+
+ void
+ debug_ignore_block (block)
+ tree block;
+ {
+ #ifdef DWARF2_DEBUGGING_INFO
+ if (write_symbols == DWARF2_DEBUG)
+ dwarf2out_ignore_block (block);
+ #endif
}
Index: toplev.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.h,v
retrieving revision 1.33
diff -c -p -r1.33 toplev.h
*** toplev.h 2000/02/06 03:40:46 1.33
--- toplev.h 2000/03/03 23:56:10
*************** toplev.h PARA
*** 35,40 ****
--- 35,41 ----
extern void debug_end_source_file PARAMS ((unsigned));
extern void debug_define PARAMS ((unsigned, char *));
extern void debug_undef PARAMS ((unsigned, char *));
+ extern void debug_ignore_block PARAMS ((union tree_node *));
extern void fatal PARAMS ((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
extern void fatal_io_error PARAMS ((const char *))