aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gcse.c32
-rw-r--r--gcc/ssa.c7
-rw-r--r--gcc/toplev.c170
4 files changed, 113 insertions, 103 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 04b2004..3c39485 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2000-04-07 Richard Henderson <rth@cygnus.com>
+ * gcse.c (gcse_main): Don't rebuild the CFG here.
+ (delete_null_pointer_checks): Likewise.
+ * ssa.c (convert_to_ssa): Likewise.
+ * toplev.c (rest_of_compilation): Do it here instead. Combine
+ sequential calls to TIMEVAR. Consistently use `insns' instead of
+ `get_insns()'. Always split insns after reload when optimizing.
+
* basic-block.h (merge_blocks_nomove): Declare.
(tidy_fallthru_edge): Declare.
* flow.c (merge_blocks_nomove): Document as merging into previous
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 7a646f1..996cde9 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -669,18 +669,13 @@ gcse_main (f, file)
/* 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);
- cleanup_cfg (f);
if (file)
dump_flow_info (file);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
- {
- free_basic_block_vars (0);
- return 0;
- }
+ return 0;
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
@@ -691,10 +686,7 @@ gcse_main (f, file)
a couple switch statements. So we require a relatively large number
of basic blocks and the ratio of edges to blocks to be high. */
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
- {
- free_basic_block_vars (0);
- return 0;
- }
+ return 0;
/* See what modes support reg/reg copy operations. */
if (! can_copy_init_p)
@@ -807,7 +799,6 @@ gcse_main (f, file)
obstack_free (&gcse_obstack, NULL_PTR);
free_reg_set_mem ();
- free_basic_block_vars (0);
return run_jump_opt_after_gcse;
}
@@ -5070,17 +5061,9 @@ delete_null_pointer_checks (f)
int max_reg;
struct null_pointer_info npi;
- /* First break the program into basic blocks. */
- find_basic_blocks (f, max_reg_num (), NULL);
- cleanup_cfg (f);
-
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
- {
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
- return;
- }
+ return;
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
@@ -5091,11 +5074,7 @@ delete_null_pointer_checks (f)
a couple switch statements. So we require a relatively large number
of basic blocks and the ratio of edges to blocks to be high. */
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
- {
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
- return;
- }
+ return;
/* We need four bitmaps, each with a bit for each register in each
basic block. */
@@ -5152,9 +5131,6 @@ delete_null_pointer_checks (f)
nonnull_avout, &npi);
}
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
-
/* Free the table of registers compared at the end of every block. */
free (block_reg);
diff --git a/gcc/ssa.c b/gcc/ssa.c
index b10c46f..af7b6ad 100644
--- a/gcc/ssa.c
+++ b/gcc/ssa.c
@@ -855,10 +855,6 @@ convert_to_ssa()
if (in_ssa_form)
abort ();
- find_basic_blocks (get_insns (), max_reg_num(), NULL);
- /* The dominator algorithms assume all blocks are reachable; clean
- up first. */
- cleanup_cfg (get_insns ());
/* Don't eliminate dead code here. The CFG we computed above must
remain unchanged until we are finished emerging from SSA form --
the phi node representation depends on it. */
@@ -930,8 +926,6 @@ convert_to_ssa()
in_ssa_form = 1;
reg_scan (get_insns (), max_reg_num (), 1);
- find_basic_blocks (get_insns (), max_reg_num (), NULL);
- life_analysis (get_insns (), max_reg_num (), NULL, 0);
}
@@ -1818,7 +1812,6 @@ convert_from_ssa()
rtx insns = get_insns ();
/* We need up-to-date life information. */
- find_basic_blocks (insns, max_reg_num (), NULL);
life_analysis (insns, max_reg_num (), NULL, 0);
/* Figure out which regs in copies and phi nodes don't conflict and
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 6ab7efc..00721b3 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2861,7 +2861,7 @@ rest_of_compilation (decl)
int saved_optimize = optimize;
optimize = 0;
find_exception_handler_labels ();
- jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN);
optimize = saved_optimize;
}
@@ -2907,9 +2907,7 @@ rest_of_compilation (decl)
/* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
- {
- goto exit_rest_of_compilation;
- }
+ goto exit_rest_of_compilation;
/* Emit code to get eh context, if needed. */
emit_eh_context ();
@@ -2935,7 +2933,6 @@ rest_of_compilation (decl)
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
-
unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
@@ -2945,13 +2942,7 @@ rest_of_compilation (decl)
#endif
/* Instantiate all virtual registers. */
-
- instantiate_virtual_regs (current_function_decl, get_insns ());
-
- /* See if we have allocated stack slots that are not directly addressable.
- If so, scan all the insns and create explicit address computation
- for all references to such slots. */
- /* fixup_stack_slots (); */
+ instantiate_virtual_regs (current_function_decl, insns);
/* Find all the EH handlers. */
find_exception_handler_labels ();
@@ -2961,26 +2952,39 @@ rest_of_compilation (decl)
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
-
- /* Jump optimization, and the removal of NULL pointer checks, may
- have reduced the number of instructions substantially. CSE, and
- future passes, allocate arrays whose dimensions involve the maximum
- instruction UID, so if we can reduce the maximum UID we'll save big on
- memory. */
- renumber_insns (rtl_dump_file);
-
- close_dump_file (DFI_jump, print_rtl, insns);
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ JUMP_AFTER_REGSCAN);
+ });
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
- goto exit_rest_of_compilation;
+ {
+ close_dump_file (DFI_jump, print_rtl, insns);
+ goto exit_rest_of_compilation;
+ }
+
+ TIMEVAR (jump_time,
+ {
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks)
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ delete_null_pointer_checks (insns);
+ }
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+ /* Jump optimization, and the removal of NULL pointer checks,
+ may have reduced the number of instructions substantially.
+ CSE, and future passes, allocate arrays whose dimensions
+ involve the maximum instruction UID, so if we can reduce
+ the maximum UID we'll save big on memory. */
+ renumber_insns (rtl_dump_file);
+ });
+
+ close_dump_file (DFI_jump, print_rtl, insns);
if (ggc_p)
ggc_collect ();
@@ -3001,6 +3005,7 @@ rest_of_compilation (decl)
TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
0, rtl_dump_file));
+
/* If we are not running the second CSE pass, then we are no longer
expecting CSE to be run. */
cse_not_expected = !flag_rerun_cse_after_loop;
@@ -3016,7 +3021,12 @@ rest_of_compilation (decl)
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
- TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+ TIMEVAR (jump_time,
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ delete_null_pointer_checks (insns);
+ });
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
@@ -3035,21 +3045,35 @@ rest_of_compilation (decl)
if (ggc_p)
ggc_collect ();
- if (flag_ssa)
+ if (optimize > 0 && flag_ssa)
{
open_dump_file (DFI_ssa, decl);
- TIMEVAR (to_ssa_time, convert_to_ssa ());
+
+ TIMEVAR (to_ssa_time,
+ {
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ convert_to_ssa ();
+ });
+
close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
open_dump_file (DFI_ussa, decl);
- TIMEVAR (from_ssa_time, convert_from_ssa ());
- /* New registers have been created. Rescan their usage. */
- reg_scan (insns, max_reg_num (), 1);
- close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
- /* Life analysis used in SSA adds log_links but these shouldn't
- be there until the flow stage, so clear them away. */
- clear_log_links (insns);
+ TIMEVAR (from_ssa_time,
+ {
+ convert_from_ssa ();
+
+ /* New registers have been created. Rescan their usage. */
+ reg_scan (insns, max_reg_num (), 1);
+
+ /* Life analysis used in SSA adds log_links but these
+ shouldn't be there until the flow stage, so clear
+ them away. */
+ clear_log_links (insns);
+ });
+
+ close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3061,7 +3085,12 @@ rest_of_compilation (decl)
{
open_dump_file (DFI_gcse, decl);
- TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
+ TIMEVAR (gcse_time,
+ {
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ tem = gcse_main (insns, rtl_dump_file);
+ });
/* If gcse altered any jumps, rerun jump optimizations to clean
things up. */
@@ -3077,6 +3106,7 @@ rest_of_compilation (decl)
if (ggc_p)
ggc_collect ();
}
+
/* Move constant computations out of loops. */
if (optimize > 0)
@@ -3091,8 +3121,7 @@ rest_of_compilation (decl)
/* We only want to perform unrolling once. */
loop_optimize (insns, rtl_dump_file, 0, 0);
-
-
+
/* The first call to loop_optimize makes some instructions
trivially dead. We delete those instructions now in the
hope that doing so will make the heuristics in loop work
@@ -3128,14 +3157,20 @@ rest_of_compilation (decl)
the second CSE pass to do a better job. Jump_optimize can change
max_reg_num so we must rerun reg_scan afterwards.
??? Rework to not call reg_scan so often. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP,
+ !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
+ });
- TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
- 1, rtl_dump_file));
+ TIMEVAR (cse2_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ tem = cse_main (insns, max_reg_num (),
+ 1, rtl_dump_file);
+ });
+
if (tem)
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
@@ -3146,8 +3181,11 @@ rest_of_compilation (decl)
{
/* This pass of jump threading straightens out code
that was kinked by loop optimization. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ thread_jumps (insns, max_reg_num (), 0);
+ });
}
close_dump_file (DFI_cse2, print_rtl, insns);
@@ -3160,11 +3198,10 @@ rest_of_compilation (decl)
{
open_dump_file (DFI_bp, decl);
- TIMEVAR
- (branch_prob_time,
- {
- branch_prob (insns, rtl_dump_file);
- });
+ TIMEVAR (branch_prob_time,
+ {
+ branch_prob (insns, rtl_dump_file);
+ });
close_dump_file (DFI_bp, print_rtl, insns);
@@ -3301,8 +3338,11 @@ rest_of_compilation (decl)
if (dump_file[DFI_lreg].enabled)
{
- TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
- TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+ TIMEVAR (dump_time,
+ {
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
+ });
close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
}
@@ -3336,13 +3376,9 @@ rest_of_compilation (decl)
if (optimize > 0)
reload_cse_regs (insns);
- /* If optimizing and we are performing instruction scheduling after
- reload, then go ahead and split insns now since we are about to
- recompute flow information anyway.
-
- reload_cse_regs may expose more splitting opportunities, expecially
- for double-word operations. */
- if (optimize > 0 && flag_schedule_insns_after_reload)
+ /* If optimizing, then go ahead and split insns now since we are about
+ to recompute flow information anyway. */
+ if (optimize > 0)
split_all_insns (0);
/* Register allocation and reloading may have turned an indirect jump into
@@ -3362,6 +3398,7 @@ rest_of_compilation (decl)
TIMEVAR (flow2_time,
{
+ jump_optimize_minimal (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
});
@@ -3498,10 +3535,7 @@ rest_of_compilation (decl)
Note this must run before reg-stack because of death note (ab)use
in the ia32 backend. */
- TIMEVAR (shorten_branch_time,
- {
- shorten_branches (get_insns ());
- });
+ TIMEVAR (shorten_branch_time, shorten_branches (get_insns ()));
#ifdef STACK_REGS
open_dump_file (DFI_stack, decl);