This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 *));

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]