This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC] Toplev.c reorganization
Hello,
> >> > I still like the idea of having all knowledge about passes and
> >> > structures on one place rather than spread around several different
> >> > files; I agree that passes.def stuff got out of my control (now I
> >> > like more an idea to just have a function for each of the passes
> >> > defined in passes.c, which seems more flexible and sufficient for
> >> > the purpose); on the other hand, I would like to retain
> >> > structures.def moreorless as it is.
> >>
> >> Why don't you do a patch that just does the passes.def part, and then
> >> come back to the structures.def stuff? I think that would be easier
> >> to review.
> >
> > OK, here is the first part of reorganization; it just creates driver
> > function for passes (and in few cases, modifies passes to return whether
> > anything has changed).
>
> The passes.[ch] attached to this patch seem to be from the older
> patch...
Yes, sorry; here are the correct ones.
Zdenek
/* passes.c -- definitions of passes of gcc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "timevar.h"
#include "rtl.h"
#include "basic-block.h"
#include "output.h"
#include "except.h"
#include "ssa.h"
#include "flags.h"
#include "insn-config.h"
#include "recog.h"
#include "reload.h"
#include "toplev.h"
#include "loop.h"
#include "cfgloop.h"
#include "function.h"
#include "regs.h"
#include "integrate.h"
#include "ggc.h"
#include "passes.h"
/* This file defines standard interface to passes. There are following
types of functions:
*_driver: a simple invocation of pass, usually called only once from
toplev.c. It does not care about timevars nor dump files.
*_routine_driver: a simple routine that is invoked multiple times
from different places (like cfg_cleanup or dce). It may manipulate
timevars.
*_pass_driver: a composite pass invoked exactly once from toplev.c;
it may manipulate timevars and dump files.
All functions return false if the pass did nothing, true otherwise. */
/* "Routine" passes: */
/* Does various cfg level optimalizations. */
bool
cfg_cleanup_routine_driver (flags)
int flags;
{
bool changed;
timevar_push (TV_CLEANUP_CFG);
changed = cleanup_cfg (flags);
timevar_pop (TV_CLEANUP_CFG);
return changed;
}
/* Rebuilds JUMP_LABEL fields and REG_LABEL notes. */
bool
rebuild_jump_labels_routine_driver ()
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
timevar_pop (TV_JUMP);
return false;
}
/* Deletes sets that are never used. */
bool
trivial_dce_routine_driver ()
{
bool changed;
timevar_push (TV_DELETE_TRIVIALLY_DEAD);
changed = delete_trivially_dead_insns (get_insns (), max_reg_num ());
timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
return changed;
}
/* Dead code ellimination using liveness. */
bool
dce_routine_driver ()
{
bool changed;
changed = update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_DEATH_NOTES
| PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE);
return changed;
}
/* Removes the blocks unreachable from origin from CFG. */
bool
delete_unreachable_blocks_routine_driver ()
{
bool changed;
changed = delete_unreachable_blocks ();
return changed;
}
/* Removes the jump tables that are never referenced. */
bool
delete_dead_jumptables_routine_driver ()
{
bool changed;
changed = delete_dead_jumptables ();
return changed;
}
/* "Driver" passes: */
/* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
bool
lower_prediction_notes_driver ()
{
note_prediction_to_br_prob ();
return true;
}
/* Turns tail recursion into iteration. */
bool
tail_recursion_optimalization_driver ()
{
rtx insn;
cfg_cleanup_routine_driver (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
optimize_sibling_and_tail_recursive_calls ();
/* Recompute the CFG as sibling optimization clobbers it randomly. */
free_bb_for_insn ();
find_exception_handler_labels ();
rebuild_jump_labels_routine_driver ();
find_basic_blocks (get_insns (), max_reg_num (), rtl_dump_file);
/* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION
notes before simplifying cfg and we must do lowering after sibcall
that unhides parts of RTL chain and cleans up the CFG.
Until sibcall is replaced by tree-level optimizer, lets just
sweep away the NOTE_INSN_PREDICTION notes that leaked out. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
delete_insn (insn);
return true;
}
/* Finishes generation of exception handling code. */
bool
finish_eh_generation_driver ()
{
bool changed;
changed = finish_eh_generation ();
return changed;
}
#ifdef SETJMP_VIA_SAVE_AREA
/* Optimize RTL generated by allocate_dynamic_stack_space for
targets where SETJMP_VIA_SAVE_AREA is defined. */
bool
optimize_save_area_alloca_driver ()
{
optimize_save_area_alloca (get_insns ());
return true;
}
#endif
/* Turn NOTE_INSN_EXPECTED_VALUEs into branch predictions. */
bool
lower_expected_value_notes_driver ()
{
expected_value_to_br_prob ();
return true;
}
/* Copy exit tests of loops. */
bool
copy_loop_headers_driver ()
{
bool changed;
changed = copy_loop_headers (get_insns ());
return changed;
}
/* Conditional constant propagation on SSA. */
bool
ssa_ccp_driver ()
{
ssa_const_prop ();
return true;
}
/* Dead code elimination on SSA. */
bool
ssa_dce_driver ()
{
ssa_eliminate_dead_code ();
return true;
}
/* Delete useless null pointer tests. */
bool
delete_null_pointer_checks_driver ()
{
bool changed;
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
changed = delete_null_pointer_checks (get_insns ());
if (changed)
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
return changed;
}
/* Common subexpression elimination. */
bool
cse_driver (after_loop, jumps_changed)
int after_loop;
int *jumps_changed;
{
bool js_changed;
reg_scan (get_insns (), max_reg_num (), 1);
js_changed = cse_main (get_insns (), max_reg_num (), after_loop, rtl_dump_file);
if (js_changed)
rebuild_jump_labels_routine_driver ();
purge_all_dead_edges (0);
trivial_dce_routine_driver ();
if (jumps_changed)
*jumps_changed = js_changed;
return true;
}
/* Global common subexpression elimination. */
bool
gcse_driver (int *jumps_changed)
{
bool js_changed;
js_changed = gcse_main (get_insns (), rtl_dump_file);
if (js_changed)
rebuild_jump_labels_routine_driver ();
trivial_dce_routine_driver ();
if (jumps_changed)
*jumps_changed = js_changed;
return true;
}
/* Moves invariants out of loops and various other loop optimizations. */
bool
old_loop_optimizer_driver (flags)
int flags;
{
loop_optimize (get_insns (), rtl_dump_file, flags);
return true;
}
/* Performs loop unswitching. */
bool
unswitch_loops_driver (loops)
struct loops *loops;
{
unswitch_loops (loops);
return true;
}
/* Jump bypassing and control flow optimizations. */
bool
bypass_jumps_driver ()
{
bool jumps_changed;
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
jumps_changed = bypass_jumps (rtl_dump_file);
if (jumps_changed)
{
rebuild_jump_labels_routine_driver ();
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
trivial_dce_routine_driver ();
}
return true;
}
/* Marks constant function. */
bool
mark_constant_function_driver ()
{
mark_constant_function ();
return false;
}
/* Instruments program and/or analyzes its behavior according to profile. */
bool
branch_prob_driver ()
{
branch_prob ();
if (!profile_arc_flag)
return false;
return true;
}
/* Estimates function profile from its properties. */
bool
profile_estimation_driver (loops)
struct loops *loops;
{
estimate_probability (loops);
return false;
}
/* Various optimizations on simple if conditions. */
bool
if_conversion_driver (life_data_ok)
int life_data_ok;
{
bool changed;
changed = if_convert (life_data_ok);
return changed;
}
/* Tail duplication and superblock formation. */
bool
tracer_driver ()
{
bool changed;
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
changed = tracer ();
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
reg_scan (get_insns (), max_reg_num (), 0);
return changed;
}
/* Computes liveness and depending on flags does a bunch of other unrelated
tasks. */
bool
life_analysis_driver (flags)
int flags;
{
life_analysis (get_insns (), rtl_dump_file, flags);
return true;
}
/* Deletes any insns that copy a register to itself. */
bool
delete_noop_moves_driver ()
{
bool changed;
changed = delete_noop_moves (get_insns ());
return changed;
}
/* Set uninitialized subregs to 0. */
bool
initialize_uninitialized_subregs_driver ()
{
bool changed;
changed = initialize_uninitialized_subregs ();
if (changed)
update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_REG_INFO | PROP_DEATH_NOTES);
return changed;
}
/* Try to combine groups of instructions. */
bool
combine_instructions_driver ()
{
bool jumps_changed;
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_LOG_LINKS);
jumps_changed = combine_instructions (get_insns (), max_reg_num ());
/* Combining insns may have turned an indirect jump into a
direct jump. Rebuid the JUMP_LABEL fields of jumping
instructions. */
if (jumps_changed)
{
rebuild_jump_labels_routine_driver ();
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
}
return true;
}
/* Split all insns in the function. */
bool
split_insns_driver (update_life)
int update_life;
{
bool changed;
changed = split_all_insns (update_life);
return changed;
}
/* Split all insns in the function, without requiring cfg. */
bool
split_insns_noflow_driver ()
{
split_all_insns_noflow ();
return true;
}
/* Peephole 2 pass. */
bool
peephole2_driver ()
{
bool changed;
changed = peephole2_optimize (rtl_dump_file);
return changed;
}
/* Register renaming. */
bool
register_renaming_driver ()
{
regrename_optimize ();
return true;
}
/* Move registers around to reduce number of move instructions needed. */
bool
regmove_driver ()
{
regmove_optimize (get_insns (), max_reg_num (), rtl_dump_file);
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
return true;
}
/* Insert mode switches. */
bool
optimize_mode_switching_driver ()
{
bool changed;
no_new_pseudos = 0;
changed = optimize_mode_switching (NULL);
no_new_pseudos = 1;
return changed;
}
/* Reorder basic blocks. */
bool
reorder_basic_blocks_driver ()
{
bool changed;
changed = reorder_basic_blocks ();
if (changed)
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
return changed;
}
/* Graph coloring based register allocator. */
bool
reg_alloc_driver ()
{
reg_alloc ();
return true;
}
/* Reload pseudo regs into hard regs. */
bool
reload_driver (global, failure)
int global;
int *failure;
{
int fail;
build_insn_chain (get_insns ());
fail = reload (get_insns (), global);
if (failure)
*failure = fail;
return true;
}
/* Compute register class preferences for pseudo-registers. */
bool
regclass_driver ()
{
regclass (get_insns (), max_reg_num (), rtl_dump_file);
return true;
}
/* Allocate registers within a basic block. */
bool
local_alloc_driver ()
{
bool labels_altered;
labels_altered = local_alloc ();
if (labels_altered)
{
rebuild_jump_labels_routine_driver ();
purge_all_dead_edges (0);
}
return true;
}
/* Allocate registers for pseudo-registers that span basic blocks. */
bool
global_alloc_driver (failure)
int *failure;
{
int fail;
fail = global_alloc (rtl_dump_file);
if (failure)
*failure = fail;
return true;
}
/* Call cse / combine like post-reload optimization phases. */
bool
cse_post_reload_driver ()
{
reload_cse_regs (get_insns ());
return true;
}
/* Add prologue and epilogue code represented as RTL. */
bool
add_prologue_and_epilogue_driver ()
{
thread_prologue_and_epilogue_insns (get_insns ());
return true;
}
/* Combine stack adjustments. */
bool
combine_stack_adjustments_driver ()
{
combine_stack_adjustments ();
return true;
}
/* Forward hardreg copy propagation. */
bool
copyprop_hardreg_forward_driver ()
{
bool changed;
changed = copyprop_hardreg_forward ();
return changed;
}
/* Instruction scheduling. */
bool
schedule_insns_driver ()
{
schedule_insns (rtl_dump_file);
return true;
}
/* Convert stack-like registers to flat ones. */
bool
regstack_driver ()
{
reg_to_stack (get_insns (), rtl_dump_file);
return false;
}
/* Compute alignments of labels. */
bool
compute_alignments_driver ()
{
compute_alignments ();
return true;
}
/* Schedule delay slots. */
#ifdef DELAY_SLOTS
bool
dbr_schedule_driver ()
{
dbr_schedule (get_insns (), rtl_dump_file);
return true;
}
#endif
/* Shorten branches. */
bool
shorten_branches_driver ()
{
shorten_branches (get_insns ());
return true;
}
/* "Pass" passes: */
/* Ssa optimizations pass. */
bool
ssa_pass_driver (decl)
tree decl;
{
/* Convert to SSA form. */
timevar_push (TV_TO_SSA);
open_dump_file (DFI_ssa, decl);
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
convert_to_ssa ();
close_dump_file (DFI_ssa, print_rtl_with_bb, get_insns ());
timevar_pop (TV_TO_SSA);
/* Perform sparse conditional constant propagation, if requested. */
if (flag_ssa_ccp)
{
timevar_push (TV_SSA_CCP);
open_dump_file (DFI_ssa_ccp, decl);
ssa_ccp_driver ();
close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ());
timevar_pop (TV_SSA_CCP);
}
/* It would be useful to cleanup the CFG at this point, but block
merging and possibly other transformations might leave a PHI
node in the middle of a basic block, which is a strict no-no. */
/* The SSA implementation uses basic block numbers in its phi
nodes. Thus, changing the control-flow graph or the basic
blocks, e.g., calling find_basic_blocks () or cleanup_cfg (),
may cause problems. */
if (flag_ssa_dce)
{
/* Remove dead code. */
timevar_push (TV_SSA_DCE);
open_dump_file (DFI_ssa_dce, decl);
ssa_dce_driver ();
close_dump_file (DFI_ssa_dce, print_rtl_with_bb, get_insns ());
timevar_pop (TV_SSA_DCE);
}
/* Convert from SSA form. */
timevar_push (TV_FROM_SSA);
open_dump_file (DFI_ussa, decl);
convert_from_ssa ();
/* New registers have been created. Rescan their usage. */
reg_scan (get_insns (), max_reg_num (), 1);
close_dump_file (DFI_ussa, print_rtl_with_bb, get_insns ());
timevar_pop (TV_FROM_SSA);
return true;
}
/* Main cse pass. */
bool
main_cse_pass_driver ()
{
int jumps_changed;
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
timevar_push (TV_CSE);
reg_scan (get_insns (), max_reg_num (), 1);
cse_driver (0, &jumps_changed);
/* 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 (jumps_changed || optimize > 1)
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
{
timevar_push (TV_JUMP);
delete_null_pointer_checks_driver ();
timevar_pop (TV_JUMP);
}
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
renumber_insns (rtl_dump_file);
timevar_pop (TV_CSE);
return true;
}
/* Global common subexpression elimination pass. */
bool
gcse_pass_driver ()
{
int jumps_changed;
int jumps_changed_in_cse;
int save_csb, save_cfj;
timevar_push (TV_GCSE);
gcse_driver (&jumps_changed);
save_csb = flag_cse_skip_blocks;
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
/* If -fexpensive-optimizations, re-run CSE to clean up things done
by gcse. */
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
reg_scan (get_insns (), max_reg_num (), 1);
cse_driver (0, &jumps_changed_in_cse);
timevar_pop (TV_CSE);
cse_not_expected = !flag_rerun_cse_after_loop;
jumps_changed |= jumps_changed_in_cse;
}
/* If gcse or cse altered any jumps, rerun jump optimizations to clean
things up. Then possibly re-run CSE again. */
while (jumps_changed)
{
jumps_changed = 0;
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
if (flag_expensive_optimizations)
{
timevar_push (TV_CSE);
reg_scan (get_insns (), max_reg_num (), 1);
cse_driver (0, &jumps_changed);
timevar_pop (TV_CSE);
}
}
flag_cse_skip_blocks = save_csb;
flag_cse_follow_jumps = save_cfj;
timevar_pop (TV_GCSE);
return true;
}
/* Old loop optimizer pass. */
bool
old_loop_optimizer_pass_driver ()
{
int do_unroll, do_prefetch;
timevar_push (TV_LOOP);
delete_dead_jumptables_routine_driver ();
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
if (flag_rerun_loop_opt)
{
cleanup_barriers ();
/* We only want to perform unrolling once. */
old_loop_optimizer_driver (do_unroll);
do_unroll = 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
better and possibly speed up compilation. */
trivial_dce_routine_driver ();
/* The regscan pass is currently necessary as the alias
analysis code depends on this information. */
reg_scan (get_insns (), max_reg_num (), 1);
}
cleanup_barriers ();
old_loop_optimizer_driver (do_unroll | LOOP_BCT | do_prefetch);
/* Loop can create trivially dead instructions. */
trivial_dce_routine_driver ();
find_basic_blocks (get_insns (), max_reg_num (), rtl_dump_file);
timevar_pop (TV_LOOP);
return true;
}
/* New loop optimizer pass. */
bool
new_loop_optimizer_pass_driver ()
{
struct loops *loops;
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
loops = loop_optimizer_init (rtl_dump_file);
if (loops)
{
/* The optimalizations: */
if (flag_unswitch_loops)
unswitch_loops_driver (loops);
loop_optimizer_finalize (loops, rtl_dump_file);
}
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
trivial_dce_routine_driver ();
reg_scan (get_insns (), max_reg_num (), 0);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
return true;
}
/* If conversion pass. */
bool
first_ifcvt_pass_driver ()
{
if (flag_if_conversion)
{
timevar_push (TV_IFCVT);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
reg_scan (get_insns (), max_reg_num (), 0);
if_conversion_driver (0);
timevar_pop (TV_IFCVT);
}
timevar_push (TV_JUMP);
cfg_cleanup_routine_driver (CLEANUP_EXPENSIVE);
reg_scan (get_insns (), max_reg_num (), 0);
timevar_pop (TV_JUMP);
return true;
}
/* Branch profiling and static profile estimation passes. */
bool
branch_prob_pass_driver ()
{
struct loops loops;
timevar_push (TV_BRANCH_PROB);
if (cfun->arc_profile || flag_branch_probabilities)
branch_prob_driver ();
/* 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);
if (rtl_dump_file)
flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
/* Estimate using heuristics if no profiling info is available. */
if (flag_guess_branch_prob)
profile_estimation_driver (&loops);
flow_loops_free (&loops);
timevar_pop (TV_BRANCH_PROB);
return true;
}
/* Register allocation pass. */
bool
regalloc_pass_driver (decl, failure)
tree decl;
int *failure;
{
if (flag_new_regalloc)
{
timevar_push (TV_LOCAL_ALLOC);
open_dump_file (DFI_lreg, decl);
trivial_dce_routine_driver ();
reg_alloc_driver ();
close_dump_file (DFI_lreg, NULL, NULL);
timevar_pop (TV_LOCAL_ALLOC);
/* XXX clean up the whole mess to bring live info in shape again. */
timevar_push (TV_GLOBAL_ALLOC);
open_dump_file (DFI_greg, decl);
reload_driver (0, failure);
timevar_pop (TV_GLOBAL_ALLOC);
if (rtl_dump_file)
dump_global_regs (rtl_dump_file);
close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
reload_completed = 1;
}
else
{
timevar_push (TV_LOCAL_ALLOC);
open_dump_file (DFI_lreg, decl);
/* Allocate the reg_renumber array. */
allocate_reg_info (max_regno, FALSE, TRUE);
/* And the reg_equiv_memory_loc array. */
reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
allocate_initial_values (reg_equiv_memory_loc);
regclass_driver ();
local_alloc_driver ();
timevar_pop (TV_LOCAL_ALLOC);
if (rtl_dump_file)
{
dump_flow_info (rtl_dump_file);
dump_local_alloc (rtl_dump_file);
}
close_dump_file (DFI_lreg, print_rtl_with_bb, get_insns ());
ggc_collect ();
timevar_push (TV_GLOBAL_ALLOC);
open_dump_file (DFI_greg, decl);
/* If optimizing, allocate remaining pseudo-regs. Do the reload
pass fixing up any insns that are invalid. */
if (optimize)
global_alloc_driver (failure);
else
reload_driver (0, failure);
timevar_pop (TV_GLOBAL_ALLOC);
if (rtl_dump_file)
dump_global_regs (rtl_dump_file);
close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
}
return true;
}
/* passes.h -- definitions of passes of gcc.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
/* Routines. */
bool cfg_cleanup_routine_driver PARAMS ((int));
bool rebuild_jump_labels_routine_driver PARAMS ((void));
bool trivial_dce_routine_driver PARAMS ((void));
bool dce_routine_driver PARAMS ((void));
bool delete_unreachable_blocks_routine_driver PARAMS ((void));
bool delete_dead_jumptables_routine_driver PARAMS ((void));
/* Drivers. */
bool lower_prediction_notes_driver PARAMS ((void));
bool tail_recursion_optimalization_driver PARAMS ((void));
bool finish_eh_generation_driver PARAMS ((void));
bool optimize_save_area_alloca_driver PARAMS ((void));
bool lower_expected_value_notes_driver PARAMS ((void));
bool copy_loop_headers_driver PARAMS ((void));
bool ssa_ccp_driver PARAMS ((void));
bool ssa_dce_driver PARAMS ((void));
bool delete_null_pointer_checks_driver PARAMS ((void));
bool cse_driver PARAMS ((int, int *));
bool gcse_driver PARAMS ((int *));
bool old_loop_optimizer_driver PARAMS ((int));
bool unswitch_loops_driver PARAMS ((struct loops *));
bool bypass_jumps_driver PARAMS ((void));
bool mark_constant_function_driver PARAMS ((void));
bool branch_prob_driver PARAMS ((void));
bool profile_estimation_driver PARAMS ((struct loops *));
bool vpt_driver PARAMS ((void));
bool if_conversion_driver PARAMS ((int));
bool tracer_driver PARAMS ((void));
bool unswitch_loops_driver PARAMS ((struct loops *));
bool unroll_and_peel_loops_driver PARAMS ((void));
bool webizer_driver PARAMS ((void));
bool life_analysis_driver PARAMS ((int));
bool delete_noop_moves_driver PARAMS ((void));
bool initialize_uninitialized_subregs_driver PARAMS ((void));
bool combine_instructions_driver PARAMS ((void));
bool ebb_scheduler_driver PARAMS ((void));
bool split_insns_driver PARAMS ((int));
bool split_insns_noflow_driver PARAMS ((void));
bool peephole2_driver PARAMS ((void));
bool register_renaming_driver PARAMS ((void));
bool regmove_driver PARAMS ((void));
bool optimize_mode_switching_driver PARAMS ((void));
bool reorder_basic_blocks_driver PARAMS ((void));
bool reg_alloc_driver PARAMS ((void));
bool reload_driver PARAMS ((int, int *));
bool regclass_driver PARAMS ((void));
bool local_alloc_driver PARAMS ((void));
bool global_alloc_driver PARAMS ((int *));
bool cse_post_reload_driver PARAMS ((void));
bool add_prologue_and_epilogue_driver PARAMS ((void));
bool combine_stack_adjustments_driver PARAMS ((void));
bool copyprop_hardreg_forward_driver PARAMS ((void));
bool schedule_insns_driver PARAMS ((void));
bool regstack_driver PARAMS ((void));
bool compute_alignments_driver PARAMS ((void));
bool dbr_schedule_driver PARAMS ((void));
bool shorten_branches_driver PARAMS ((void));
/* Passes. */
bool ssa_pass_driver PARAMS ((tree));
bool main_cse_pass_driver PARAMS ((void));
bool gcse_pass_driver PARAMS ((void));
bool old_loop_optimizer_pass_driver PARAMS ((void));
bool new_loop_optimizer_pass_driver PARAMS ((void));
bool first_ifcvt_pass_driver PARAMS ((void));
bool branch_prob_pass_driver PARAMS ((void));
bool regalloc_pass_driver PARAMS ((tree, int *));