diff options
author | Jan Hubicka <jh@suse.cz> | 2002-02-28 10:11:01 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2002-02-28 10:11:01 +0000 |
commit | 38c1593d577d667bd1bcb486c0a6b34c218ebb46 (patch) | |
tree | 8d5067250a1945f16e7442da0ebfa33bcd46322d /gcc/toplev.c | |
parent | bde131d34d70387ac376419405e9b5c8a788984c (diff) | |
download | gcc-38c1593d577d667bd1bcb486c0a6b34c218ebb46.tar.gz |
basic-block.h (BB_REACHABLE): Renumber.
* basic-block.h (BB_REACHABLE): Renumber.
(BB_DIRTY, BB_NEW): New flags.
(clear_bb_flags): Declare.
(update_life_info_in_dirty_blocks): Declare.
* cfg.c (clear_bb_flags): New function.
* cfgrtl.c (create_basic_block_structure): Set flags to BB_NEW.
* emit-rtl.c (add_insn_after, add_insn_before, remove_insn,
reorder_insns, emit_insn_after): Mark block as dirty.
* flow.c (update_life_info): Fix clearing of PROP_LOG_LINKS.
(update_life_info_in_dirty_blocks): New function.
* recog.c (apply_change_group): Dirtify block.
* cse.c (cse_insn): Reorder emitting of jump insn to keep
cfg consistent.
* gcse.c (delete_null_pointer_checks): Likewise.
* toplev.c (dump_file_index): Move cse2 after bp,
add DFI_null
(dump_file_info): Similary.
(rest_of_compilation): Avoid most of CFG rebuilds;
do first if converision after null pointer checks, do cse2
after branch prediction; avoid full liveness rebuild after
initializing subregs.
* invoke.texi (-d options): Document -du, renumber.
* cfgcleanup.c (bb_flags): Remove BB_UPDATE_LIFE.
(notice_new_block): Do not set BB_UPDATE_LIFE.
(try_forward_edges, merge_blocks_move_predecessor_nojumps,
merge_blocks_move_successor_nojumps, merge_blocks,
try_crossjump_to_edge): Likewise.
(try_optimize_cfg): Likewise; use update_life_info_in_dirty_blocks.
* cfgrtl.c (merge_blocks_nomove): Copy b's flags to a.
* ifcvt.c (SET_UPDATE_LIFE, UPDATE_LIFE): Kill.
(merge_of_block): Do not use life_data_ok.
(find_if_case_1): Do not use SET_UPDATE_LIFE.
(if_convert): Use BB_DIRTY mechanizm to update life.
* lcm.c (optimize_mode_switching): Update
update_life_info_in_dirty_blocks
From-SVN: r50127
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r-- | gcc/toplev.c | 221 |
1 files changed, 107 insertions, 114 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c index 9676dcde5a0..7cf0c96db9a 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -240,13 +240,14 @@ enum dump_file_index DFI_ssa_ccp, DFI_ssa_dce, DFI_ussa, + DFI_null, DFI_cse, DFI_addressof, DFI_gcse, DFI_loop, - DFI_cse2, DFI_cfg, DFI_bp, + DFI_cse2, DFI_life, DFI_combine, DFI_ce, @@ -272,7 +273,7 @@ enum dump_file_index Remaining -d letters: - " o q u " + " o q " " H JK OPQ TUV YZ" */ @@ -286,13 +287,14 @@ static struct dump_file_info dump_file[DFI_MAX] = { "ssaccp", 'W', 1, 0, 0 }, { "ssadce", 'X', 1, 0, 0 }, { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */ + { "null", 'u', 0, 0, 0 }, { "cse", 's', 0, 0, 0 }, { "addressof", 'F', 0, 0, 0 }, { "gcse", 'G', 1, 0, 0 }, { "loop", 'L', 1, 0, 0 }, - { "cse2", 't', 1, 0, 0 }, { "cfg", 'f', 1, 0, 0 }, { "bp", 'b', 1, 0, 0 }, + { "cse2", 't', 1, 0, 0 }, { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ { "combine", 'c', 1, 0, 0 }, { "ce", 'C', 1, 0, 0 }, @@ -2608,6 +2610,8 @@ rest_of_compilation (decl) reg_scan (insns, max_reg_num (), 0); rebuild_jump_labels (insns); find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP); /* CFG is no longer maintained up-to-date. */ @@ -2616,11 +2620,11 @@ rest_of_compilation (decl) purge_line_number_notes (insns); timevar_pop (TV_JUMP); + 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)) { - close_dump_file (DFI_jump, print_rtl, insns); goto exit_rest_of_compilation; } @@ -2697,23 +2701,22 @@ rest_of_compilation (decl) if (optimize > 0) { + open_dump_file (DFI_null, decl); find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - /* ??? Run if-conversion before delete_null_pointer_checks, - since the later does not preserve the CFG. This should - be changed -- no since converting if's that are going to - be deleted. */ - timevar_push (TV_IFCVT); - if_convert (0); - timevar_pop (TV_IFCVT); - - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); /* Try to identify useless null pointer tests and delete them. */ if (flag_delete_null_pointer_checks) delete_null_pointer_checks (insns); + + timevar_push (TV_IFCVT); + if_convert (0); + timevar_pop (TV_IFCVT); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); + close_dump_file (DFI_null, print_rtl_with_bb, insns); } /* Jump optimization, and the removal of NULL pointer checks, may @@ -2722,9 +2725,11 @@ rest_of_compilation (decl) maximum instruction UID, so if we can reduce the maximum UID we'll save big on memory. */ renumber_insns (rtl_dump_file); + if (optimize) + compute_bb_for_insn (get_max_uid ()); timevar_pop (TV_JUMP); - close_dump_file (DFI_jump, print_rtl, insns); + close_dump_file (DFI_jump, print_rtl_with_bb, insns); ggc_collect (); @@ -2736,36 +2741,32 @@ rest_of_compilation (decl) if (optimize > 0) { open_dump_file (DFI_cse, decl); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + if (tem) + rebuild_jump_labels (insns); + purge_all_dead_edges (0); /* If we are not running more CSE passes, then we are no longer expecting CSE to be run. But always rerun it in a cheap mode. */ cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; if (tem || optimize > 1) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (insns); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - timevar_pop (TV_JUMP); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); - } + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); /* Run this after jump optmizations remove all the unreachable code so that unreachable code will not keep values live. */ - delete_trivially_dead_insns (insns, max_reg_num (), 0); + delete_trivially_dead_insns (insns, max_reg_num (), 1); /* Try to identify useless null pointer tests and delete them. */ if (flag_delete_null_pointer_checks || flag_thread_jumps) { timevar_push (TV_JUMP); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP | (flag_thread_jumps ? CLEANUP_THREADING : 0)); @@ -2773,21 +2774,23 @@ rest_of_compilation (decl) if (flag_delete_null_pointer_checks) delete_null_pointer_checks (insns); /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); timevar_pop (TV_JUMP); } /* The second pass of jump optimization is likely to have removed a bunch more instructions. */ renumber_insns (rtl_dump_file); + compute_bb_for_insn (get_max_uid ()); timevar_pop (TV_CSE); - close_dump_file (DFI_cse, print_rtl, insns); + close_dump_file (DFI_cse, print_rtl_with_bb, insns); } open_dump_file (DFI_addressof, decl); purge_addressof (insns); + if (optimize) + purge_all_dead_edges (0); reg_scan (insns, max_reg_num (), 1); close_dump_file (DFI_addressof, print_rtl, insns); @@ -2804,7 +2807,6 @@ rest_of_compilation (decl) timevar_push (TV_GCSE); open_dump_file (DFI_gcse, decl); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); tem = gcse_main (insns, rtl_dump_file); rebuild_jump_labels (insns); @@ -2813,8 +2815,6 @@ rest_of_compilation (decl) save_cfj = flag_cse_follow_jumps; flag_cse_skip_blocks = flag_cse_follow_jumps = 0; - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); /* If -fexpensive-optimizations, re-run CSE to clean up things done by gcse. */ if (flag_expensive_optimizations) @@ -2822,6 +2822,7 @@ rest_of_compilation (decl) timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + purge_all_dead_edges (0); timevar_pop (TV_CSE); cse_not_expected = !flag_rerun_cse_after_loop; } @@ -2833,11 +2834,8 @@ rest_of_compilation (decl) tem = tem2 = 0; timevar_push (TV_JUMP); rebuild_jump_labels (insns); - delete_trivially_dead_insns (insns, max_reg_num (), 0); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + delete_trivially_dead_insns (insns, max_reg_num (), 1); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); timevar_pop (TV_JUMP); if (flag_expensive_optimizations) @@ -2845,16 +2843,20 @@ rest_of_compilation (decl) timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + purge_all_dead_edges (0); timevar_pop (TV_CSE); } } - close_dump_file (DFI_gcse, print_rtl, insns); + close_dump_file (DFI_gcse, print_rtl_with_bb, insns); timevar_pop (TV_GCSE); ggc_collect (); flag_cse_skip_blocks = save_csb; flag_cse_follow_jumps = save_cfj; +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif } /* Move constant computations out of loops. */ @@ -2863,6 +2865,7 @@ rest_of_compilation (decl) { timevar_push (TV_LOOP); open_dump_file (DFI_loop, decl); + /* CFG is no longer maintained up-to-date. */ free_bb_for_insn (); if (flag_rerun_loop_opt) @@ -2888,62 +2891,98 @@ rest_of_compilation (decl) (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT | (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0)); + /* Loop can create trivially dead instructions. */ + delete_trivially_dead_insns (insns, max_reg_num (), 0); close_dump_file (DFI_loop, print_rtl, insns); timevar_pop (TV_LOOP); ggc_collect (); } + /* Do control and data flow analysis; wrote some of the results to + the dump file. */ + + timevar_push (TV_FLOW); + open_dump_file (DFI_cfg, decl); + + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + + /* It may make more sense to mark constant functions after dead code is + eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs + may insert code making function non-constant, but we still must consider + it as constant, otherwise -fbranch-probabilities will not read data back. + + life_analyzis rarely eliminates modification of external memory. + */ + mark_constant_function (); + + close_dump_file (DFI_cfg, print_rtl_with_bb, insns); + + /* Do branch profiling and static profile estimation passes. */ + if (optimize > 0 || profile_arc_flag || flag_test_coverage + || flag_branch_probabilities) + { + struct loops loops; + + timevar_push (TV_BRANCH_PROB); + open_dump_file (DFI_bp, decl); + if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) + branch_prob (); + + /* Discover and record the loop depth at the head of each basic + block. The loop infrastructure does the real job for us. */ + flow_loops_find (&loops, LOOP_TREE); + + /* Estimate using heuristics if no profiling info is available. */ + if (flag_guess_branch_prob) + estimate_probability (&loops); + + if (rtl_dump_file) + flow_loops_dump (&loops, rtl_dump_file, NULL, 0); + + flow_loops_free (&loops); + close_dump_file (DFI_bp, print_rtl_with_bb, insns); + timevar_pop (TV_BRANCH_PROB); + } + if (optimize > 0) { timevar_push (TV_CSE2); open_dump_file (DFI_cse2, decl); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); if (flag_rerun_cse_after_loop) { - /* Running another jump optimization pass before the second - cse pass sometimes simplifies the RTL enough to allow - 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_push (TV_JUMP); - /* The previous 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 jump work - better and possibly speed up compilation. */ - delete_trivially_dead_insns (insns, max_reg_num (), 0); - reg_scan (insns, max_reg_num (), 0); timevar_push (TV_IFCVT); - - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE); if_convert (0); - timevar_pop(TV_IFCVT); timevar_pop (TV_JUMP); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); reg_scan (insns, max_reg_num (), 0); tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file); + purge_all_dead_edges (0); if (tem) { timevar_push (TV_JUMP); rebuild_jump_labels (insns); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); timevar_pop (TV_JUMP); } } - close_dump_file (DFI_cse2, print_rtl, insns); + close_dump_file (DFI_cse2, print_rtl_with_bb, insns); timevar_pop (TV_CSE2); ggc_collect (); @@ -2951,60 +2990,17 @@ rest_of_compilation (decl) cse_not_expected = 1; + close_dump_file (DFI_life, print_rtl_with_bb, insns); regclass_init (); - /* Do control and data flow analysis; wrote some of the results to - the dump file. */ - - timevar_push (TV_FLOW); - open_dump_file (DFI_cfg, decl); - - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); - cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); check_function_return_warnings (); - /* It may make more sense to mark constant functions after dead code is - eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs - may insert code making function non-constant, but we still must consider - it as constant, otherwise -fbranch-probabilities will not read data back. - - life_analyzis rarely eliminates modification of external memory. - */ - mark_constant_function (); - - close_dump_file (DFI_cfg, print_rtl_with_bb, insns); - - if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) - { - timevar_push (TV_BRANCH_PROB); - open_dump_file (DFI_bp, decl); - - branch_prob (); - - close_dump_file (DFI_bp, print_rtl_with_bb, insns); - timevar_pop (TV_BRANCH_PROB); - } - - open_dump_file (DFI_life, decl); - if (optimize) - { - struct loops loops; - - /* Discover and record the loop depth at the head of each basic - block. The loop infrastructure does the real job for us. */ - flow_loops_find (&loops, LOOP_TREE); - - /* Estimate using heuristics if no profiling info is available. */ - if (flag_guess_branch_prob) - estimate_probability (&loops); - - if (rtl_dump_file) - flow_loops_dump (&loops, rtl_dump_file, NULL, 0); - - flow_loops_free (&loops); - } +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif life_analysis (insns, rtl_dump_file, PROP_FINAL); + if (optimize) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); timevar_pop (TV_FLOW); no_new_pseudos = 1; @@ -3018,12 +3014,14 @@ rest_of_compilation (decl) if (optimize) { + clear_bb_flags (); if (initialize_uninitialized_subregs ()) { /* Insns were inserted, so things might look a bit different. */ insns = get_insns (); - life_analysis (insns, rtl_dump_file, - (PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES)); + update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, + PROP_LOG_LINKS | PROP_REG_INFO + | PROP_DEATH_NOTES); } } @@ -3089,6 +3087,7 @@ rest_of_compilation (decl) regmove_optimize (insns, max_reg_num (), rtl_dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); close_dump_file (DFI_regmove, print_rtl_with_bb, insns); timevar_pop (TV_REGMOVE); @@ -3107,13 +3106,7 @@ rest_of_compilation (decl) timevar_push (TV_MODE_SWITCH); no_new_pseudos = 0; - if (optimize_mode_switching (NULL)) - { - /* We did work, and so had to regenerate global life information. - Take advantage of this and don't re-recompute register life - information below. */ - register_life_up_to_date = 1; - } + optimize_mode_switching (NULL); no_new_pseudos = 1; timevar_pop (TV_MODE_SWITCH); |