/* Top level of GCC compilers (cc1, cc1plus, etc.)
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
}
-/* Run new register allocator. Return TRUE if we must exit
- rest_of_compilation upon return. */
-static bool
-rest_of_handle_new_regalloc (void)
-{
- int failure;
-
- timevar_push (TV_LOCAL_ALLOC);
- open_dump_file (DFI_lreg, current_function_decl);
-
- delete_trivially_dead_insns (get_insns (), max_reg_num ());
- reg_alloc ();
-
- timevar_pop (TV_LOCAL_ALLOC);
- close_dump_file (DFI_lreg, NULL, NULL);
-
- /* XXX clean up the whole mess to bring live info in shape again. */
- timevar_push (TV_GLOBAL_ALLOC);
- open_dump_file (DFI_greg, current_function_decl);
-
- build_insn_chain (get_insns ());
- failure = reload (get_insns (), 0);
-
- timevar_pop (TV_GLOBAL_ALLOC);
-
- ggc_collect ();
-
- if (dump_enabled_p (DFI_greg))
- {
- timevar_push (TV_DUMP);
- dump_global_regs (dump_file);
- timevar_pop (TV_DUMP);
- close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
- }
-
- if (failure)
- return true;
-
- reload_completed = 1;
-
- return false;
-}
-
/* Run old register allocator. Return TRUE if we must exit
rest_of_compilation upon return. */
static bool
rebuild_jump_labels (get_insns ());
purge_all_dead_edges (0);
+ delete_unreachable_blocks ();
timevar_pop (TV_JUMP);
}
dump_flow_info (dump_file);
tracer (0);
cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
}
if (dump_file)
dump_flow_info (dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
if_convert (0);
}
timevar_push (TV_JUMP);
cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
timevar_pop (TV_JUMP);
close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
timevar_pop (TV_WEB);
close_dump_file (DFI_web, print_rtl_with_bb, get_insns ());
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
}
/* Do branch profiling and static profile estimation passes. */
{
/* Alias analysis depends on this information and mark_constant_function
depends on alias analysis. */
- reg_scan (get_insns (), max_reg_num (), 1);
+ reg_scan (get_insns (), max_reg_num ());
mark_constant_function ();
}
open_dump_file (DFI_bypass, current_function_decl);
cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (get_insns (), max_reg_num (), 1);
+ reg_scan (get_insns (), max_reg_num ());
if (bypass_jumps (dump_file))
{
rebuild_jump_labels (get_insns ());
timevar_pop (TV_JUMP);
+ delete_dead_jumptables ();
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
}
#endif
life_analysis (dump_file, PROP_FINAL);
if (optimize)
- cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
- | CLEANUP_LOG_LINKS
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE | CLEANUP_LOG_LINKS
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
if (extra_warnings)
if (optimize)
{
- if (!flag_new_regalloc && initialize_uninitialized_subregs ())
+ if (initialize_uninitialized_subregs ())
{
/* Insns were inserted, and possibly pseudos created, so
things might look a bit different. */
dump_flow_info (dump_file);
timevar_push (TV_CSE);
- reg_scan (get_insns (), max_reg_num (), 1);
+ reg_scan (get_insns (), max_reg_num ());
tem = cse_main (get_insns (), max_reg_num (), dump_file);
if (tem)
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)
+ delete_dead_jumptables ();
+
if (tem || optimize > 1)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
+ delete_dead_jumptables ();
cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP);
}
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
close_dump_file (DFI_cse2, print_rtl_with_bb, get_insns ());
timevar_pop (TV_CSE2);
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
- reg_scan (get_insns (), max_reg_num (), 1);
+ reg_scan (get_insns (), max_reg_num ());
tem2 = cse_main (get_insns (), max_reg_num (), dump_file);
purge_all_dead_edges (0);
delete_trivially_dead_insns (get_insns (), max_reg_num ());
}
/* If gcse or cse altered any jumps, rerun jump optimizations to clean
- things up. Then possibly re-run CSE again. */
- while (tem || tem2)
+ things up. */
+ if (tem || tem2)
{
- tem = tem2 = 0;
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
+ delete_dead_jumptables ();
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
timevar_pop (TV_JUMP);
-
- if (flag_expensive_optimizations)
- {
- timevar_push (TV_CSE);
- reg_scan (get_insns (), max_reg_num (), 1);
- tem2 = cse_main (get_insns (), max_reg_num (), dump_file);
- purge_all_dead_edges (0);
- delete_trivially_dead_insns (get_insns (), max_reg_num ());
- timevar_pop (TV_CSE);
- }
}
close_dump_file (DFI_gcse, print_rtl_with_bb, get_insns ());
int do_prefetch;
timevar_push (TV_LOOP);
- delete_dead_jumptables ();
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
open_dump_file (DFI_loop, current_function_decl);
/* CFG is no longer maintained up-to-date. */
/* The regscan pass is currently necessary as the alias
analysis code depends on this information. */
- reg_scan (get_insns (), max_reg_num (), 1);
+ reg_scan (get_insns (), max_reg_num ());
}
cleanup_barriers ();
loop_optimize (get_insns (), dump_file, do_prefetch);
/* Loop can create trivially dead instructions. */
delete_trivially_dead_insns (get_insns (), max_reg_num ());
- find_basic_blocks (get_insns (), max_reg_num (), dump_file);
+ find_basic_blocks (get_insns ());
close_dump_file (DFI_loop, print_rtl, get_insns ());
timevar_pop (TV_LOOP);
cleanup_cfg (CLEANUP_EXPENSIVE);
delete_trivially_dead_insns (get_insns (), max_reg_num ());
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
if (dump_file)
dump_flow_info (dump_file);
close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
}
}
-
-static void
-rest_of_handle_prologue_epilogue (void)
-{
- if (optimize && !flow2_completed)
- cleanup_cfg (CLEANUP_EXPENSIVE);
-
- /* On some machines, the prologue and epilogue code, or parts thereof,
- can be represented as RTL. Doing so lets us schedule insns between
- it and the rest of the code and also allows delayed branch
- scheduling to operate in the epilogue. */
- thread_prologue_and_epilogue_insns (get_insns ());
- epilogue_completed = 1;
-
- if (optimize && flow2_completed)
- life_analysis (dump_file, PROP_POSTRELOAD);
-}
-
static void
rest_of_handle_stack_adjustments (void)
{
split_all_insns (0);
if (flag_branch_target_load_optimize)
- rest_of_handle_branch_target_load_optimize ();
+ {
+ close_dump_file (DFI_flow2, print_rtl_with_bb, get_insns ());
+ rest_of_handle_branch_target_load_optimize ();
+ open_dump_file (DFI_flow2, current_function_decl);
+ }
- if (!targetm.late_rtl_prologue_epilogue)
- rest_of_handle_prologue_epilogue ();
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ /* On some machines, the prologue and epilogue code, or parts thereof,
+ can be represented as RTL. Doing so lets us schedule insns between
+ it and the rest of the code and also allows delayed branch
+ scheduling to operate in the epilogue. */
+ thread_prologue_and_epilogue_insns (get_insns ());
+ epilogue_completed = 1;
if (optimize)
rest_of_handle_stack_adjustments ();
expected_value_to_br_prob ();
delete_trivially_dead_insns (get_insns (), max_reg_num ());
- reg_scan (get_insns (), max_reg_num (), 0);
+ reg_scan (get_insns (), max_reg_num ());
if (dump_file)
dump_flow_info (dump_file);
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
if (targetm.binds_local_p (current_function_decl))
{
int pref = cfun->preferred_stack_boundary;
- if (cfun->recursive_call_emit
- && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+ if (cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
pref = cfun->stack_alignment_needed;
cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
= pref;
static void
rest_of_compilation (void)
{
- /* Convert from NOTE_INSN_EH_REGION style notes, and do other
- sorts of eh initialization. */
- convert_from_eh_region_ranges ();
-
/* If we're emitting a nested function, make sure its parent gets
emitted as well. Doing otherwise confuses debug info. */
{
&& !user_defined_section_attribute)
rest_of_handle_partition_blocks ();
- if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
+ if (optimize > 0 && flag_regmove)
rest_of_handle_regmove ();
/* Do unconditional splitting before register allocation to allow machine
/* Any of the several passes since flow1 will have munged register
lifetime data a bit. We need it to be up to date for scheduling
(see handling of reg_known_equiv in init_alias_analysis). */
- recompute_reg_usage (get_insns (), !optimize_size);
+ recompute_reg_usage ();
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_modulo_sched)
epilogue thus changing register elimination offsets. */
current_function_is_leaf = leaf_function_p ();
- if (flag_new_regalloc)
- {
- if (rest_of_handle_new_regalloc ())
- goto exit_rest_of_compilation;
- }
- else
- {
- if (rest_of_handle_old_regalloc ())
- goto exit_rest_of_compilation;
- }
+ if (rest_of_handle_old_regalloc ())
+ goto exit_rest_of_compilation;
if (optimize > 0)
rest_of_handle_postreload ();
= optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
#endif
- if (targetm.late_rtl_prologue_epilogue)
- rest_of_handle_prologue_epilogue ();
-
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
rest_of_handle_sched2 ();
compute_alignments ();
+ /* Aggressively duplicate basic blocks ending in computed gotos to the
+ tails of their predecessors, unless we are optimizing for size. */
+ if (flag_expensive_optimizations && !optimize_size)
+ duplicate_computed_gotos ();
+
if (flag_var_tracking)
rest_of_handle_variable_tracking ();