flow tweeks
Richard Henderson
rth@cygnus.com
Wed Mar 31 12:46:00 GMT 1999
There was a comment I'd left in find_basic_blocks,
/* ??? Do this conditionally, or make this another entry point? */
delete_unreachable_blocks ();
Well, one of the optimization bits in Cygnus' internal tree
fell over on this. So here's me putting in a bit to actually
make it conditional.
Long-term I'd like to never recalculate basic blocks. They're
too easy to just keep up to date all the time.
r~
Wed Mar 31 12:32:43 1999 Richard Henderson <rth@cygnus.com>
* flow.c (find_basic_blocks): New argument `do_cleanup'.
Conditionally call delete_unreachable_blocks.
(free_basic_block_vars): Zero ENTRY/EXIT data.
(allocate_for_life_analysis): Kill. Split into...
(allocate_bb_life_data, allocate_reg_life_data): ... new functions.
(life_analysis_1): Update.
* gcse.c (gcse_main): Update find_basic_blocks call.
* toplev.c (rest_of_compilation): Likewise.
* stupid.c (stupid_life_analysis): Update life data calls.
* rtl.h, output.h: Update prototypes.
Index: flow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/flow.c,v
retrieving revision 1.170
diff -c -p -d -r1.170 flow.c
*** flow.c 1999/03/27 23:21:02 1.170
--- flow.c 1999/03/31 20:28:33
*************** static void new_insn_dead_notes PROTO (
*** 354,363 ****
numbers in use. */
void
! find_basic_blocks (f, nregs, file)
rtx f;
int nregs ATTRIBUTE_UNUSED;
FILE *file ATTRIBUTE_UNUSED;
{
rtx *bb_eh_end;
int max_uid;
--- 354,364 ----
numbers in use. */
void
! find_basic_blocks (f, nregs, file, do_cleanup)
rtx f;
int nregs ATTRIBUTE_UNUSED;
FILE *file ATTRIBUTE_UNUSED;
+ int do_cleanup;
{
rtx *bb_eh_end;
int max_uid;
*************** find_basic_blocks (f, nregs, file)
*** 416,424 ****
make_edges (label_value_list, bb_eh_end);
/* Delete unreachable blocks. */
- /* ??? Do this conditionally, or make this another entry point? */
! delete_unreachable_blocks ();
/* Mark critical edges. */
--- 417,425 ----
make_edges (label_value_list, bb_eh_end);
/* Delete unreachable blocks. */
! if (do_cleanup)
! delete_unreachable_blocks ();
/* Mark critical edges. */
*************** free_basic_block_vars (keep_head_end_p)
*** 2111,2116 ****
--- 2112,2122 ----
clear_edges ();
VARRAY_FREE (basic_block_info);
n_basic_blocks = 0;
+
+ ENTRY_BLOCK_PTR->aux = NULL;
+ ENTRY_BLOCK_PTR->global_live_at_end = NULL;
+ EXIT_BLOCK_PTR->aux = NULL;
+ EXIT_BLOCK_PTR->global_live_at_start = NULL;
}
}
*************** life_analysis_1 (f, nregs)
*** 2312,2318 ****
/* Allocate and zero out many data structures
that will record the data from lifetime analysis. */
! allocate_for_life_analysis ();
reg_next_use = (rtx *) alloca (nregs * sizeof (rtx));
memset (reg_next_use, 0, nregs * sizeof (rtx));
--- 2318,2325 ----
/* Allocate and zero out many data structures
that will record the data from lifetime analysis. */
! allocate_reg_life_data ();
! allocate_bb_life_data ();
reg_next_use = (rtx *) alloca (nregs * sizeof (rtx));
memset (reg_next_use, 0, nregs * sizeof (rtx));
*************** life_analysis_1 (f, nregs)
*** 2525,2545 ****
of life analysis. Not static since used also for stupid life analysis. */
void
! allocate_for_life_analysis ()
{
register int i;
- /* Recalculate the register space, in case it has grown. Old style
- vector oriented regsets would set regset_{size,bytes} here also. */
- allocate_reg_info (max_regno, FALSE, FALSE);
-
- /* Because both reg_scan and flow_analysis want to set up the REG_N_SETS
- information, explicitly reset it here. The allocation should have
- already happened on the previous reg_scan pass. Make sure in case
- some more registers were allocated. */
- for (i = 0; i < max_regno; i++)
- REG_N_SETS (i) = 0;
-
for (i = 0; i < n_basic_blocks; i++)
{
basic_block bb = BASIC_BLOCK (i);
--- 2532,2541 ----
of life analysis. Not static since used also for stupid life analysis. */
void
! allocate_bb_life_data ()
{
register int i;
for (i = 0; i < n_basic_blocks; i++)
{
basic_block bb = BASIC_BLOCK (i);
*************** allocate_for_life_analysis ()
*** 2555,2561 ****
= OBSTACK_ALLOC_REG_SET (function_obstack);
regs_live_at_setjmp = OBSTACK_ALLOC_REG_SET (function_obstack);
! CLEAR_REG_SET (regs_live_at_setjmp);
}
/* Make each element of VECTOR point at a regset. The vector has
--- 2551,2573 ----
= OBSTACK_ALLOC_REG_SET (function_obstack);
regs_live_at_setjmp = OBSTACK_ALLOC_REG_SET (function_obstack);
! }
!
! void
! allocate_reg_life_data ()
! {
! int i;
!
! /* Recalculate the register space, in case it has grown. Old style
! vector oriented regsets would set regset_{size,bytes} here also. */
! allocate_reg_info (max_regno, FALSE, FALSE);
!
! /* Because both reg_scan and flow_analysis want to set up the REG_N_SETS
! information, explicitly reset it here. The allocation should have
! already happened on the previous reg_scan pass. Make sure in case
! some more registers were allocated. */
! for (i = 0; i < max_regno; i++)
! REG_N_SETS (i) = 0;
}
/* Make each element of VECTOR point at a regset. The vector has
*************** cygnus_merge_blocks (f)
*** 5086,5092 ****
return;
/* First break the program into basic blocks. */
! find_basic_blocks (f, max_reg_num (), NULL);
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
--- 5098,5104 ----
return;
/* First break the program into basic blocks. */
! find_basic_blocks (f, max_reg_num (), NULL, 1);
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
Index: gcse.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/gcse.c,v
retrieving revision 1.62
diff -c -p -d -r1.62 gcse.c
*** gcse.c 1999/03/21 15:47:00 1.62
--- gcse.c 1999/03/31 20:28:34
*************** gcse_main (f, file)
*** 665,671 ****
/* Identify the basic block information for this function, including
successors and predecessors. */
max_gcse_regno = max_reg_num ();
! find_basic_blocks (f, max_gcse_regno, file);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
--- 665,671 ----
/* Identify the basic block information for this function, including
successors and predecessors. */
max_gcse_regno = max_reg_num ();
! find_basic_blocks (f, max_gcse_regno, file, 1);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
*************** gcse_main (f, file)
*** 698,704 ****
{
/* Call find_basic_blocks to compute the new number of basic
blocks and new edge data. */
! find_basic_blocks (f, max_gcse_regno, file);
/* This leaks memory until the end of this function. I don't see
a good way to fix this without introducing more complexity in
--- 698,704 ----
{
/* Call find_basic_blocks to compute the new number of basic
blocks and new edge data. */
! find_basic_blocks (f, max_gcse_regno, file, 1);
/* This leaks memory until the end of this function. I don't see
a good way to fix this without introducing more complexity in
*************** delete_null_pointer_checks (f)
*** 5535,5541 ****
sbitmap *nonnull_avin, *nonnull_avout;
/* First break the program into basic blocks. */
! find_basic_blocks (f, max_reg_num (), NULL);
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
--- 5535,5541 ----
sbitmap *nonnull_avin, *nonnull_avout;
/* First break the program into basic blocks. */
! find_basic_blocks (f, max_reg_num (), NULL, 1);
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
Index: output.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/output.h,v
retrieving revision 1.48
diff -c -p -d -r1.48 output.h
*** output.h 1999/03/16 23:58:09 1.48
--- output.h 1999/03/31 20:28:34
*************** extern int only_leaf_regs_used PROTO((vo
*** 124,134 ****
extern void leaf_renumber_regs_insn PROTO((rtx));
/* Functions in flow.c */
! extern void allocate_for_life_analysis PROTO((void));
extern int regno_uninitialized PROTO((int));
extern int regno_clobbered_at_setjmp PROTO((int));
extern void dump_flow_info PROTO((FILE *));
! extern void find_basic_blocks PROTO((rtx, int, FILE *));
extern void free_basic_block_vars PROTO((int));
extern void set_block_num PROTO((rtx, int));
extern void life_analysis PROTO((rtx, int, FILE *));
--- 124,135 ----
extern void leaf_renumber_regs_insn PROTO((rtx));
/* Functions in flow.c */
! extern void allocate_bb_life_data PROTO((void));
! extern void allocate_reg_life_data PROTO((void));
extern int regno_uninitialized PROTO((int));
extern int regno_clobbered_at_setjmp PROTO((int));
extern void dump_flow_info PROTO((FILE *));
! extern void find_basic_blocks PROTO((rtx, int, FILE *, int));
extern void free_basic_block_vars PROTO((int));
extern void set_block_num PROTO((rtx, int));
extern void life_analysis PROTO((rtx, int, FILE *));
Index: range.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/range.c,v
retrieving revision 1.13
diff -c -p -d -r1.13 range.c
*** range.c 1999/03/05 20:43:31 1.13
--- range.c 1999/03/31 20:28:34
*************** range_update_basic_block (stream, first_
*** 1101,1106 ****
--- 1101,1111 ----
for (i = 0; i < old_n_basic_blocks; i++)
{
rtx p = emit_note_before (NOTE_INSN_LIVE, BLOCK_HEAD (i));
+
+ /* ??? Note that we are putting a pointer to the current
+ global_live_at_start info into the rtl. When we reallocate
+ basic block below, we need to create new reg sets to avoid
+ sharing. */
NOTE_LIVE_INFO (p) = gen_rtx (RANGE_LIVE, VOIDmode,
BASIC_BLOCK (i)->global_live_at_start, i);
map_bb[i] = -1;
*************** range_update_basic_block (stream, first_
*** 1121,1135 ****
putc ('\n', stream);
/* Recalculate the basic blocks. */
! find_basic_blocks (first_insn, max_regno, stream);
free_basic_block_vars (TRUE);
! /* Restore the live information. We assume that flow will find either a
! previous start of a basic block, or the newly created insn blocks as
! the start of the new basic blocks. */
! if (old_n_basic_blocks != n_basic_blocks)
! allocate_for_life_analysis ();
block = 0;
in_block_p = FALSE;
--- 1126,1139 ----
putc ('\n', stream);
/* Recalculate the basic blocks. */
! find_basic_blocks (first_insn, max_regno, stream, 0);
free_basic_block_vars (TRUE);
! /* Reallocate the life information.
! ??? We're assuming we get new data structures so that we avoid sharing
! with the old data structures squirreled away above. */
! allocate_bb_life_data ();
block = 0;
in_block_p = FALSE;
*************** range_update_basic_block (stream, first_
*** 1212,1217 ****
--- 1216,1229 ----
if (block < n_basic_blocks)
{
block_start = BLOCK_HEAD (block);
+
+ /* We want to skip the NOTE_INSN_BASIC_BLOCK notes emitted by
+ flow, so that the new_bb[i].first_insn test above will
+ work. */
+ if (GET_CODE (block_start) == NOTE
+ && NOTE_LINE_NUMBER (block_start) == NOTE_INSN_BASIC_BLOCK)
+ block_start = NEXT_INSN (block_start);
+
block_end = BLOCK_END (block);
}
else
Index: rtl.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/rtl.h,v
retrieving revision 1.120
diff -c -p -d -r1.120 rtl.h
*** rtl.h 1999/03/25 20:09:10 1.120
--- rtl.h 1999/03/31 20:28:34
*************** extern void stupid_life_analysis PROTO (
*** 1458,1464 ****
#endif
/* In flow.c */
! extern void allocate_for_life_analysis PROTO ((void));
extern void recompute_reg_usage PROTO ((rtx, int));
#ifdef BUFSIZ
extern void dump_flow_info PROTO ((FILE *));
--- 1458,1465 ----
#endif
/* In flow.c */
! extern void allocate_bb_life_data PROTO ((void));
! extern void allocate_reg_life_data PROTO ((void));
extern void recompute_reg_usage PROTO ((rtx, int));
#ifdef BUFSIZ
extern void dump_flow_info PROTO ((FILE *));
Index: sibcall.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/sibcall.c,v
retrieving revision 1.10
diff -c -p -d -r1.10 sibcall.c
*** sibcall.c 1999/03/17 04:25:28 1.10
--- sibcall.c 1999/03/31 20:28:34
*************** optimize_sibling_and_tail_recursive_call
*** 339,345 ****
/* We need cfg information to determine which blocks are succeeded
only by the epilogue. */
! find_basic_blocks (insns, max_reg_num (), 0);
/* If there are no basic blocks, then there is nothing to do. */
if (n_basic_blocks == 0)
--- 339,345 ----
/* We need cfg information to determine which blocks are succeeded
only by the epilogue. */
! find_basic_blocks (insns, max_reg_num (), 0, 1);
/* If there are no basic blocks, then there is nothing to do. */
if (n_basic_blocks == 0)
Index: stupid.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/stupid.c,v
retrieving revision 1.36
diff -c -p -d -r1.36 stupid.c
*** stupid.c 1999/01/15 07:57:58 1.36
--- stupid.c 1999/03/31 20:28:34
*************** stupid_life_analysis (f, nregs, file)
*** 253,259 ****
/* Allocate and zero out many data structures
that will record the data from lifetime analysis. */
! allocate_for_life_analysis ();
for (i = 0; i < max_regno; i++)
REG_N_DEATHS (i) = 1;
--- 253,260 ----
/* Allocate and zero out many data structures
that will record the data from lifetime analysis. */
! allocate_reg_life_data ();
! allocate_bb_life_data ();
for (i = 0; i < max_regno; i++)
REG_N_DEATHS (i) = 1;
Index: toplev.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/toplev.c,v
retrieving revision 1.352
diff -c -p -d -r1.352 toplev.c
*** toplev.c 1999/03/12 16:50:52 1.352
--- toplev.c 1999/03/31 20:28:35
*************** rest_of_compilation (decl)
*** 4070,4076 ****
TIMEVAR
(flow_time,
{
! find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
--- 4070,4076 ----
TIMEVAR
(flow_time,
{
! find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
*************** rest_of_compilation (decl)
*** 4268,4274 ****
TIMEVAR
(flow2_time,
{
! find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
}
--- 4268,4274 ----
TIMEVAR
(flow2_time,
{
! find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file);
});
}
*************** main (argc, argv)
*** 4917,4924 ****
If/when we add LRS support to our dwarf2 code we can enable LRS
optimizations for more targets. */
! /* ??? Temporary. Live range splitting is broken with new flow code. */
! /* flag_live_range = (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG); */
/* END CYGNUS LOCAL */
/* CYGNUS LOCAL peephole2 */
flag_peephole2 = 1;
--- 4917,4923 ----
If/when we add LRS support to our dwarf2 code we can enable LRS
optimizations for more targets. */
! flag_live_range = 1 || (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG);
/* END CYGNUS LOCAL */
/* CYGNUS LOCAL peephole2 */
flag_peephole2 = 1;
More information about the Gcc-patches
mailing list