/* Top level of GNU C compiler
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
#include "flags.h"
#include "insn-attr.h"
#include "insn-config.h"
+#include "insn-flags.h"
#include "hard-reg-set.h"
#include "recog.h"
#include "output.h"
#define fopen vms_fopen
#endif /* VMS */
-#ifndef DEFAULT_GDB_EXTENSIONS
-#define DEFAULT_GDB_EXTENSIONS 1
-#endif
-
-/* If more than one debugging type is supported, you must define
- PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way.
-
- This is one long line cause VAXC can't handle a \-newline. */
-#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
-#ifndef PREFERRED_DEBUGGING_TYPE
-You Lose! You must define PREFERRED_DEBUGGING_TYPE!
-#endif /* no PREFERRED_DEBUGGING_TYPE */
-#else /* Only one debugging format supported. Define PREFERRED_DEBUGGING_TYPE
- so the following code needn't care. */
-#ifdef DBX_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-#endif
-#ifdef SDB_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-#endif
-#ifdef XCOFF_DEBUGGING_INFO
-#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
-#endif
-#endif /* More than one debugger format enabled. */
-
-/* If still not defined, must have been because no debugging formats
- are supported. */
-#ifndef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
-#endif
-
-#if defined (HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON
-extern char **environ;
-#endif
-
/* Carry information from ASM_DECLARE_OBJECT_NAME
to ASM_FINISH_DECLARE_OBJECT. */
extern int size_directive_output;
extern tree last_assemble_variable_decl;
+static void general_init PARAMS ((char *));
+static void parse_options_and_default_flags PARAMS ((int, char **));
+static void do_compile PARAMS ((void));
+static void process_options PARAMS ((void));
+static void lang_independent_init PARAMS ((void));
+static int lang_dependent_init PARAMS ((const char *));
+static void init_asm_output PARAMS ((const char *));
+static void finalize PARAMS ((void));
+
static void set_target_switch PARAMS ((const char *));
static const char *decl_name PARAMS ((tree, int));
static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void set_float_handler PARAMS ((jmp_buf));
-static void compile_file PARAMS ((const char *));
+static void compile_file PARAMS ((void));
static void display_help PARAMS ((void));
static void display_target_options PARAMS ((void));
const char *dump_base_name;
+/* Format to use to print dumpfile index value */
+#ifndef DUMPFILE_FORMAT
+#define DUMPFILE_FORMAT ".%02d."
+#endif
+
/* Bit flags that specify the machine subtype we are compiling for.
Bits are tested using macros TARGET_... defined in the tm.h file
and set by `-m...' switches. Must be defined in rtlanal.c. */
/* Debug hooks - dependent upon command line options. */
-struct gcc_debug_hooks *debug_hooks;
+struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
/* Describes a dump file. */
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,
Remaining -d letters:
- " o q u "
+ " o q "
" H JK OPQ TUV YZ"
*/
-struct dump_file_info dump_file[DFI_MAX] =
+static struct dump_file_info dump_file[DFI_MAX] =
{
{ "rtl", 'r', 0, 0, 0 },
{ "sibling", 'i', 0, 0, 0 },
{ "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 },
lang_expand_expr_t lang_expand_expr = 0;
-tree (*lang_expand_constant) PARAMS ((tree)) = 0;
-
/* Pointer to function to finish handling an incomplete decl at the
end of compilation. */
int profile_flag = 0;
-/* Nonzero if generating code to do profiling on a line-by-line basis. */
-
-int profile_block_flag;
-
/* Nonzero if generating code to profile program flow graph arcs. */
int profile_arc_flag = 0;
/* Nonzero if registers should be renamed. */
int flag_rename_registers = 0;
+int flag_cprop_registers = 0;
/* Nonzero for -pedantic switch: warn about anything
that standard spec forbids. */
int flag_unroll_all_loops;
+/* Nonzero enables prefetch optimizations for arrays in loops. */
+
+int flag_prefetch_loop_arrays;
+
/* Nonzero forces all invariant computations in loops to be moved
outside the loop. */
int flag_gnu_linker = 1;
#endif
+/* Nonzero means put zero initialized data in the bss section. */
+int flag_zero_initialized_in_bss = 1;
+
/* Enable SSA. */
int flag_ssa = 0;
the support provided depends on the backend. */
rtx stack_limit_rtx;
-/* -fcheck-memory-usage causes extra code to be generated in order to check
- memory accesses. This is used by a detector of bad memory accesses such
- as Checker. */
-int flag_check_memory_usage = 0;
-
-/* -fprefix-function-name causes function name to be prefixed. This
- can be used with -fcheck-memory-usage to isolate code compiled with
- -fcheck-memory-usage. */
-int flag_prefix_function_name = 0;
-
/* 0 if pointer arguments may alias each other. True in C.
1 if pointer arguments may not alias each other but may alias
global variables.
int align_loops;
int align_loops_log;
+int align_loops_max_skip;
int align_jumps;
int align_jumps_log;
+int align_jumps_max_skip;
int align_labels;
int align_labels_log;
+int align_labels_max_skip;
int align_functions;
int align_functions_log;
typedef struct
{
- const char *string;
- int *variable;
- int on_value;
- const char *description;
+ const char *const string;
+ int *const variable;
+ const int on_value;
+ const char *const description;
}
lang_independent_options;
if `-fSTRING' is seen as an option.
(If `-fno-STRING' is seen as an option, the opposite value is stored.) */
-lang_independent_options f_options[] =
+static const lang_independent_options f_options[] =
{
{"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
N_("Perform DWARF2 duplicate elimination") },
{"cse-skip-blocks", &flag_cse_skip_blocks, 1,
N_("When running CSE, follow conditional jumps") },
{"expensive-optimizations", &flag_expensive_optimizations, 1,
- N_("Perform a number of minor, expensive optimisations") },
+ N_("Perform a number of minor, expensive optimizations") },
{"thread-jumps", &flag_thread_jumps, 1,
- N_("Perform jump threading optimisations") },
+ N_("Perform jump threading optimizations") },
{"strength-reduce", &flag_strength_reduce, 1,
- N_("Perform strength reduction optimisations") },
+ N_("Perform strength reduction optimizations") },
{"unroll-loops", &flag_unroll_loops, 1,
N_("Perform loop unrolling when iteration count is known") },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
N_("Perform loop unrolling for all loops") },
+ {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
+ N_("Generate prefetch instructions, if available, for arrays in loops") },
{"move-all-movables", &flag_move_all_movables, 1,
N_("Force all loop invariant computations out of loops") },
{"reduce-all-givs", &flag_reduce_all_givs, 1,
{"writable-strings", &flag_writable_strings, 1,
N_("Store strings in writable data section") },
{"peephole", &flag_no_peephole, 0,
- N_("Enable machine specific peephole optimisations") },
+ N_("Enable machine specific peephole optimizations") },
{"force-mem", &flag_force_mem, 1,
N_("Copy memory operands into registers before using") },
{"force-addr", &flag_force_addr, 1,
{"gcse-sm", &flag_gcse_sm, 1,
N_("Perform store motion after global subexpression elimination") },
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
- N_("Run CSE pass after loop optimisations") },
+ N_("Run CSE pass after loop optimizations") },
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
- N_("Run the loop optimiser twice") },
+ N_("Run the loop optimizer twice") },
{"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1,
N_("Delete useless null pointer checks") },
{"pretend-float", &flag_pretend_float, 1,
N_("Reorder basic blocks to improve code placement") },
{"rename-registers", &flag_rename_registers, 1,
N_("Do the register renaming optimization pass") },
+ {"cprop-registers", &flag_cprop_registers, 1,
+ N_("Do the register copy-propagation optimization pass") },
{"common", &flag_no_common, 0,
N_("Do not put uninitialized globals in the common section") },
{"inhibit-size-directive", &flag_inhibit_size_directive, 1,
{"verbose-asm", &flag_verbose_asm, 1,
N_("Add extra commentry to assembler output") },
{"gnu-linker", &flag_gnu_linker, 1,
- N_("Output GNU ld formatted global initialisers") },
+ N_("Output GNU ld formatted global initializers") },
{"regmove", &flag_regmove, 1,
- N_("Enables a register move optimisation") },
+ N_("Enables a register move optimization") },
{"optimize-register-move", &flag_regmove, 1,
N_("Do the full regmove optimization pass") },
{"pack-struct", &flag_pack_struct, 1,
N_("Attempt to merge identical constants accross compilation units") },
{"merge-all-constants", &flag_merge_constants, 2,
N_("Attempt to merge identical constants and constant variables") },
- {"check-memory-usage", &flag_check_memory_usage, 1,
- N_("Generate code to check every memory access") },
- {"prefix-function-name", &flag_prefix_function_name, 1,
- N_("Add a prefix to all function names") },
{"dump-unnumbered", &flag_dump_unnumbered, 1,
N_("Suppress output of instruction numbers and line number notes in debugging dumps") },
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
N_("Instrument function entry/exit with profiling calls") },
+ {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1,
+ N_("Put zero initialized data in the bss section") },
{"ssa", &flag_ssa, 1,
N_("Enable SSA optimizations") },
{"ssa-ccp", &flag_ssa_ccp, 1,
- N_("Enable SSA conditonal constant propagation") },
+ N_("Enable SSA conditional constant propagation") },
{"ssa-dce", &flag_ssa_dce, 1,
N_("Enable aggressive SSA dead code elimination") },
{"leading-underscore", &flag_leading_underscore, 1,
{"mem-report", &mem_report, 1,
N_("Report on permanent memory allocation at end of run") },
{ "trapv", &flag_trapv, 1,
- N_("Trap for signed overflow in addition / subtraction / multiplication.") },
+ N_("Trap for signed overflow in addition / subtraction / multiplication") },
};
/* Table of language-specific options. */
{ "-ansi",
N_("Compile just for ISO C89") },
- { "-fallow-single-precision",
- N_("Do not promote floats to double if using -traditional") },
{ "-std= ",
N_("Determine language standard") },
{ "-fsigned-bitfields", "" },
{ "-funsigned-bitfields",
- N_("Make bitfields by unsigned by default") },
+ N_("Make bit-fields by unsigned by default") },
{ "-fno-signed-bitfields", "" },
{ "-fno-unsigned-bitfields","" },
{ "-fsigned-char",
{ "-fno-signed-char", "" },
{ "-fno-unsigned-char", "" },
- { "-ftraditional", "" },
- { "-traditional",
- N_("Attempt to support traditional K&R style C") },
- { "-fnotraditional", "" },
- { "-fno-traditional", "" },
-
{ "-fasm", "" },
{ "-fno-asm",
- N_("Do not recognise the 'asm' keyword") },
+ N_("Do not recognize the 'asm' keyword") },
{ "-fbuiltin", "" },
{ "-fno-builtin",
- N_("Do not recognise any built in functions") },
+ N_("Do not recognize any built in functions") },
{ "-fhosted",
N_("Assume normal C execution environment") },
{ "-fno-hosted", "" },
N_("Warn about suspicious declarations of main") },
{ "-Wno-main", "" },
{ "-Wmissing-braces",
- N_("Warn about possibly missing braces around initialisers") },
+ N_("Warn about possibly missing braces around initializers") },
{ "-Wno-missing-braces", "" },
{ "-Wmissing-declarations",
N_("Warn about global funcs without previous declarations") },
N_("Warn about non-prototyped function decls") },
{ "-Wno-strict-prototypes", "" },
{ "-Wtraditional",
- N_("Warn about constructs whose meaning change in ISO C") },
+ N_("Warn about constructs whose meanings change in ISO C") },
{ "-Wno-traditional", "" },
{ "-Wtrigraphs",
N_("Warn when trigraphs are encountered") },
int warn_unused_variable;
int warn_unused_value;
-void
-set_Wunused (setting)
- int setting;
-{
- warn_unused_function = setting;
- warn_unused_label = setting;
- /* Unused function parameter warnings are reported when either ``-W
- -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate
- -Wunused by setting WARN_UNUSED_PARAMETER to -1. */
- if (!setting)
- warn_unused_parameter = 0;
- else if (!warn_unused_parameter)
- warn_unused_parameter = -1;
- warn_unused_variable = setting;
- warn_unused_value = setting;
-}
-
/* Nonzero to warn about code which is never reached. */
int warn_notreached;
int warn_missing_noreturn;
+/* Nonzero means warn about uses of __attribute__((deprecated))
+ declarations. */
+
+int warn_deprecated_decl = 1;
+
/* Likewise for -W. */
-lang_independent_options W_options[] =
+static const lang_independent_options W_options[] =
{
{"unused-function", &warn_unused_function, 1,
N_("Warn when a function is unused") },
N_("Warn when padding is required to align struct members") },
{"disabled-optimization", &warn_disabled_optimization, 1,
N_("Warn when an optimization pass is disabled") },
+ {"deprecated-declarations", &warn_deprecated_decl, 1,
+ N_("Warn about uses of __attribute__((deprecated)) declarations") },
{"missing-noreturn", &warn_missing_noreturn, 1,
N_("Warn about functions which might be candidates for attribute noreturn") }
};
+void
+set_Wunused (setting)
+ int setting;
+{
+ warn_unused_function = setting;
+ warn_unused_label = setting;
+ /* Unused function parameter warnings are reported when either ``-W
+ -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate
+ -Wunused by setting WARN_UNUSED_PARAMETER to -1. */
+ if (!setting)
+ warn_unused_parameter = 0;
+ else if (!warn_unused_parameter)
+ warn_unused_parameter = -1;
+ warn_unused_variable = setting;
+ warn_unused_value = setting;
+}
+
/* The following routines are useful in setting all the flags that
-ffast-math and -fno-fast-math imply. */
if (*endp != 0)
{
if (pname != 0)
- error ("Invalid option `%s'", pname);
+ error ("invalid option `%s'", pname);
return defval;
}
int
do_float_handler (fn, data)
- void (*fn) PARAMS ((PTR));
- PTR data;
+ void (*fn) PARAMS ((PTR));
+ PTR data;
{
jmp_buf buf;
crash_signal (signo)
int signo;
{
- internal_error ("Internal error: %s", strsignal (signo));
+ internal_error ("internal error: %s", strsignal (signo));
}
/* Strip off a legitimate source ending from the input string NAME of
putc ('\"', asm_file);
while ((c = *string++) != 0)
{
- if (c == '\"' || c == '\\')
- putc ('\\', asm_file);
- putc (c, asm_file);
+ if (ISPRINT (c))
+ {
+ if (c == '\"' || c == '\\')
+ putc ('\\', asm_file);
+ putc (c, asm_file);
+ }
+ else
+ fprintf (asm_file, "\\%03o", c);
}
putc ('\"', asm_file);
#endif
if (rtl_dump_file != NULL)
fclose (rtl_dump_file);
- sprintf (seq, ".%02d.", index);
+ sprintf (seq, DUMPFILE_FORMAT, index);
if (! dump_file[index].initialized)
{
char seq[16];
char *suffix;
- sprintf (seq, ".%02d.", index);
+ sprintf (seq, DUMPFILE_FORMAT, index);
suffix = concat (seq, dump_file[index].extension, NULL);
print_rtl_graph_with_bb (dump_base_name, suffix, insns);
free (suffix);
lineno = input_file_stack->line;
}
-/* Compile an entire translation unit, whose primary source file is
- named NAME. Write a file of assembly output and various debugging
- dumps. */
+/* Compile an entire translation unit. Write a file of assembly
+ output and various debugging dumps. */
static void
-compile_file (name)
- const char *name;
+compile_file ()
{
tree globals;
- int name_specified = name != 0;
-
- if (dump_base_name == 0)
- dump_base_name = name ? name : "gccdump";
-
- if (! quiet_flag)
- time_report = 1;
-
- /* Start timing total execution time. */
-
- init_timevar ();
- timevar_start (TV_TOTAL);
-
- /* Open assembly code output file. Do this even if -fsyntax-only is on,
- because then the driver will have provided the name of a temporary
- file or bit bucket for us. */
-
- if (! name_specified && asm_file_name == 0)
- asm_out_file = stdout;
- else
- {
- if (asm_file_name == 0)
- {
- int len = strlen (dump_base_name);
- char *dumpname = (char *) xmalloc (len + 6);
- memcpy (dumpname, dump_base_name, len + 1);
- strip_off_ending (dumpname, len);
- strcat (dumpname, ".s");
- asm_file_name = dumpname;
- }
- if (!strcmp (asm_file_name, "-"))
- asm_out_file = stdout;
- else
- asm_out_file = fopen (asm_file_name, "w");
- if (asm_out_file == 0)
- fatal_io_error ("can't open %s for writing", asm_file_name);
- }
-
- /* Initialize data in various passes. */
-
- init_obstacks ();
- name = init_parse (name);
- init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
- || debug_info_level == DINFO_LEVEL_VERBOSE
- || flag_test_coverage
- || warn_notreached);
- init_regs ();
- init_alias_once ();
- init_decl_processing ();
- init_eh ();
- init_optabs ();
- init_stmt ();
- init_loop ();
- init_reload ();
- init_function_once ();
- init_stor_layout_once ();
- init_varasm_once ();
- init_EXPR_INSN_LIST_cache ();
-
- /* The following initialization functions need to generate rtl, so
- provide a dummy function context for them. */
- init_dummy_function_start ();
- init_expmed ();
- init_expr_once ();
- if (flag_caller_saves)
- init_caller_save ();
- expand_dummy_function_end ();
-
- /* If auxiliary info generation is desired, open the output file.
- This goes in the same directory as the source file--unlike
- all the other output files. */
- if (flag_gen_aux_info)
- {
- aux_info_file = fopen (aux_info_file_name, "w");
- if (aux_info_file == 0)
- fatal_io_error ("can't open %s", aux_info_file_name);
- }
-
-#ifdef IO_BUFFER_SIZE
- setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
- _IOFBF, IO_BUFFER_SIZE);
-#endif
-
- if (name != 0)
- name = ggc_strdup (name);
-
- input_filename = name;
-
- /* Put an entry on the input file stack for the main input file. */
- push_srcloc (input_filename, 0);
-
- /* Perform language-specific initialization.
- This may set main_input_filename. */
- (*lang_hooks.init) ();
-
- /* If the input doesn't start with a #line, use the input name
- as the official input file name. */
- if (main_input_filename == 0)
- main_input_filename = name;
-
- if (flag_syntax_only)
- {
- write_symbols = NO_DEBUG;
- profile_flag = 0;
- profile_block_flag = 0;
- }
- else
- {
-#ifdef ASM_FILE_START
- ASM_FILE_START (asm_out_file);
-#endif
-
-#ifdef ASM_COMMENT_START
- if (flag_verbose_asm)
- {
- /* Print the list of options in effect. */
- print_version (asm_out_file, ASM_COMMENT_START);
- print_switch_values (asm_out_file, 0, MAX_LINE,
- ASM_COMMENT_START, " ", "\n");
- /* Add a blank line here so it appears in assembler output but not
- screen output. */
- fprintf (asm_out_file, "\n");
- }
-#endif
- } /* ! flag_syntax_only */
-
- /* Set up the debug hooks based on write_symbols. Default to doing
- nothing. */
- debug_hooks = &do_nothing_debug_hooks;
-#if defined(DBX_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG)
- debug_hooks = &dbx_debug_hooks;
-#endif
-#if defined(XCOFF_DEBUGGING_INFO)
- if (write_symbols == XCOFF_DEBUG)
- debug_hooks = &xcoff_debug_hooks;
-#endif
-#ifdef SDB_DEBUGGING_INFO
- if (write_symbols == SDB_DEBUG)
- debug_hooks = &sdb_debug_hooks;
-#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- debug_hooks = &dwarf_debug_hooks;
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG)
- debug_hooks = &dwarf2_debug_hooks;
-#endif
-
- if (! targetm.have_named_sections)
- {
- if (flag_function_sections)
- {
- warning ("-ffunction-sections not supported for this target.");
- flag_function_sections = 0;
- }
- if (flag_data_sections)
- {
- warning ("-fdata-sections not supported for this target.");
- flag_data_sections = 0;
- }
- }
-
- if (flag_function_sections
- && (profile_flag || profile_block_flag))
- {
- warning ("-ffunction-sections disabled; it makes profiling impossible.");
- flag_function_sections = 0;
- }
-
-#ifndef OBJECT_FORMAT_ELF
- if (flag_function_sections && write_symbols != NO_DEBUG)
- warning ("-ffunction-sections may affect debugging on some targets.");
-#endif
-
- /* If dbx symbol table desired, initialize writing it
- and output the predefined types. */
- timevar_push (TV_SYMOUT);
-#ifdef DWARF2_UNWIND_INFO
- if (dwarf2out_do_frame ())
- dwarf2out_frame_init ();
-#endif
-
- (*debug_hooks->init) (main_input_filename);
- timevar_pop (TV_SYMOUT);
-
/* Initialize yet another pass. */
init_final (main_input_filename);
timevar_pop (TV_PARSE);
if (flag_syntax_only)
- goto finish_syntax;
+ return;
globals = getdecls ();
IDENT_ASM_OP, version_string);
#endif
- /* Language-specific end of compilation actions. */
- finish_syntax:
- (*lang_hooks.finish) ();
-
- /* Close the dump files. */
-
- if (flag_gen_aux_info)
- {
- fclose (aux_info_file);
- if (errorcount)
- unlink (aux_info_file_name);
- }
-
if (optimize > 0 && open_dump_file (DFI_combine, NULL))
{
timevar_push (TV_DUMP);
close_dump_file (DFI_combine, NULL, NULL_RTX);
timevar_pop (TV_DUMP);
}
+}
+\f
+/* This is called from various places for FUNCTION_DECL, VAR_DECL,
+ and TYPE_DECL nodes.
- /* Close non-debugging input and output files. Take special care to note
- whether fclose returns an error, since the pages might still be on the
- buffer chain while the file is open. */
-
- finish_parse ();
+ This does nothing for local (non-static) variables, unless the
+ variable is a register variable with an ASMSPEC. In that case, or
+ if the variable is not an automatic, it sets up the RTL and
+ outputs any assembler code (label definition, storage allocation
+ and initialization).
- if (ferror (asm_out_file) != 0)
- fatal_io_error ("error writing to %s", asm_file_name);
- if (fclose (asm_out_file) != 0)
- fatal_io_error ("error closing %s", asm_file_name);
-
- /* Do whatever is necessary to finish printing the graphs. */
- if (graph_dump_format != no_graph)
- {
- int i;
-
- for (i = 0; i < (int) DFI_MAX; ++i)
- if (dump_file[i].initialized && dump_file[i].graph_dump_p)
- {
- char seq[16];
- char *suffix;
-
- sprintf (seq, ".%02d.", i);
- suffix = concat (seq, dump_file[i].extension, NULL);
- finish_graph_dump_file (dump_base_name, suffix);
- free (suffix);
- }
- }
-
- if (mem_report)
- {
- ggc_print_statistics ();
- stringpool_statistics ();
- dump_tree_statistics ();
- }
-
- /* Free up memory for the benefit of leak detectors. */
- free_reg_info ();
-
- /* Stop timing total execution time. */
- timevar_stop (TV_TOTAL);
-
- /* Print the times. */
-
- timevar_print (stderr);
-}
-\f
-/* This is called from various places for FUNCTION_DECL, VAR_DECL,
- and TYPE_DECL nodes.
-
- This does nothing for local (non-static) variables, unless the
- variable is a register variable with an ASMSPEC. In that case, or
- if the variable is not an automatic, it sets up the RTL and
- outputs any assembler code (label definition, storage allocation
- and initialization).
-
- DECL is the declaration. If ASMSPEC is nonzero, it specifies
- the assembler symbol name to be used. TOP_LEVEL is nonzero
- if this declaration is not within a function. */
+ DECL is the declaration. If ASMSPEC is nonzero, it specifies
+ the assembler symbol name to be used. TOP_LEVEL is nonzero
+ if this declaration is not within a function. */
void
rest_of_decl_compilation (decl, asmspec, top_level, at_end)
sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG && toplev)
+ if ((write_symbols == DWARF2_DEBUG
+ || write_symbols == VMS_AND_DWARF2_DEBUG)
+ && toplev)
dwarf2out_decl (TYPE_STUB_DECL (type));
#endif
timevar_pop (TV_SYMOUT);
if (!cfun->x_whole_function_mode_p)
identify_blocks ();
- /* Then remove any notes we don't need. That will make iterating
- over the instruction sequence faster, and allow the garbage
- collector to reclaim the memory used by the notes. */
- remove_unnecessary_notes ();
-
/* In function-at-a-time mode, we do not attempt to keep the BLOCK
tree in sensible shape. So, we just recalculate it here. */
if (cfun->x_whole_function_mode_p)
goto exit_rest_of_compilation;
}
+ /* If we're emitting a nested function, make sure its parent gets
+ emitted as well. Doing otherwise confuses debug info. */
+ {
+ tree parent;
+ for (parent = DECL_CONTEXT (current_function_decl);
+ parent != NULL_TREE;
+ parent = get_containing_scope (parent))
+ if (TREE_CODE (parent) == FUNCTION_DECL)
+ TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1;
+ }
+
+ /* We are now committed to emitting code for this function. Do any
+ preparation, such as emitting abstract debug info for the inline
+ before it gets mangled by optimization. */
+ if (DECL_INLINE (decl))
+ (*debug_hooks->outlining_inline_function) (decl);
+
+ /* Remove any notes we don't need. That will make iterating
+ over the instruction sequence faster, and allow the garbage
+ collector to reclaim the memory used by the notes. */
+ remove_unnecessary_notes ();
+ reorder_blocks ();
+
ggc_collect ();
/* Initialize some variables used by the optimizers. */
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. */
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;
}
if (optimize > 0)
{
+ open_dump_file (DFI_null, decl);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-
- /* ??? 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);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
- /* 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
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 ();
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);
- if (flag_thread_jumps)
- {
- timevar_push (TV_JUMP);
- thread_jumps (insns, max_reg_num (), 1);
- timevar_pop (TV_JUMP);
- }
-
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)
+ 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);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
- delete_null_pointer_checks (insns);
+ 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);
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);
save_csb = flag_cse_skip_blocks;
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)
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;
}
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)
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. */
if (optimize > 0)
{
timevar_push (TV_LOOP);
+ delete_dead_jumptables ();
open_dump_file (DFI_loop, decl);
+ /* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
if (flag_rerun_loop_opt)
}
cleanup_barriers ();
loop_optimize (insns, rtl_dump_file,
- (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT);
+ (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);
}
}
- if (flag_thread_jumps)
- {
- /* This pass of jump threading straightens out code
- that was kinked by loop optimization. */
- timevar_push (TV_JUMP);
- reg_scan (insns, max_reg_num (), 0);
- thread_jumps (insns, max_reg_num (), 0);
- 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 ();
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);
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;
setjmp_args_warning ();
}
+ if (optimize)
+ {
+ clear_bb_flags ();
+ if (initialize_uninitialized_subregs ())
+ {
+ /* Insns were inserted, so things might look a bit different. */
+ insns = get_insns ();
+ update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO
+ | PROP_DEATH_NOTES);
+ }
+ }
+
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();
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);
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);
}
#endif
- if (optimize > 0 && flag_rename_registers)
+ if (flag_rename_registers || flag_cprop_registers)
{
timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
- regrename_optimize ();
+ if (flag_rename_registers)
+ regrename_optimize ();
+ if (flag_cprop_registers)
+ copyprop_hardreg_forward ();
close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
timevar_pop (TV_RENAME_REGISTERS);
init_temp_slots ();
free_basic_block_vars (0);
+ free_bb_for_insn ();
timevar_pop (TV_FINAL);
f_options[i].string, _(description));
}
- printf (_(" -O[number] Set optimisation level to [number]\n"));
- printf (_(" -Os Optimise for space rather than speed\n"));
+ printf (_(" -O[number] Set optimization level to [number]\n"));
+ printf (_(" -Os Optimize for space rather than speed\n"));
for (i = LAST_PARAM; i--;)
{
const char *description = compiler_params[i].help;
static void
display_target_options ()
{
- int undoc,i;
+ int undoc, i;
+ static bool displayed = false;
+
+ /* Avoid double printing for --help --target-help. */
+ if (displayed)
+ return;
+ displayed = true;
if (ARRAY_SIZE (target_switches) > 1
#ifdef TARGET_OPTIONS
rtl_dump_and_exit = 1;
break;
case 'y':
- set_yydebug (1);
+ (*lang_hooks.set_yydebug) (1);
break;
case 'D': /* These are handled by the preprocessor. */
case 'I':
}
if (!strcmp (arg, "fast-math"))
- set_fast_math_flags();
+ set_fast_math_flags ();
else if (!strcmp (arg, "no-fast-math"))
- set_no_fast_math_flags();
+ set_no_fast_math_flags ();
else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
|| (option_value = skip_leading_substring (arg, "inline-limit=")))
{
diagnostic_prefixing_rule (global_dc)
= DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
else
- error ("Unrecognized option `%s'", arg - 2);
+ error ("unrecognized option `%s'", arg - 2);
}
else if (!strcmp (arg, "no-stack-limit"))
stack_limit_rtx = NULL_RTX;
/* Indexed by enum debug_info_type. */
static const char *const debug_type_names[] =
{
- "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
+ "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
};
/* The maximum admissible debug level value. */
break;
case 'a':
- if (arg[1] == 0)
- {
-#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- warning ("`-a' option (basic block profile) not supported");
-#else
- profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
-#endif
- }
- else if (!strcmp (arg, "ax"))
- {
-#if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- warning ("`-ax' option (jump profiling) not supported");
-#else
- profile_block_flag = (!profile_block_flag
- || profile_block_flag == 2) ? 2 : 3;
-#endif
- }
- else if (!strncmp (arg, "aux-info", 8))
+ if (!strncmp (arg, "aux-info", 8))
{
if (arg[8] == '\0')
{
return 1;
}
\f
-/* Entry point of cc1, cc1plus, jc1, f771, etc.
- Decode command args, then call compile_file.
- Exit code is FATAL_EXIT_CODE if can't open files or if there were
- any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
-
- It is not safe to call this function more than once. */
+/* Decode -m switches. */
+/* Decode the switch -mNAME. */
-int
-toplev_main (argc, argv)
- int argc;
- char **argv;
+static void
+set_target_switch (name)
+ const char *name;
{
- int i;
- char *p;
-
- /* save in case md file wants to emit args as a comment. */
- save_argc = argc;
- save_argv = argv;
+ size_t j;
+ int valid_target_option = 0;
- p = argv[0] + strlen (argv[0]);
- while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
- --p;
+ for (j = 0; j < ARRAY_SIZE (target_switches); j++)
+ if (!strcmp (target_switches[j].name, name))
+ {
+ if (target_switches[j].value < 0)
+ target_flags &= ~-target_switches[j].value;
+ else
+ target_flags |= target_switches[j].value;
+ valid_target_option = 1;
+ }
+
+#ifdef TARGET_OPTIONS
+ if (!valid_target_option)
+ for (j = 0; j < ARRAY_SIZE (target_options); j++)
+ {
+ int len = strlen (target_options[j].prefix);
+ if (!strncmp (target_options[j].prefix, name, len))
+ {
+ *target_options[j].variable = name + len;
+ valid_target_option = 1;
+ }
+ }
+#endif
+
+ if (!valid_target_option)
+ error ("invalid option `%s'", name);
+}
+\f
+/* Print version information to FILE.
+ Each line begins with INDENT (for the case where FILE is the
+ assembler output file). */
+
+static void
+print_version (file, indent)
+ FILE *file;
+ const char *indent;
+{
+#ifndef __VERSION__
+#define __VERSION__ "[?]"
+#endif
+ fnotice (file,
+#ifdef __GNUC__
+ "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
+#else
+ "%s%s%s version %s (%s) compiled by CC.\n"
+#endif
+ , indent, *indent != 0 ? " " : "",
+ lang_hooks.name, version_string, TARGET_NAME,
+ indent, __VERSION__);
+}
+
+/* Print an option value and return the adjusted position in the line.
+ ??? We don't handle error returns from fprintf (disk full); presumably
+ other code will catch a disk full though. */
+
+static int
+print_single_switch (file, pos, max, indent, sep, term, type, name)
+ FILE *file;
+ int pos, max;
+ const char *indent, *sep, *term, *type, *name;
+{
+ /* The ultrix fprintf returns 0 on success, so compute the result we want
+ here since we need it for the following test. */
+ int len = strlen (sep) + strlen (type) + strlen (name);
+
+ if (pos != 0
+ && pos + len > max)
+ {
+ fprintf (file, "%s", term);
+ pos = 0;
+ }
+ if (pos == 0)
+ {
+ fprintf (file, "%s", indent);
+ pos = strlen (indent);
+ }
+ fprintf (file, "%s%s%s", sep, type, name);
+ pos += len;
+ return pos;
+}
+
+/* Print active target switches to FILE.
+ POS is the current cursor position and MAX is the size of a "line".
+ Each line begins with INDENT and ends with TERM.
+ Each switch is separated from the next by SEP. */
+
+static void
+print_switch_values (file, pos, max, indent, sep, term)
+ FILE *file;
+ int pos, max;
+ const char *indent, *sep, *term;
+{
+ size_t j;
+ char **p;
+
+ /* Print the options as passed. */
+
+ pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
+ _("options passed: "), "");
+
+ for (p = &save_argv[1]; *p != NULL; p++)
+ if (**p == '-')
+ {
+ /* Ignore these. */
+ if (strcmp (*p, "-o") == 0)
+ {
+ if (p[1] != NULL)
+ p++;
+ continue;
+ }
+ if (strcmp (*p, "-quiet") == 0)
+ continue;
+ if (strcmp (*p, "-version") == 0)
+ continue;
+ if ((*p)[1] == 'd')
+ continue;
+
+ pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
+ }
+ if (pos > 0)
+ fprintf (file, "%s", term);
+
+ /* Print the -f and -m options that have been enabled.
+ We don't handle language specific options but printing argv
+ should suffice. */
+
+ pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
+ _("options enabled: "), "");
+
+ for (j = 0; j < ARRAY_SIZE (f_options); j++)
+ if (*f_options[j].variable == f_options[j].on_value)
+ pos = print_single_switch (file, pos, max, indent, sep, term,
+ "-f", f_options[j].string);
+
+ /* Print target specific options. */
+
+ for (j = 0; j < ARRAY_SIZE (target_switches); j++)
+ if (target_switches[j].name[0] != '\0'
+ && target_switches[j].value > 0
+ && ((target_switches[j].value & target_flags)
+ == target_switches[j].value))
+ {
+ pos = print_single_switch (file, pos, max, indent, sep, term,
+ "-m", target_switches[j].name);
+ }
+
+#ifdef TARGET_OPTIONS
+ for (j = 0; j < ARRAY_SIZE (target_options); j++)
+ if (*target_options[j].variable != NULL)
+ {
+ char prefix[256];
+ sprintf (prefix, "-m%s", target_options[j].prefix);
+ pos = print_single_switch (file, pos, max, indent, sep, term,
+ prefix, *target_options[j].variable);
+ }
+#endif
+
+ fprintf (file, "%s", term);
+}
+\f
+/* Open assembly code output file. Do this even if -fsyntax-only is
+ on, because then the driver will have provided the name of a
+ temporary file or bit bucket for us. NAME is the file specified on
+ the command line, possibly NULL. */
+static void
+init_asm_output (name)
+ const char *name;
+{
+ if (name == NULL && asm_file_name == 0)
+ asm_out_file = stdout;
+ else
+ {
+ if (asm_file_name == 0)
+ {
+ int len = strlen (dump_base_name);
+ char *dumpname = (char *) xmalloc (len + 6);
+ memcpy (dumpname, dump_base_name, len + 1);
+ strip_off_ending (dumpname, len);
+ strcat (dumpname, ".s");
+ asm_file_name = dumpname;
+ }
+ if (!strcmp (asm_file_name, "-"))
+ asm_out_file = stdout;
+ else
+ asm_out_file = fopen (asm_file_name, "w");
+ if (asm_out_file == 0)
+ fatal_io_error ("can't open %s for writing", asm_file_name);
+ }
+
+#ifdef IO_BUFFER_SIZE
+ setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+ _IOFBF, IO_BUFFER_SIZE);
+#endif
+
+ if (!flag_syntax_only)
+ {
+#ifdef ASM_FILE_START
+ ASM_FILE_START (asm_out_file);
+#endif
+
+#ifdef ASM_COMMENT_START
+ if (flag_verbose_asm)
+ {
+ /* Print the list of options in effect. */
+ print_version (asm_out_file, ASM_COMMENT_START);
+ print_switch_values (asm_out_file, 0, MAX_LINE,
+ ASM_COMMENT_START, " ", "\n");
+ /* Add a blank line here so it appears in assembler output but not
+ screen output. */
+ fprintf (asm_out_file, "\n");
+ }
+#endif
+ }
+}
+\f
+/* Initialization of the front end environment, before command line
+ options are parsed. Signal handlers, internationalization etc.
+ ARGV0 is main's argv[0]. */
+static void
+general_init (argv0)
+ char *argv0;
+{
+ char *p;
+
+ p = argv0 + strlen (argv0);
+ while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
+ --p;
progname = p;
xmalloc_set_program_name (progname);
signal (SIGIOT, crash_signal);
#endif
- decl_printable_name = decl_name;
- lang_expand_expr = (lang_expand_expr_t) do_abort;
-
- /* Initialize whether `char' is signed. */
- flag_signed_char = DEFAULT_SIGNED_CHAR;
-#ifdef DEFAULT_SHORT_ENUMS
- /* Initialize how much space enums occupy, by default. */
- flag_short_enums = DEFAULT_SHORT_ENUMS;
-#endif
-
- tree_code_length[(int) IDENTIFIER_NODE]
- = ((lang_hooks.identifier_size - sizeof (struct tree_common))
- / sizeof (tree));
+ /* Initialize the diagnostics reporting machinery, so option parsing
+ can give warnings and errors. */
+ diagnostic_initialize (global_dc);
+}
+\f
+/* 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
+parse_options_and_default_flags (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
- /* Initialize the garbage-collector. */
- init_ggc ();
- init_stringpool ();
- ggc_add_rtx_root (&stack_limit_rtx, 1);
- ggc_add_tree_root (¤t_function_decl, 1);
- ggc_add_tree_root (¤t_function_func_begin_label, 1);
+ /* Save in case md file wants to emit args as a comment. */
+ save_argc = argc;
+ save_argv = argv;
- /* Initialize the diagnostics reporting machinery. */
- diagnostic_initialize (global_dc);
+ /* Initialize register usage now so switches may override. */
+ init_reg_sets ();
/* Register the language-independent parameters. */
add_params (lang_independent_params, LAST_PARAM);
- /* Perform language-specific options intialization. */
+ /* Perform language-specific options initialization. */
(*lang_hooks.init_options) ();
/* Scan to see what optimization level has been specified. That will
flag_omit_frame_pointer = 1;
#endif
flag_guess_branch_prob = 1;
+ flag_cprop_registers = 1;
}
if (optimize >= 2)
align_functions = 1;
}
+ /* Initialize whether `char' is signed. */
+ flag_signed_char = DEFAULT_SIGNED_CHAR;
+#ifdef DEFAULT_SHORT_ENUMS
+ /* Initialize how much space enums occupy, by default. */
+ flag_short_enums = DEFAULT_SHORT_ENUMS;
+#endif
+
/* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
modify it. */
target_flags = 0;
OPTIMIZATION_OPTIONS (optimize, optimize_size);
#endif
- /* Initialize register usage now so switches may override. */
- init_reg_sets ();
-
/* Perform normal command line switch decoding. */
for (i = 1; i < argc;)
{
{
if (extra_warnings)
{
- warning ("Ignoring command line option '%s'", argv[i]);
+ warning ("ignoring command line option '%s'", argv[i]);
if (lang)
warning
- ("(It is valid for %s but not the selected language)",
+ ("(it is valid for %s but not the selected language)",
lang);
}
}
else if (argv[i][0] == '-' && argv[i][1] == 'g')
warning ("`%s': unknown or unsupported -g option", &argv[i][2]);
else
- error ("Unrecognized option `%s'", argv[i]);
+ error ("unrecognized option `%s'", argv[i]);
i++;
}
}
- /* All command line options have been processed. */
- (*lang_hooks.post_options) ();
-
- if (exit_after_options)
- exit (0);
-
- /* Checker uses the frame pointer. */
- if (flag_check_memory_usage)
- flag_omit_frame_pointer = 0;
-
+ /* Set flag_no_inline before the post_options () hook. The C front
+ ends use it to determine tree inlining defaults. FIXME: such
+ code should be lang-independent when all front ends use tree
+ inlining, in which case it, and this condition, should be moved
+ to the top of process_options() instead. */
if (optimize == 0)
{
/* Inlining does not work if not optimizing,
warning ("-Wuninitialized is not supported without -O");
}
- /* We do not currently support sibling-call optimization in the
- presence of exceptions. See PR2975 for a test-case that will
- fail if we try to combine both of these features. */
- if (flag_exceptions)
- flag_optimize_sibling_calls = 0;
-
-#ifdef OVERRIDE_OPTIONS
+ /* All command line options have been parsed; allow the front end to
+ perform consistency checks, etc. */
+ (*lang_hooks.post_options) ();
+}
+\f
+/* Process the options that have been parsed. */
+static void
+process_options ()
+{
+#ifdef OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of options. */
OVERRIDE_OPTIONS;
#endif
/* Set up the align_*_log variables, defaulting them to 1 if they
were still unset. */
if (align_loops <= 0) align_loops = 1;
+ if (align_loops_max_skip > align_loops || !align_loops)
+ align_loops_max_skip = align_loops - 1;
align_loops_log = floor_log2 (align_loops * 2 - 1);
if (align_jumps <= 0) align_jumps = 1;
+ if (align_jumps_max_skip > align_jumps || !align_jumps)
+ align_jumps_max_skip = align_jumps - 1;
align_jumps_log = floor_log2 (align_jumps * 2 - 1);
if (align_labels <= 0) align_labels = 1;
align_labels_log = floor_log2 (align_labels * 2 - 1);
+ if (align_labels_max_skip > align_labels || !align_labels)
+ align_labels_max_skip = align_labels - 1;
if (align_functions <= 0) align_functions = 1;
align_functions_log = floor_log2 (align_functions * 2 - 1);
- if (profile_block_flag == 3)
- {
- warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
- profile_block_flag = 2;
- }
-
/* Unrolling all loops implies that standard loop unrolling must also
be done. */
if (flag_unroll_all_loops)
print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
}
- compile_file (filename);
+ if (! quiet_flag)
+ time_report = 1;
- if (errorcount)
- return (FATAL_EXIT_CODE);
- if (sorrycount)
- return (FATAL_EXIT_CODE);
- return (SUCCESS_EXIT_CODE);
+ if (flag_syntax_only)
+ {
+ write_symbols = NO_DEBUG;
+ profile_flag = 0;
+ }
+
+ /* Now we know write_symbols, set up the debug hooks based on it.
+ By default we do nothing for debug output. */
+#if defined(DBX_DEBUGGING_INFO)
+ if (write_symbols == DBX_DEBUG)
+ debug_hooks = &dbx_debug_hooks;
+#endif
+#if defined(XCOFF_DEBUGGING_INFO)
+ if (write_symbols == XCOFF_DEBUG)
+ debug_hooks = &xcoff_debug_hooks;
+#endif
+#ifdef SDB_DEBUGGING_INFO
+ if (write_symbols == SDB_DEBUG)
+ debug_hooks = &sdb_debug_hooks;
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+ if (write_symbols == DWARF_DEBUG)
+ debug_hooks = &dwarf_debug_hooks;
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+ if (write_symbols == DWARF2_DEBUG)
+ debug_hooks = &dwarf2_debug_hooks;
+#endif
+#ifdef VMS_DEBUGGING_INFO
+ if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
+ debug_hooks = &vmsdbg_debug_hooks;
+#endif
+
+ /* If auxiliary info generation is desired, open the output file.
+ This goes in the same directory as the source file--unlike
+ all the other output files. */
+ if (flag_gen_aux_info)
+ {
+ aux_info_file = fopen (aux_info_file_name, "w");
+ if (aux_info_file == 0)
+ fatal_io_error ("can't open %s", aux_info_file_name);
+ }
+
+ if (! targetm.have_named_sections)
+ {
+ if (flag_function_sections)
+ {
+ warning ("-ffunction-sections not supported for this target");
+ flag_function_sections = 0;
+ }
+ if (flag_data_sections)
+ {
+ warning ("-fdata-sections not supported for this target");
+ flag_data_sections = 0;
+ }
+ }
+
+ if (flag_function_sections && profile_flag)
+ {
+ warning ("-ffunction-sections disabled; it makes profiling impossible");
+ flag_function_sections = 0;
+ }
+
+#ifndef HAVE_prefetch
+ if (flag_prefetch_loop_arrays)
+ {
+ warning ("-fprefetch-loop-arrays not supported for this target");
+ flag_prefetch_loop_arrays = 0;
+ }
+#else
+ if (flag_prefetch_loop_arrays && !HAVE_prefetch)
+ {
+ warning ("-fprefetch-loop-arrays not supported for this target (try -march switches)");
+ flag_prefetch_loop_arrays = 0;
+ }
+#endif
+
+ /* This combination of options isn't handled for i386 targets and doesn't
+ make much sense anyway, so don't allow it. */
+ if (flag_prefetch_loop_arrays && optimize_size)
+ {
+ warning ("-fprefetch-loop-arrays is not supported with -Os");
+ flag_prefetch_loop_arrays = 0;
+ }
+
+#ifndef OBJECT_FORMAT_ELF
+ if (flag_function_sections && write_symbols != NO_DEBUG)
+ warning ("-ffunction-sections may affect debugging on some targets");
+#endif
}
\f
-/* Decode -m switches. */
-/* Decode the switch -mNAME. */
-
+/* Language-independent initialization, before language-dependent
+ initialization. */
static void
-set_target_switch (name)
+lang_independent_init ()
+{
+ decl_printable_name = decl_name;
+ lang_expand_expr = (lang_expand_expr_t) do_abort;
+
+ /* Set the language-dependent identifier size. */
+ tree_code_length[(int) IDENTIFIER_NODE]
+ = ((lang_hooks.identifier_size - sizeof (struct tree_common)
+ + sizeof (tree) - 1) / sizeof (tree));
+
+ /* Initialize the garbage-collector, and string pools. */
+ init_ggc ();
+ ggc_add_rtx_root (&stack_limit_rtx, 1);
+ ggc_add_tree_root (¤t_function_decl, 1);
+ ggc_add_tree_root (¤t_function_func_begin_label, 1);
+
+ init_stringpool ();
+ init_obstacks ();
+
+ init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
+ || debug_info_level == DINFO_LEVEL_VERBOSE
+#ifdef VMS_DEBUGGING_INFO
+ /* Enable line number info for traceback */
+ || debug_info_level > DINFO_LEVEL_NONE
+#endif
+ || flag_test_coverage
+ || warn_notreached);
+ init_regs ();
+ init_alias_once ();
+ init_stmt ();
+ init_loop ();
+ init_reload ();
+ init_function_once ();
+ init_stor_layout_once ();
+ init_varasm_once ();
+ init_EXPR_INSN_LIST_cache ();
+
+ /* The following initialization functions need to generate rtl, so
+ provide a dummy function context for them. */
+ init_dummy_function_start ();
+ init_expmed ();
+ init_expr_once ();
+ if (flag_caller_saves)
+ init_caller_save ();
+ expand_dummy_function_end ();
+}
+\f
+/* Language-dependent initialization. Returns non-zero on success. */
+static int
+lang_dependent_init (name)
const char *name;
{
- size_t j;
- int valid_target_option = 0;
+ if (dump_base_name == 0)
+ dump_base_name = name ? name : "gccdump";
- for (j = 0; j < ARRAY_SIZE (target_switches); j++)
- if (!strcmp (target_switches[j].name, name))
- {
- if (target_switches[j].value < 0)
- target_flags &= ~-target_switches[j].value;
- else
- target_flags |= target_switches[j].value;
- valid_target_option = 1;
- }
+ /* Front-end initialization. This hook can assume that GC,
+ identifier hashes etc. are set up, but debug initialization is
+ not done yet. This routine must return the original filename
+ (e.g. foo.i -> foo.c) so can correctly initialize debug output. */
+ name = (*lang_hooks.init) (name);
+ if (name == NULL)
+ return 0;
-#ifdef TARGET_OPTIONS
- if (!valid_target_option)
- for (j = 0; j < ARRAY_SIZE (target_options); j++)
- {
- int len = strlen (target_options[j].prefix);
- if (!strncmp (target_options[j].prefix, name, len))
- {
- *target_options[j].variable = name + len;
- valid_target_option = 1;
- }
- }
+ /* Is this duplication necessary? */
+ name = ggc_strdup (name);
+ main_input_filename = input_filename = name;
+ init_asm_output (name);
+
+ /* These create various _DECL nodes, so need to be called after the
+ front end is initialized. */
+ init_eh ();
+ init_optabs ();
+
+ /* Put an entry on the input file stack for the main input file. */
+ push_srcloc (input_filename, 0);
+
+ /* If dbx symbol table desired, initialize writing it and output the
+ predefined types. */
+ timevar_push (TV_SYMOUT);
+
+#ifdef DWARF2_UNWIND_INFO
+ if (dwarf2out_do_frame ())
+ dwarf2out_frame_init ();
#endif
- if (!valid_target_option)
- error ("Invalid option `%s'", name);
+ /* Now we have the correct original filename, we can initialize
+ debug output. */
+ (*debug_hooks->init) (name);
+
+ timevar_pop (TV_SYMOUT);
+
+ return 1;
}
\f
-/* Print version information to FILE.
- Each line begins with INDENT (for the case where FILE is the
- assembler output file). */
+/* Clean up: close opened files, etc. */
static void
-print_version (file, indent)
- FILE *file;
- const char *indent;
+finalize ()
{
-#ifndef __VERSION__
-#define __VERSION__ "[?]"
-#endif
- fnotice (file,
-#ifdef __GNUC__
- "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
-#else
- "%s%s%s version %s (%s) compiled by CC.\n"
-#endif
- , indent, *indent != 0 ? " " : "",
- lang_hooks.name, version_string, TARGET_NAME,
- indent, __VERSION__);
-}
+ /* Close the dump files. */
+ if (flag_gen_aux_info)
+ {
+ fclose (aux_info_file);
+ if (errorcount)
+ unlink (aux_info_file_name);
+ }
-/* Print an option value and return the adjusted position in the line.
- ??? We don't handle error returns from fprintf (disk full); presumably
- other code will catch a disk full though. */
+ /* Close non-debugging input and output files. Take special care to note
+ whether fclose returns an error, since the pages might still be on the
+ buffer chain while the file is open. */
-static int
-print_single_switch (file, pos, max, indent, sep, term, type, name)
- FILE *file;
- int pos, max;
- const char *indent, *sep, *term, *type, *name;
-{
- /* The ultrix fprintf returns 0 on success, so compute the result we want
- here since we need it for the following test. */
- int len = strlen (sep) + strlen (type) + strlen (name);
+ if (asm_out_file)
+ {
+ if (ferror (asm_out_file) != 0)
+ fatal_io_error ("error writing to %s", asm_file_name);
+ if (fclose (asm_out_file) != 0)
+ fatal_io_error ("error closing %s", asm_file_name);
+ }
- if (pos != 0
- && pos + len > max)
+ /* Do whatever is necessary to finish printing the graphs. */
+ if (graph_dump_format != no_graph)
{
- fprintf (file, "%s", term);
- pos = 0;
+ int i;
+
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ if (dump_file[i].initialized && dump_file[i].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
+
+ sprintf (seq, DUMPFILE_FORMAT, i);
+ suffix = concat (seq, dump_file[i].extension, NULL);
+ finish_graph_dump_file (dump_base_name, suffix);
+ free (suffix);
+ }
}
- if (pos == 0)
+
+ if (mem_report)
{
- fprintf (file, "%s", indent);
- pos = strlen (indent);
+ ggc_print_statistics ();
+ stringpool_statistics ();
+ dump_tree_statistics ();
}
- fprintf (file, "%s%s%s", sep, type, name);
- pos += len;
- return pos;
-}
-/* Print active target switches to FILE.
- POS is the current cursor position and MAX is the size of a "line".
- Each line begins with INDENT and ends with TERM.
- Each switch is separated from the next by SEP. */
+ /* Free up memory for the benefit of leak detectors. */
+ free_reg_info ();
+ /* Language-specific end of compilation actions. */
+ (*lang_hooks.finish) ();
+}
+\f
+/* Initialize the compiler, and compile the input file. */
static void
-print_switch_values (file, pos, max, indent, sep, term)
- FILE *file;
- int pos, max;
- const char *indent, *sep, *term;
+do_compile ()
{
- size_t j;
- char **p;
+ /* The bulk of command line switch processing. */
+ process_options ();
- /* Print the options as passed. */
+ /* We cannot start timing until after options are processed since that
+ says if we run timers or not. */
+ init_timevar ();
+ timevar_start (TV_TOTAL);
- pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
- _("options passed: "), "");
+ /* Language-independent initialization. Also sets up GC, identifier
+ hashes etc. */
+ lang_independent_init ();
- for (p = &save_argv[1]; *p != NULL; p++)
- if (**p == '-')
- {
- /* Ignore these. */
- if (strcmp (*p, "-o") == 0)
- {
- if (p[1] != NULL)
- p++;
- continue;
- }
- if (strcmp (*p, "-quiet") == 0)
- continue;
- if (strcmp (*p, "-version") == 0)
- continue;
- if ((*p)[1] == 'd')
- continue;
+ /* Language-dependent initialization. Returns true on success. */
+ if (lang_dependent_init (filename))
+ compile_file ();
- pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
- }
- if (pos > 0)
- fprintf (file, "%s", term);
+ finalize ();
- /* Print the -f and -m options that have been enabled.
- We don't handle language specific options but printing argv
- should suffice. */
+ /* Stop timing and print the times. */
+ timevar_stop (TV_TOTAL);
+ timevar_print (stderr);
+}
+\f
+/* Entry point of cc1, cc1plus, jc1, f771, etc.
+ Decode command args, then call compile_file.
+ Exit code is FATAL_EXIT_CODE if can't open files or if there were
+ any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
- pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
- _("options enabled: "), "");
+ It is not safe to call this function more than once. */
- for (j = 0; j < ARRAY_SIZE (f_options); j++)
- if (*f_options[j].variable == f_options[j].on_value)
- pos = print_single_switch (file, pos, max, indent, sep, term,
- "-f", f_options[j].string);
+int
+toplev_main (argc, argv)
+ int argc;
+ char **argv;
+{
+ hex_init ();
- /* Print target specific options. */
+ /* Initialization of GCC's environment, and diagnostics. */
+ general_init (argv [0]);
- for (j = 0; j < ARRAY_SIZE (target_switches); j++)
- if (target_switches[j].name[0] != '\0'
- && target_switches[j].value > 0
- && ((target_switches[j].value & target_flags)
- == target_switches[j].value))
- {
- pos = print_single_switch (file, pos, max, indent, sep, term,
- "-m", target_switches[j].name);
- }
+ /* Parse the options and do minimal processing; basically just
+ enough to default flags appropriately. */
+ parse_options_and_default_flags (argc, argv);
-#ifdef TARGET_OPTIONS
- for (j = 0; j < ARRAY_SIZE (target_options); j++)
- if (*target_options[j].variable != NULL)
- {
- char prefix[256];
- sprintf (prefix, "-m%s", target_options[j].prefix);
- pos = print_single_switch (file, pos, max, indent, sep, term,
- prefix, *target_options[j].variable);
- }
-#endif
+ /* Exit early if we can (e.g. -help). */
+ if (!exit_after_options)
+ do_compile ();
- fprintf (file, "%s", term);
+ if (errorcount || sorrycount)
+ return (FATAL_EXIT_CODE);
+
+ return (SUCCESS_EXIT_CODE);
}