This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cond_exec patch 2/4
- To: gcc-patches at gcc dot gnu dot org
- Subject: cond_exec patch 2/4
- From: Richard Henderson <rth at cygnus dot com>
- Date: Fri, 7 Apr 2000 02:33:02 -0700
If-conversion requires the CFG to be correct on entry, and
it also leaves the the CFG correct on exit.
Pull most of the calls to find_basic_blocks et al into
rest_of_compilation where we can see them, and we can begin
to remove redundant invocations.
The only functional change is to the call to split_all_insns,
which I actually intended to go in with a different logical hunk,
but got lazy and didn't fix it after discovering the mistake.
r~
* 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.
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.84
diff -c -p -d -r1.84 gcse.c
*** gcse.c 2000/03/25 18:34:02 1.84
--- gcse.c 2000/04/07 08:56:54
*************** gcse_main (f, file)
*** 669,686 ****
/* 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;
! }
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
--- 669,681 ----
/* Identify the basic block information for this function, including
successors and predecessors. */
max_gcse_regno = max_reg_num ();
if (file)
dump_flow_info (file);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
! 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
*************** gcse_main (f, file)
*** 691,700 ****
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;
! }
/* See what modes support reg/reg copy operations. */
if (! can_copy_init_p)
--- 686,692 ----
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)
! return 0;
/* See what modes support reg/reg copy operations. */
if (! can_copy_init_p)
*************** gcse_main (f, file)
*** 807,813 ****
obstack_free (&gcse_obstack, NULL_PTR);
free_reg_set_mem ();
- free_basic_block_vars (0);
return run_jump_opt_after_gcse;
}
--- 799,804 ----
*************** delete_null_pointer_checks (f)
*** 5070,5086 ****
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;
! }
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
--- 5061,5069 ----
int max_reg;
struct null_pointer_info npi;
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
! return;
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
*************** delete_null_pointer_checks (f)
*** 5091,5101 ****
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;
! }
/* We need four bitmaps, each with a bit for each register in each
basic block. */
--- 5074,5080 ----
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)
! return;
/* We need four bitmaps, each with a bit for each register in each
basic block. */
*************** delete_null_pointer_checks (f)
*** 5151,5159 ****
delete_null_pointer_checks_1 (block_reg, nonnull_avin,
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);
--- 5130,5135 ----
Index: ssa.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ssa.c,v
retrieving revision 1.5
diff -c -p -d -r1.5 ssa.c
*** ssa.c 2000/04/06 21:22:48 1.5
--- ssa.c 2000/04/07 08:56:54
*************** convert_to_ssa()
*** 855,864 ****
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. */
--- 855,860 ----
*************** convert_to_ssa()
*** 930,937 ****
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);
}
--- 926,931 ----
*************** convert_from_ssa()
*** 1818,1824 ****
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
--- 1812,1817 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.314
diff -c -p -d -r1.314 toplev.c
*** toplev.c 2000/04/06 21:22:48 1.314
--- toplev.c 2000/04/07 08:56:55
*************** rest_of_compilation (decl)
*** 2881,2887 ****
int saved_optimize = optimize;
optimize = 0;
find_exception_handler_labels ();
! jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN);
optimize = saved_optimize;
}
--- 2881,2887 ----
int saved_optimize = optimize;
optimize = 0;
find_exception_handler_labels ();
! jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN);
optimize = saved_optimize;
}
*************** rest_of_compilation (decl)
*** 2927,2935 ****
/* 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;
! }
/* Emit code to get eh context, if needed. */
emit_eh_context ();
--- 2927,2933 ----
/* 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;
/* Emit code to get eh context, if needed. */
emit_eh_context ();
*************** rest_of_compilation (decl)
*** 2955,2961 ****
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
-
unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
--- 2953,2958 ----
*************** rest_of_compilation (decl)
*** 2965,2977 ****
#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 (); */
/* Find all the EH handlers. */
find_exception_handler_labels ();
--- 2962,2968 ----
#endif
/* Instantiate all virtual registers. */
! instantiate_virtual_regs (current_function_decl, insns);
/* Find all the EH handlers. */
find_exception_handler_labels ();
*************** rest_of_compilation (decl)
*** 2981,3007 ****
/* 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);
/* 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;
! /* 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 ()));
if (ggc_p)
ggc_collect ();
--- 2972,3011 ----
/* 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);
! 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))
! {
! 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);
! }
+ /* 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 ();
*************** rest_of_compilation (decl)
*** 3021,3026 ****
--- 3025,3031 ----
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;
*************** rest_of_compilation (decl)
*** 3036,3042 ****
/* 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 ()));
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
--- 3041,3052 ----
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
! 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. */
*************** rest_of_compilation (decl)
*** 3055,3075 ****
if (ggc_p)
ggc_collect ();
! if (flag_ssa)
{
open_dump_file (DFI_ssa, decl);
! TIMEVAR (to_ssa_time, 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);
if (ggc_p)
ggc_collect ();
--- 3065,3099 ----
if (ggc_p)
ggc_collect ();
! if (optimize > 0 && flag_ssa)
{
open_dump_file (DFI_ssa, decl);
!
! 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);
!
! /* 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 ();
*************** rest_of_compilation (decl)
*** 3081,3087 ****
{
open_dump_file (DFI_gcse, decl);
! TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
/* If gcse altered any jumps, rerun jump optimizations to clean
things up. */
--- 3105,3116 ----
{
open_dump_file (DFI_gcse, decl);
! 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. */
*************** rest_of_compilation (decl)
*** 3097,3102 ****
--- 3126,3132 ----
if (ggc_p)
ggc_collect ();
}
+
/* Move constant computations out of loops. */
if (optimize > 0)
*************** rest_of_compilation (decl)
*** 3111,3118 ****
/* 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
--- 3141,3147 ----
/* 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
*************** rest_of_compilation (decl)
*** 3148,3161 ****
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 (cse2_time, reg_scan (insns, max_reg_num (), 0));
! TIMEVAR (cse2_time, 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,
--- 3177,3196 ----
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);
! jump_optimize (insns, !JUMP_CROSS_JUMP,
! !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
! });
! 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,
*************** rest_of_compilation (decl)
*** 3166,3173 ****
{
/* 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));
}
close_dump_file (DFI_cse2, print_rtl, insns);
--- 3201,3211 ----
{
/* This pass of jump threading straightens out code
that was kinked by loop optimization. */
! 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);
*************** rest_of_compilation (decl)
*** 3180,3190 ****
{
open_dump_file (DFI_bp, decl);
! TIMEVAR
! (branch_prob_time,
! {
! branch_prob (insns, rtl_dump_file);
! });
close_dump_file (DFI_bp, print_rtl, insns);
--- 3218,3227 ----
{
open_dump_file (DFI_bp, decl);
! TIMEVAR (branch_prob_time,
! {
! branch_prob (insns, rtl_dump_file);
! });
close_dump_file (DFI_bp, print_rtl, insns);
*************** rest_of_compilation (decl)
*** 3321,3328 ****
if (dump_file[DFI_lreg].enabled)
{
! TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
! TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
}
--- 3358,3368 ----
if (dump_file[DFI_lreg].enabled)
{
! 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);
}
*************** rest_of_compilation (decl)
*** 3356,3368 ****
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)
split_all_insns (0);
/* Register allocation and reloading may have turned an indirect jump into
--- 3396,3404 ----
if (optimize > 0)
reload_cse_regs (insns);
! /* 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
*************** rest_of_compilation (decl)
*** 3382,3387 ****
--- 3418,3424 ----
TIMEVAR (flow2_time,
{
+ jump_optimize_minimal (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
});
*************** rest_of_compilation (decl)
*** 3518,3527 ****
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 ());
! });
#ifdef STACK_REGS
open_dump_file (DFI_stack, decl);
--- 3555,3561 ----
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 ()));
#ifdef STACK_REGS
open_dump_file (DFI_stack, decl);