-
/* Top level of GNU C compiler
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
extern int size_directive_output;
extern tree last_assemble_variable_decl;
+extern void reg_alloc PARAMS ((void));
+
static void general_init PARAMS ((char *));
-static void parse_options_and_default_flags PARAMS ((int, char **));
-static void do_compile PARAMS ((void));
+static bool parse_options_and_default_flags PARAMS ((int, char **));
+static void do_compile PARAMS ((int));
static void process_options PARAMS ((void));
-static void lang_independent_init PARAMS ((void));
+static void lang_independent_init PARAMS ((int));
static int lang_dependent_init PARAMS ((const char *));
static void init_asm_output PARAMS ((const char *));
static void finalize PARAMS ((void));
extern int target_flags;
+/* A mask of target_flags that includes bit X if X was set or cleared
+ on the command line. */
+
+int target_flags_explicit;
+
/* Debug hooks - dependent upon command line options. */
const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
one, unconditionally renumber instruction UIDs. */
int flag_renumber_insns = 1;
+/* If nonzero, use the graph coloring register allocator. */
+int flag_new_regalloc = 0;
+
/* Nonzero if we perform superblock formation. */
int flag_tracer = 0;
N_("Report on permanent memory allocation at end of run") },
{ "trapv", &flag_trapv, 1,
N_("Trap for signed overflow in addition / subtraction / multiplication") },
+ { "new-ra", &flag_new_regalloc, 1,
+ N_("Use graph coloring register allocation.") },
};
/* Table of language-specific options. */
enabled by default. */
{ "-ansi",
- N_("Compile just for ISO C89") },
+ N_("Compile just for ISO C90") },
{ "-std= ",
N_("Determine language standard") },
-ffast-math and -fno-fast-math imply. */
void
-set_fast_math_flags (int set)
+set_fast_math_flags (set)
+ int set;
{
flag_trapping_math = !set;
flag_unsafe_math_optimizations = set;
free_bb_for_insn ();
copy_loop_headers (insns);
purge_line_number_notes (insns);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
timevar_pop (TV_JUMP);
close_dump_file (DFI_jump, print_rtl, insns);
timevar_push (TV_TO_SSA);
open_dump_file (DFI_ssa, decl);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
convert_to_ssa ();
timevar_pop (TV_FROM_SSA);
ggc_collect ();
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
}
timevar_push (TV_JUMP);
+ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP: 0);
- if (flag_delete_null_pointer_checks || flag_if_conversion)
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks)
{
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);
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- delete_null_pointer_checks (insns);
+ if (delete_null_pointer_checks (insns))
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
close_dump_file (DFI_null, print_rtl_with_bb, insns);
}
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 ();
timevar_pop (TV_JUMP);
close_dump_file (DFI_jump, print_rtl_with_bb, insns);
if (tem || optimize > 1)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks || flag_thread_jumps)
+ if (flag_delete_null_pointer_checks)
{
timevar_push (TV_JUMP);
- if (flag_delete_null_pointer_checks)
- delete_null_pointer_checks (insns);
- /* CFG is no longer maintained up-to-date. */
+ if (delete_null_pointer_checks (insns))
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
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 ();
timevar_pop (TV_CSE);
close_dump_file (DFI_cse, print_rtl_with_bb, insns);
timevar_push (TV_GCSE);
open_dump_file (DFI_gcse, decl);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
tem = gcse_main (insns, rtl_dump_file);
rebuild_jump_labels (insns);
delete_trivially_dead_insns (insns, max_reg_num ());
if (optimize > 0 && flag_loop_optimize)
{
+ int do_unroll, do_prefetch;
+
timevar_push (TV_LOOP);
delete_dead_jumptables ();
cleanup_cfg (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. */
- loop_optimize (insns, rtl_dump_file, LOOP_FIRST_PASS);
+ loop_optimize (insns, rtl_dump_file, do_unroll);
+ do_unroll = 0;
/* The first call to loop_optimize makes some instructions
trivially dead. We delete those instructions now in the
reg_scan (insns, max_reg_num (), 1);
}
cleanup_barriers ();
- loop_optimize (insns, rtl_dump_file,
- (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT
- | (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0));
+ loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch);
/* Loop can create trivially dead instructions. */
delete_trivially_dead_insns (insns, max_reg_num ());
close_dump_file (DFI_loop, print_rtl, insns);
timevar_pop (TV_LOOP);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
ggc_collect ();
}
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)
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)
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)
{
clear_bb_flags ();
- if (initialize_uninitialized_subregs ())
+ if (!flag_new_regalloc && initialize_uninitialized_subregs ())
{
/* Insns were inserted, so things might look a bit different. */
insns = get_insns ();
if (! register_life_up_to_date)
recompute_reg_usage (insns, ! optimize_size);
- /* Allocate the reg_renumber array. */
- allocate_reg_info (max_regno, FALSE, TRUE);
+ if (flag_new_regalloc)
+ {
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ reg_alloc ();
- /* And the reg_equiv_memory_loc array. */
- reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
+ timevar_pop (TV_LOCAL_ALLOC);
+ if (dump_file[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
- allocate_initial_values (reg_equiv_memory_loc);
+ close_dump_file (DFI_lreg, NULL, NULL);
+ timevar_pop (TV_DUMP);
+ }
- regclass (insns, max_reg_num (), rtl_dump_file);
- rebuild_label_notes_after_reload = 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);
- timevar_pop (TV_LOCAL_ALLOC);
+ build_insn_chain (insns);
+ failure = reload (insns, 0);
- if (dump_file[DFI_lreg].enabled)
- {
- timevar_push (TV_DUMP);
+ timevar_pop (TV_GLOBAL_ALLOC);
- dump_flow_info (rtl_dump_file);
- dump_local_alloc (rtl_dump_file);
+ if (dump_file[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
- close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
- timevar_pop (TV_DUMP);
+ dump_global_regs (rtl_dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ if (failure)
+ goto exit_rest_of_compilation;
+ reload_completed = 1;
+ rebuild_label_notes_after_reload = 0;
}
+ else
+ {
+ /* Allocate the reg_renumber array. */
+ allocate_reg_info (max_regno, FALSE, TRUE);
- ggc_collect ();
+ /* And the reg_equiv_memory_loc array. */
+ reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
- timevar_push (TV_GLOBAL_ALLOC);
- open_dump_file (DFI_greg, decl);
+ allocate_initial_values (reg_equiv_memory_loc);
- /* If optimizing, allocate remaining pseudo-regs. Do the reload
- pass fixing up any insns that are invalid. */
+ regclass (insns, max_reg_num (), rtl_dump_file);
+ rebuild_label_notes_after_reload = local_alloc ();
- if (optimize)
- failure = global_alloc (rtl_dump_file);
- else
- {
- build_insn_chain (insns);
- failure = reload (insns, 0);
- }
+ timevar_pop (TV_LOCAL_ALLOC);
- timevar_pop (TV_GLOBAL_ALLOC);
+ if (dump_file[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
- if (dump_file[DFI_greg].enabled)
- {
- timevar_push (TV_DUMP);
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
- dump_global_regs (rtl_dump_file);
+ close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
- close_dump_file (DFI_greg, print_rtl_with_bb, insns);
- timevar_pop (TV_DUMP);
- }
+ ggc_collect ();
- if (failure)
- goto exit_rest_of_compilation;
+ 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)
+ failure = global_alloc (rtl_dump_file);
+ else
+ {
+ build_insn_chain (insns);
+ failure = reload (insns, 0);
+ }
+
+ timevar_pop (TV_GLOBAL_ALLOC);
+
+ if (dump_file[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (rtl_dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ if (failure)
+ goto exit_rest_of_compilation;
+ }
ggc_collect ();
target_flags &= ~-target_switches[j].value;
else
target_flags |= target_switches[j].value;
+ if (name[0] != 0)
+ {
+ if (target_switches[j].value < 0)
+ target_flags_explicit |= -target_switches[j].value;
+ else
+ target_flags_explicit |= target_switches[j].value;
+ }
valid_target_option = 1;
}
xmalloc_set_program_name (progname);
+ hex_init ();
+
gcc_init_libintl ();
/* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
/* Parse command line options and set default flag values, called
after language-independent option-independent initialization. Do
minimal options processing. Outputting diagnostics is OK, but GC
- and identifier hashtables etc. are not initialized yet. */
-static void
+ and identifier hashtables etc. are not initialized yet.
+
+ Return non-zero to suppress compiler back end initialization. */
+static bool
parse_options_and_default_flags (argc, argv)
int argc;
char **argv;
/* All command line options have been parsed; allow the front end to
perform consistency checks, etc. */
- (*lang_hooks.post_options) ();
+ return (*lang_hooks.post_options) ();
}
\f
/* Process the options that have been parsed. */
/* Language-independent initialization, before language-dependent
initialization. */
static void
-lang_independent_init ()
+lang_independent_init (no_backend)
+ int no_backend;
{
/* Initialize the garbage-collector, and string pools. */
init_ggc ();
init_stringpool ();
init_obstacks ();
+ if (no_backend)
+ return;
+
+ /* init_emit_once uses reg_raw_mode and therefore must be called
+ after init_regs which initialized reg_raw_mode. */
+ init_regs ();
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
#ifdef VMS_DEBUGGING_INFO
#endif
|| flag_test_coverage
|| warn_notreached);
- init_regs ();
+ init_fake_stack_mems ();
init_alias_once ();
init_loop ();
init_reload ();
front end is initialized. */
init_eh ();
init_optabs ();
+
+ /* The following initialization functions need to generate rtl, so
+ provide a dummy function context for them. */
+ init_dummy_function_start ();
init_expr_once ();
+ expand_dummy_function_end ();
/* Put an entry on the input file stack for the main input file. */
push_srcloc (input_filename, 0);
\f
/* Initialize the compiler, and compile the input file. */
static void
-do_compile ()
+do_compile (no_backend)
+ int no_backend;
{
/* The bulk of command line switch processing. */
process_options ();
timevar_start (TV_TOTAL);
/* Language-independent initialization. Also sets up GC, identifier
- hashes etc. */
- lang_independent_init ();
+ hashes etc., and the back-end if requested. */
+ lang_independent_init (no_backend);
/* Language-dependent initialization. Returns true on success. */
if (lang_dependent_init (filename))
int argc;
char **argv;
{
- hex_init ();
+ bool no_backend;
/* Initialization of GCC's environment, and diagnostics. */
general_init (argv[0]);
/* Parse the options and do minimal processing; basically just
enough to default flags appropriately. */
- parse_options_and_default_flags (argc, argv);
+ no_backend = parse_options_and_default_flags (argc, argv);
/* Exit early if we can (e.g. -help). */
if (!errorcount && !exit_after_options)
- do_compile ();
+ do_compile (no_backend);
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);