summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/toplev.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-02-06 04:59:39 +0000
committerobrien <obrien@FreeBSD.org>2002-02-06 04:59:39 +0000
commit7d7df915b2215810c82954b121d12bba5f1e457f (patch)
treef3bddf2f511dca563169e75faf5011b56629b20d /contrib/gcc/toplev.c
parent26e5ea876a774df47ff11791a98e5717cb56f0f4 (diff)
downloadFreeBSD-src-7d7df915b2215810c82954b121d12bba5f1e457f.zip
FreeBSD-src-7d7df915b2215810c82954b121d12bba5f1e457f.tar.gz
Merge rev 1.2 (-fformat-extensions) and rev 1.7 (optimization downgrade)
into GCC 3.1-snap.
Diffstat (limited to 'contrib/gcc/toplev.c')
-rw-r--r--contrib/gcc/toplev.c6909
1 files changed, 3194 insertions, 3715 deletions
diff --git a/contrib/gcc/toplev.c b/contrib/gcc/toplev.c
index e9d8886..379358b 100644
--- a/contrib/gcc/toplev.c
+++ b/contrib/gcc/toplev.c
@@ -1,23 +1,23 @@
/* 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 GNU CC.
+This file is part of GCC.
-GNU CC 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 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.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+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. */
/* $FreeBSD$ */
@@ -44,22 +44,34 @@ Boston, MA 02111-1307, USA. */
#include "input.h"
#include "tree.h"
#include "rtl.h"
+#include "tm_p.h"
#include "flags.h"
#include "insn-attr.h"
-#include "insn-codes.h"
#include "insn-config.h"
+#include "insn-flags.h"
+#include "hard-reg-set.h"
#include "recog.h"
-#include "defaults.h"
#include "output.h"
#include "except.h"
+#include "function.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
-
-#ifdef DWARF_DEBUGGING_INFO
-#include "dwarfout.h"
-#endif
+#include "ggc.h"
+#include "graph.h"
+#include "loop.h"
+#include "regs.h"
+#include "timevar.h"
+#include "diagnostic.h"
+#include "ssa.h"
+#include "params.h"
+#include "reload.h"
+#include "dwarf2asm.h"
+#include "integrate.h"
+#include "debug.h"
+#include "target.h"
+#include "langhooks.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
@@ -74,15 +86,21 @@ Boston, MA 02111-1307, USA. */
#endif
#ifdef XCOFF_DEBUGGING_INFO
-#include "xcoffout.h"
+#include "xcoffout.h" /* Needed for external data
+ declarations for e.g. AIX 4.x. */
+#endif
+
+#ifdef HALF_PIC_DEBUG
+#include "halfpic.h"
#endif
#ifdef VMS
/* The extra parameters substantially improve the I/O performance. */
+
static FILE *
vms_fopen (fname, type)
- char * fname;
- char * type;
+ char *fname;
+ char *type;
{
/* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
fixed arguments, which matches ANSI's specification but not VAXCRTL's
@@ -95,56 +113,9 @@ vms_fopen (fname, type)
else
return (*vmslib_fopen) (fname, type, "mbc=32");
}
-#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
-
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
-
-extern int rtx_equal_function_value_matters;
-
-#if ! (defined (VMS) || defined (OS2))
-extern char **environ;
-#endif
-extern char *version_string, *language_string;
+#define fopen vms_fopen
+#endif /* VMS */
/* Carry information from ASM_DECLARE_OBJECT_NAME
to ASM_FINISH_DECLARE_OBJECT. */
@@ -152,108 +123,59 @@ extern char *version_string, *language_string;
extern int size_directive_output;
extern tree last_assemble_variable_decl;
-extern char *init_parse PVPROTO((char *));
-extern void finish_parse ();
-extern void init_decl_processing ();
-extern void init_obstacks ();
-extern void init_tree_codes ();
-extern void init_rtl ();
-extern void init_regs ();
-extern void init_optabs ();
-extern void init_stmt ();
-extern void init_reg_sets ();
-extern void dump_flow_info ();
-extern void dump_sched_info ();
-extern void dump_local_alloc ();
-extern void regset_release_memory ();
-
-extern void print_rtl ();
-extern void print_rtl_with_bb ();
-
-void rest_of_decl_compilation ();
-void error_with_file_and_line PVPROTO((const char *file,
- int line, const char *s, ...));
-void error_with_decl PVPROTO((tree decl, const char *s, ...));
-void error_for_asm PVPROTO((rtx insn, const char *s, ...));
-void notice PVPROTO((const char *s, ...));
-void error PVPROTO((const char *s, ...));
-void fatal PVPROTO((const char *s, ...));
-void warning_with_file_and_line PVPROTO((const char *file,
- int line, const char *s, ...));
-void warning_with_decl PVPROTO((tree decl, const char *s, ...));
-void warning PVPROTO((const char *s, ...));
-void pedwarn PVPROTO((const char *s, ...));
-void pedwarn_with_decl PVPROTO((tree decl, const char *s, ...));
-void pedwarn_with_file_and_line PVPROTO((const char *file,
- int line, const char *s, ...));
-void sorry PVPROTO((const char *s, ...));
-static void set_target_switch PROTO((const char *));
-static char *decl_name PROTO((tree, int));
-static void vmessage PROTO((const char *, const char *, va_list));
-static void v_message_with_file_and_line PROTO((const char *, int, int,
- const char *, va_list));
-static void v_message_with_decl PROTO((tree, int, const char *, va_list));
-static void file_and_line_for_asm PROTO((rtx, char **, int *));
-static void v_error_with_file_and_line PROTO((const char *, int,
- const char *, va_list));
-static void v_error_with_decl PROTO((tree, const char *, va_list));
-static void v_error_for_asm PROTO((rtx, const char *, va_list));
-static void verror PROTO((const char *, va_list));
-static void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
-static void v_warning_with_file_and_line PROTO ((const char *, int,
- const char *, va_list));
-static void v_warning_with_decl PROTO((tree, const char *, va_list));
-static void v_warning_for_asm PROTO((rtx, const char *, va_list));
-static void vwarning PROTO((const char *, va_list));
-static void vpedwarn PROTO((const char *, va_list));
-static void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
-static void v_pedwarn_with_file_and_line PROTO((const char *, int,
- const char *, va_list));
-static void vsorry PROTO((const char *, va_list));
-static void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
-static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
-#ifdef ASM_IDENTIFY_LANGUAGE
-/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
-static void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
-#endif
-static void open_dump_file PROTO((const char *, const char *));
-static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
-static void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
-static void clean_dump_file PROTO((const char *));
-static void compile_file PROTO((char *));
-static void display_help PROTO ((void));
-
-static void print_version PROTO((FILE *, const char *));
-static int print_single_switch PROTO((FILE *, int, int, const char *,
+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 ((void));
+static void display_help PARAMS ((void));
+static void display_target_options PARAMS ((void));
+
+static void decode_d_option PARAMS ((const char *));
+static int decode_f_option PARAMS ((const char *));
+static int decode_W_option PARAMS ((const char *));
+static int decode_g_option PARAMS ((const char *));
+static unsigned int independent_decode_option PARAMS ((int, char **));
+
+static void print_version PARAMS ((FILE *, const char *));
+static int print_single_switch PARAMS ((FILE *, int, int, const char *,
const char *, const char *,
const char *, const char *));
-static void print_switch_values PROTO((FILE *, int, int, const char *,
+static void print_switch_values PARAMS ((FILE *, int, int, const char *,
const char *, const char *));
-void print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
-void clean_graph_dump_file PROTO ((const char *, const char *));
-void finish_graph_dump_file PROTO ((const char *, const char *));
/* Length of line when printing switch values. */
#define MAX_LINE 75
/* Name of program invoked, sans directories. */
-char *progname;
+const char *progname;
-/* Copy of arguments to main. */
+/* Copy of arguments to toplev_main. */
int save_argc;
char **save_argv;
/* Name of current original source file (what was input to cpp).
This comes from each #-command in the actual input. */
-char *input_filename;
+const char *input_filename;
/* Name of top-level original source file (what was input to cpp).
This comes from the #-command at the beginning of the actual input.
If there isn't any there, then this is the cc1 input file name. */
-char *main_input_filename;
+const char *main_input_filename;
/* Current line number in real source file. */
@@ -269,50 +191,139 @@ struct file_stack *input_file_stack;
/* Incremented on each change to input_file_stack. */
int input_file_stack_tick;
-/* FUNCTION_DECL for function now being parsed or compiled. */
-
-extern tree current_function_decl;
-
/* Name to use as base of names for dump output files. */
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. */
extern int target_flags;
-/* Flags saying which kinds of debugging dump have been requested. */
-
-int rtl_dump = 0;
-int rtl_dump_and_exit = 0;
-int jump_opt_dump = 0;
-int addressof_dump = 0;
-int cse_dump = 0;
-int gcse_dump = 0;
-int loop_dump = 0;
-int cse2_dump = 0;
-int branch_prob_dump = 0;
-int flow_dump = 0;
-int combine_dump = 0;
-int regmove_dump = 0;
-int sched_dump = 0;
-int local_reg_dump = 0;
-int global_reg_dump = 0;
-int flow2_dump = 0;
-int sched2_dump = 0;
-int jump2_opt_dump = 0;
-#ifdef DELAY_SLOTS
-int dbr_sched_dump = 0;
-#endif
-int flag_print_asm_name = 0;
-#ifdef STACK_REGS
-int stack_reg_dump = 0;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-int mach_dep_reorg_dump = 0;
-#endif
+/* Debug hooks - dependent upon command line options. */
+
+struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
+
+/* Describes a dump file. */
+
+struct dump_file_info
+{
+ /* The unique extension to apply, e.g. ".jump". */
+ const char *const extension;
+
+ /* The -d<c> character that enables this dump file. */
+ char const debug_switch;
+
+ /* True if there is a corresponding graph dump file. */
+ char const graph_dump_p;
+
+ /* True if the user selected this dump. */
+ char enabled;
+
+ /* True if the files have been initialized (ie truncated). */
+ char initialized;
+};
+
+/* Enumerate the extant dump files. */
+
+enum dump_file_index
+{
+ DFI_rtl,
+ DFI_sibling,
+ DFI_eh,
+ DFI_jump,
+ DFI_ssa,
+ DFI_ssa_ccp,
+ DFI_ssa_dce,
+ DFI_ussa,
+ DFI_cse,
+ DFI_addressof,
+ DFI_gcse,
+ DFI_loop,
+ DFI_cse2,
+ DFI_cfg,
+ DFI_bp,
+ DFI_life,
+ DFI_combine,
+ DFI_ce,
+ DFI_regmove,
+ DFI_sched,
+ DFI_lreg,
+ DFI_greg,
+ DFI_postreload,
+ DFI_flow2,
+ DFI_peephole2,
+ DFI_rnreg,
+ DFI_ce2,
+ DFI_sched2,
+ DFI_stack,
+ DFI_bbro,
+ DFI_mach,
+ DFI_dbr,
+ DFI_MAX
+};
+
+/* Describes all the dump files. Should be kept in order of the
+ pass and in sync with dump_file_index above.
+
+ Remaining -d letters:
+
+ " o q u "
+ " H JK OPQ TUV YZ"
+*/
+
+static struct dump_file_info dump_file[DFI_MAX] =
+{
+ { "rtl", 'r', 0, 0, 0 },
+ { "sibling", 'i', 0, 0, 0 },
+ { "eh", 'h', 0, 0, 0 },
+ { "jump", 'j', 0, 0, 0 },
+ { "ssa", 'e', 1, 0, 0 },
+ { "ssaccp", 'W', 1, 0, 0 },
+ { "ssadce", 'X', 1, 0, 0 },
+ { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "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 },
+ { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "combine", 'c', 1, 0, 0 },
+ { "ce", 'C', 1, 0, 0 },
+ { "regmove", 'N', 1, 0, 0 },
+ { "sched", 'S', 1, 0, 0 },
+ { "lreg", 'l', 1, 0, 0 },
+ { "greg", 'g', 1, 0, 0 },
+ { "postreload", 'o', 1, 0, 0 },
+ { "flow2", 'w', 1, 0, 0 },
+ { "peephole2", 'z', 1, 0, 0 },
+ { "rnreg", 'n', 1, 0, 0 },
+ { "ce2", 'E', 1, 0, 0 },
+ { "sched2", 'R', 1, 0, 0 },
+ { "stack", 'k', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
+ { "mach", 'M', 1, 0, 0 },
+ { "dbr", 'd', 0, 0, 0 },
+};
+
+static int open_dump_file PARAMS ((enum dump_file_index, tree));
+static void close_dump_file PARAMS ((enum dump_file_index,
+ void (*) (FILE *, rtx), rtx));
+
+/* Other flags saying which kinds of debugging dump have been requested. */
+
+int rtl_dump_and_exit;
+int flag_print_asm_name;
+static int version_flag;
+static char *filename;
enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
@@ -354,11 +365,16 @@ int optimize = 0;
int optimize_size = 0;
-/* Number of error messages and warning messages so far. */
+/* Nonzero if we should exit after parsing options. */
+static int exit_after_options = 0;
-int errorcount = 0;
-int warningcount = 0;
-int sorrycount = 0;
+/* The FUNCTION_DECL for the function currently being compiled,
+ or 0 if between functions. */
+tree current_function_decl;
+
+/* Set to the FUNC_BEGIN label of the current function, or NULL_TREE
+ if none. */
+tree current_function_func_begin_label;
/* Pointer to function to compute the name to use to print a declaration.
DECL is the declaration in question.
@@ -368,30 +384,28 @@ int sorrycount = 0;
2: and any other information that might be interesting, such as function
parameter types in C++. */
-char *(*decl_printable_name) PROTO ((tree, int));
+const char *(*decl_printable_name) PARAMS ((tree, int));
/* Pointer to function to compute rtl for a language-specific tree code. */
typedef rtx (*lang_expand_expr_t)
- PROTO ((union tree_node *, rtx, enum machine_mode,
+ PARAMS ((union tree_node *, rtx, enum machine_mode,
enum expand_modifier modifier));
lang_expand_expr_t lang_expand_expr = 0;
-tree (*lang_expand_constant) PROTO((tree)) = 0;
-
/* Pointer to function to finish handling an incomplete decl at the
end of compilation. */
-void (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
+void (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0;
-/* Nonzero if generating code to do profiling. */
+/* Nonzero if doing dwarf2 duplicate elimination. */
-int profile_flag = 0;
+int flag_eliminate_dwarf2_dups = 0;
-/* Nonzero if generating code to do profiling on a line-by-line basis. */
+/* Nonzero if generating code to do profiling. */
-int profile_block_flag;
+int profile_flag = 0;
/* Nonzero if generating code to profile program flow graph arcs. */
@@ -405,6 +419,15 @@ int flag_test_coverage = 0;
int flag_branch_probabilities = 0;
+/* Nonzero if basic blocks should be reordered. */
+
+int flag_reorder_blocks = 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. */
@@ -415,15 +438,23 @@ int pedantic = 0;
int in_system_header = 0;
-/* Nonzero means do stupid register allocation.
- Currently, this is 1 if `optimize' is 0. */
+/* Don't print functions as they are compiled. -quiet. */
+
+int quiet_flag = 0;
-int obey_regdecls = 0;
+/* Print times taken by the various passes. -ftime-report. */
-/* Don't print functions as they are compiled and don't print
- times taken by the various passes. -quiet. */
+int time_report = 0;
+
+/* Print memory still in use at end of compilation (which may have little
+ to do with peak memory consumption). -fmem-report. */
+
+int mem_report = 0;
+
+/* Non-zero means to collect statistics which might be expensive
+ and to print them when we are done. */
+int flag_detailed_statistics = 0;
-int quiet_flag = 0;
/* -f flags. */
@@ -512,13 +543,17 @@ int flag_unroll_loops;
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. */
+ outside the loop. */
int flag_move_all_movables = 0;
/* Nonzero forces all general induction variables in loops to be
- strength reduced. */
+ strength reduced. */
int flag_reduce_all_givs = 0;
@@ -549,28 +584,38 @@ int flag_omit_frame_pointer = 0;
int flag_function_sections = 0;
/* ... and similar for data. */
-
+
int flag_data_sections = 0;
/* Nonzero to inhibit use of define_optimization peephole opts. */
int flag_no_peephole = 0;
-/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
- operations in the interest of optimization. For example it allows
- GCC to assume arguments to sqrt are nonnegative numbers, allowing
- faster code for sqrt to be generated. */
+/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
-int flag_fast_math = 0;
+int flag_optimize_sibling_calls = 0;
/* Nonzero means the front end generally wants `errno' maintained by math
- operations, like built-in SQRT, unless overridden by flag_fast_math. */
+ operations, like built-in SQRT. */
int flag_errno_math = 1;
+/* Nonzero means that unsafe floating-point math optimizations are allowed
+ for the sake of speed. IEEE compliance is not guaranteed, and operations
+ are allowed to assume that their arguments and results are "normal"
+ (e.g., nonnegative for SQRT). */
+
+int flag_unsafe_math_optimizations = 0;
+
+/* Zero means that floating-point math operations cannot generate a
+ (user-visible) trap. This is the case, for example, in nonstop
+ IEEE 754 arithmetic. */
+
+int flag_trapping_math = 1;
+
/* 0 means straightforward implementation of complex divide acceptable.
1 means wide ranges of inputs must work for complex divide.
- 2 means C9X-like requirements for complex divide (not yet implemented). */
+ 2 means C99-like requirements for complex divide (not yet implemented). */
int flag_complex_divide_method = 0;
@@ -594,6 +639,23 @@ int flag_syntax_only = 0;
static int flag_gcse;
+/* Nonzero means to use global dataflow analysis to eliminate
+ useless null pointer tests. */
+
+static int flag_delete_null_pointer_checks;
+
+/* Nonzero means to do the enhanced load motion during gcse, which trys
+ to hoist loads by not killing them when a store to the same location
+ is seen. */
+
+int flag_gcse_lm = 1;
+
+/* Nonzero means to perform store motion after gcse, which will try to
+ move stores closer to the exit block. Its not very effective without
+ flag_gcse_lm. */
+
+int flag_gcse_sm = 1;
+
/* Nonzero means to rerun cse after loop optimization. This increases
compilation time about 20% and picks up a few more common expressions. */
@@ -651,10 +713,13 @@ int flag_pic;
int flag_exceptions;
-/* Nonzero means use the new model for exception handling. Replaces
- -DNEW_EH_MODEL as a compile option. */
+/* Nonzero means generate frame unwind info table when supported. */
-int flag_new_exceptions = 0;
+int flag_unwind_tables = 0;
+
+/* Nonzero means generate frame unwind info table exact at each insn boundary */
+
+int flag_asynchronous_unwind_tables = 0;
/* Nonzero means don't place uninitialized global data in common storage
by default. */
@@ -680,7 +745,6 @@ int flag_pedantic_errors = 0;
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
-#ifdef HAIFA
/* The following flags have effect only for scheduling before register
allocation:
@@ -695,14 +759,15 @@ int flag_schedule_interblock = 1;
int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
-#endif /* HAIFA */
-/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
- by a cheaper branch, on a count register. */
-int flag_branch_on_count_reg;
+int flag_single_precision_constant;
+
+/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
+ by a cheaper branch on a count register. */
+int flag_branch_on_count_reg = 1;
/* -finhibit-size-directive inhibits output of .size for ELF.
- This is used only for compiling crtstuff.c,
+ This is used only for compiling crtstuff.c,
and it may be extended to other effects
needed for crtstuff.c on other systems. */
int flag_inhibit_size_directive = 0;
@@ -725,6 +790,10 @@ int flag_verbose_asm = 0;
int flag_debug_asm = 0;
+/* -dP causes the rtl to be emitted as a comment in assembly. */
+
+int flag_dump_rtl_in_asm = 0;
+
/* -fgnu-linker specifies use of the GNU linker for initializations.
(Or, more generally, a linker that handles initializations.)
-fno-gnu-linker says that collect2 will be used. */
@@ -734,7 +803,16 @@ int flag_gnu_linker = 0;
int flag_gnu_linker = 1;
#endif
-/* Tag all structures with __attribute__(packed) */
+/* Enable SSA. */
+int flag_ssa = 0;
+
+/* Enable ssa conditional constant propagation. */
+int flag_ssa_ccp = 0;
+
+/* Enable ssa aggressive dead code elimination. */
+int flag_ssa_dce = 0;
+
+/* Tag all structures with __attribute__(packed). */
int flag_pack_struct = 0;
/* Nonzero means that -Wformat accepts certain system-dependent formats. */
@@ -744,15 +822,14 @@ int flag_format_extensions = 0;
to be allocated dynamically. */
int flag_stack_check;
-/* -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;
+/* When non-NULL, indicates that whenever space is allocated on the
+ stack, the resulting stack pointer must not pass this
+ address---that is, for stacks that grow downward, the stack pointer
+ must always be greater than or equal to this address; for stacks
+ that grow upward, the stack pointer must be less than this address.
+ At present, the rtx may be either a REG or a SYMBOL_REF, although
+ the support provided depends on the backend. */
+rtx stack_limit_rtx;
/* 0 if pointer arguments may alias each other. True in C.
1 if pointer arguments may not alias each other but may alias
@@ -777,58 +854,116 @@ int flag_instrument_function_entry_exit = 0;
int flag_no_ident = 0;
+/* This will perform a peephole pass before sched2. */
+int flag_peephole2 = 0;
+
+/* This will try to guess branch probabilities. */
+int flag_guess_branch_prob = 0;
+
+/* -fbounded-pointers causes gcc to compile pointers as composite
+ objects occupying three words: the pointer value, the base address
+ of the referent object, and the address immediately beyond the end
+ of the referent object. The base and extent allow us to perform
+ runtime bounds checking. -fbounded-pointers implies -fcheck-bounds. */
+int flag_bounded_pointers = 0;
+
+/* -fcheck-bounds causes gcc to generate array bounds checks.
+ For C, C++: defaults to value of flag_bounded_pointers.
+ For ObjC: defaults to off.
+ For Java: defaults to on.
+ For Fortran: defaults to off.
+ For CHILL: defaults to off. */
+int flag_bounds_check = 0;
+
+/* This will attempt to merge constant section constants, if 1 only
+ string constants and constants from constant pool, if 2 also constant
+ variables. */
+int flag_merge_constants = 1;
+
+/* If one, renumber instruction UIDs to reduce the number of
+ unused UIDs if there are a lot of instructions. If greater than
+ one, unconditionally renumber instruction UIDs. */
+int flag_renumber_insns = 1;
+
+/* Values of the -falign-* flags: how much to align labels in code.
+ 0 means `use default', 1 means `don't align'.
+ For each variable, there is an _log variant which is the power
+ of two not less than the variable, for .align output. */
+
+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;
+
/* Table of supported debugging formats. */
-static struct
+static const struct
{
- const char * arg;
+ const char *const arg;
/* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
constant expression, we use NO_DEBUG in its place. */
- enum debug_info_type debug_type;
- int use_extensions_p;
- const char * description;
+ const enum debug_info_type debug_type;
+ const int use_extensions_p;
+ const char *const description;
} *da,
debug_args[] =
{
- { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
- "Generate default debug format output" },
- { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
+ { "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
+ N_("Generate debugging info in default format") },
+ { "gdb", NO_DEBUG, 1, N_("Generate debugging info in default extended format") },
#ifdef DBX_DEBUGGING_INFO
- { "gstabs", DBX_DEBUG, 0, "Generate STABS format debug output" },
- { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
+ { "stabs", DBX_DEBUG, 0, N_("Generate STABS format debug info") },
+ { "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") },
#endif
#ifdef DWARF_DEBUGGING_INFO
- { "gdwarf", DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
- { "gdwarf+", DWARF_DEBUG, 1,
- "Generated extended DWARF-1 format debug output" },
+ { "dwarf", DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") },
+ { "dwarf+", DWARF_DEBUG, 1,
+ N_("Generate extended DWARF-1 format debug info") },
#endif
#ifdef DWARF2_DEBUGGING_INFO
- { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
+ { "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") },
#endif
#ifdef XCOFF_DEBUGGING_INFO
- { "gxcoff", XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
- { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
+ { "xcoff", XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") },
+ { "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") },
#endif
#ifdef SDB_DEBUGGING_INFO
- { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
+ { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") },
#endif
{ 0, 0, 0, 0 }
};
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;
+int flag_trapv = 0;
+
/* Add or remove a leading underscore from user symbols. */
int flag_leading_underscore = -1;
/* The user symbol prefix after having resolved same. */
const char *user_label_prefix;
+static const param_info lang_independent_params[] = {
+#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT) \
+ { OPTION, DEFAULT, HELP },
+#include "params.def"
+#undef DEFPARAM
+ { NULL, 0, NULL }
+};
+
/* A default for same. */
#ifndef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX ""
@@ -840,163 +975,211 @@ const char *user_label_prefix;
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[] =
{
+ {"format-extensions", &flag_format_extensions, 1,
+ N_("-Wformat accepts certain FreeBSD system-dependent formats") },
+ {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
+ N_("Perform DWARF2 duplicate elimination") },
{"float-store", &flag_float_store, 1,
- "Do not store floats in registers" },
+ N_("Do not store floats in registers") },
{"volatile", &flag_volatile, 1,
- "Consider all mem refs through pointers as volatile"},
+ N_("Consider all mem refs through pointers as volatile") },
{"volatile-global", &flag_volatile_global, 1,
- "Consider all mem refs to global data to be volatile" },
+ N_("Consider all mem refs to global data to be volatile") },
{"volatile-static", &flag_volatile_static, 1,
- "Consider all mem refs to static data to be volatile" },
+ N_("Consider all mem refs to static data to be volatile") },
{"defer-pop", &flag_defer_pop, 1,
- "Defer popping functions args from stack until later" },
+ N_("Defer popping functions args from stack until later") },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
- "When possible do not generate stack frames"},
+ N_("When possible do not generate stack frames") },
+ {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
+ N_("Optimize sibling and tail recursive calls") },
{"cse-follow-jumps", &flag_cse_follow_jumps, 1,
- "When running CSE, follow jumps to their targets" },
+ N_("When running CSE, follow jumps to their targets") },
{"cse-skip-blocks", &flag_cse_skip_blocks, 1,
- "When running CSE, follow conditional jumps" },
+ N_("When running CSE, follow conditional jumps") },
{"expensive-optimizations", &flag_expensive_optimizations, 1,
- "Perform a number of minor, expensive optimisations" },
+ N_("Perform a number of minor, expensive optimizations") },
{"thread-jumps", &flag_thread_jumps, 1,
- "Perform jump threading optimisations"},
+ N_("Perform jump threading optimizations") },
{"strength-reduce", &flag_strength_reduce, 1,
- "Perform strength reduction optimisations" },
+ N_("Perform strength reduction optimizations") },
{"unroll-loops", &flag_unroll_loops, 1,
- "Perform loop unrolling when iteration count is known" },
+ N_("Perform loop unrolling when iteration count is known") },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
- "Perform loop unrolling for all loops" },
+ 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,
- "Force all loop invariant computations out of loops" },
+ N_("Force all loop invariant computations out of loops") },
{"reduce-all-givs", &flag_reduce_all_givs, 1,
- "Strength reduce all loop general induction variables" },
+ N_("Strength reduce all loop general induction variables") },
{"writable-strings", &flag_writable_strings, 1,
- "Store strings in writable data section" },
+ N_("Store strings in writable data section") },
{"peephole", &flag_no_peephole, 0,
- "Enable machine specific peephole optimisations" },
+ N_("Enable machine specific peephole optimizations") },
{"force-mem", &flag_force_mem, 1,
- "Copy memory operands into registers before using" },
+ N_("Copy memory operands into registers before using") },
{"force-addr", &flag_force_addr, 1,
- "Copy memory address constants into regs before using" },
+ N_("Copy memory address constants into regs before using") },
{"function-cse", &flag_no_function_cse, 0,
- "Allow function addresses to be held in registers" },
+ N_("Allow function addresses to be held in registers") },
{"inline-functions", &flag_inline_functions, 1,
- "Integrate simple functions into their callers" },
+ N_("Integrate simple functions into their callers") },
{"keep-inline-functions", &flag_keep_inline_functions, 1,
- "Generate code for funcs even if they are fully inlined" },
+ N_("Generate code for funcs even if they are fully inlined") },
{"inline", &flag_no_inline, 0,
- "Pay attention to the 'inline' keyword"},
+ N_("Pay attention to the 'inline' keyword") },
{"keep-static-consts", &flag_keep_static_consts, 1,
- "Emit static const variables even if they are not used" },
+ N_("Emit static const variables even if they are not used") },
{"syntax-only", &flag_syntax_only, 1,
- "Check for syntax errors, then stop" },
+ N_("Check for syntax errors, then stop") },
{"shared-data", &flag_shared_data, 1,
- "Mark data as shared rather than private" },
+ N_("Mark data as shared rather than private") },
{"caller-saves", &flag_caller_saves, 1,
- "Enable saving registers around function calls" },
+ N_("Enable saving registers around function calls") },
{"pcc-struct-return", &flag_pcc_struct_return, 1,
- "Return 'short' aggregates in memory, not registers" },
+ N_("Return 'short' aggregates in memory, not registers") },
{"reg-struct-return", &flag_pcc_struct_return, 0,
- "Return 'short' aggregates in registers" },
+ N_("Return 'short' aggregates in registers") },
{"delayed-branch", &flag_delayed_branch, 1,
- "Attempt to fill delay slots of branch instructions" },
+ N_("Attempt to fill delay slots of branch instructions") },
{"gcse", &flag_gcse, 1,
- "Perform the global common subexpression elimination" },
+ N_("Perform the global common subexpression elimination") },
+ {"gcse-lm", &flag_gcse_lm, 1,
+ N_("Perform enhanced load motion during global subexpression elimination") },
+ {"gcse-sm", &flag_gcse_sm, 1,
+ N_("Perform store motion after global subexpression elimination") },
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
- "Run CSE pass after loop optimisations"},
+ N_("Run CSE pass after loop optimizations") },
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
- "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,
- "Pretend that host and target use the same FP format"},
+ N_("Pretend that host and target use the same FP format") },
{"schedule-insns", &flag_schedule_insns, 1,
- "Reschedule instructions to avoid pipeline stalls"},
+ N_("Reschedule instructions before register allocation") },
{"schedule-insns2", &flag_schedule_insns_after_reload, 1,
- "Run two passes of the instruction scheduler"},
-#ifdef HAIFA
+ N_("Reschedule instructions after register allocation") },
{"sched-interblock",&flag_schedule_interblock, 1,
- "Enable scheduling across basic blocks" },
+ N_("Enable scheduling across basic blocks") },
{"sched-spec",&flag_schedule_speculative, 1,
- "Allow speculative motion of non-loads" },
+ N_("Allow speculative motion of non-loads") },
{"sched-spec-load",&flag_schedule_speculative_load, 1,
- "Allow speculative motion of some loads" },
+ N_("Allow speculative motion of some loads") },
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
- "Allow speculative motion of more loads" },
-#endif /* HAIFA */
+ N_("Allow speculative motion of more loads") },
{"branch-count-reg",&flag_branch_on_count_reg, 1,
- "Replace add,compare,branch with branch on count reg"},
+ N_("Replace add,compare,branch with branch on count reg") },
{"pic", &flag_pic, 1,
- "Generate position independent code, if possible"},
+ N_("Generate position independent code, if possible") },
{"PIC", &flag_pic, 2, ""},
{"exceptions", &flag_exceptions, 1,
- "Enable exception handling" },
- {"new-exceptions", &flag_new_exceptions, 1,
- "Use the new model for exception handling" },
- {"sjlj-exceptions", &exceptions_via_longjmp, 1,
- "Use setjmp/longjmp to handle exceptions" },
- {"asynchronous-exceptions", &asynchronous_exceptions, 1,
- "Support asynchronous exceptions" },
+ N_("Enable exception handling") },
+ {"unwind-tables", &flag_unwind_tables, 1,
+ N_("Just generate unwind tables for exception handling") },
+ {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1,
+ N_("Generate unwind tables exact at each instruction boundary") },
+ {"non-call-exceptions", &flag_non_call_exceptions, 1,
+ N_("Support synchronous non-call exceptions") },
{"profile-arcs", &profile_arc_flag, 1,
- "Insert arc based program profiling code" },
+ N_("Insert arc based program profiling code") },
{"test-coverage", &flag_test_coverage, 1,
- "Create data files needed by gcov" },
+ N_("Create data files needed by gcov") },
{"branch-probabilities", &flag_branch_probabilities, 1,
- "Use profiling information for branch probabilities" },
- {"fast-math", &flag_fast_math, 1,
- "Improve FP speed by violating ANSI & IEEE rules" },
+ N_("Use profiling information for branch probabilities") },
+ {"reorder-blocks", &flag_reorder_blocks, 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,
- "Do not put unitialised globals in the common section" },
+ N_("Do not put uninitialized globals in the common section") },
{"inhibit-size-directive", &flag_inhibit_size_directive, 1,
- "Do not generate .size directives" },
+ N_("Do not generate .size directives") },
{"function-sections", &flag_function_sections, 1,
- "place each function into its own section" },
+ N_("place each function into its own section") },
{"data-sections", &flag_data_sections, 1,
- "place data items into their own section" },
+ N_("place data items into their own section") },
{"verbose-asm", &flag_verbose_asm, 1,
- "Add extra commentry to assembler output"},
+ N_("Add extra commentry to assembler output") },
{"gnu-linker", &flag_gnu_linker, 1,
- "Output GNU ld formatted global initialisers"},
+ N_("Output GNU ld formatted global initializers") },
{"regmove", &flag_regmove, 1,
- "Enables a register move optimisation"},
+ N_("Enables a register move optimization") },
{"optimize-register-move", &flag_regmove, 1,
- "Do the full regmove optimization pass"},
+ N_("Do the full regmove optimization pass") },
{"pack-struct", &flag_pack_struct, 1,
- "Pack structure members together without holes" },
- {"format-extensions", &flag_format_extensions, 1,
- "-Wformat accepts certain FreeBSD system-dependent formats" },
+ N_("Pack structure members together without holes") },
{"stack-check", &flag_stack_check, 1,
- "Insert stack checking code into the program" },
+ N_("Insert stack checking code into the program") },
{"argument-alias", &flag_argument_noalias, 0,
- "Specify that arguments may alias each other & globals"},
+ N_("Specify that arguments may alias each other & globals") },
{"argument-noalias", &flag_argument_noalias, 1,
- "Assume arguments may alias globals but not each other"},
+ N_("Assume arguments may alias globals but not each other") },
{"argument-noalias-global", &flag_argument_noalias, 2,
- "Assume arguments do not alias each other or globals" },
+ N_("Assume arguments do not alias each other or globals") },
{"strict-aliasing", &flag_strict_aliasing, 1,
- "Assume strict aliasing rules apply" },
- {"check-memory-usage", &flag_check_memory_usage, 1,
- "Generate code to check every memory access" },
- {"prefix-function-name", &flag_prefix_function_name, 1,
- "Add a prefix to all function names" },
+ N_("Assume strict aliasing rules apply") },
+ {"align-loops", &align_loops, 0,
+ N_("Align the start of loops") },
+ {"align-jumps", &align_jumps, 0,
+ N_("Align labels which are only reached by jumping") },
+ {"align-labels", &align_labels, 0,
+ N_("Align all labels") },
+ {"align-functions", &align_functions, 0,
+ N_("Align the start of functions") },
+ {"merge-constants", &flag_merge_constants, 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") },
{"dump-unnumbered", &flag_dump_unnumbered, 1,
- "Suppress output of instruction numbers and line number notes in debugging dumps"},
+ N_("Suppress output of instruction numbers and line number notes in debugging dumps") },
{"instrument-functions", &flag_instrument_function_entry_exit, 1,
- "Instrument function entry/exit with profiling calls"},
+ N_("Instrument function entry/exit with profiling calls") },
+ {"ssa", &flag_ssa, 1,
+ N_("Enable SSA optimizations") },
+ {"ssa-ccp", &flag_ssa_ccp, 1,
+ 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,
- "External symbols have a leading underscore" },
+ N_("External symbols have a leading underscore") },
{"ident", &flag_no_ident, 0,
- "Process #ident directives"}
+ N_("Process #ident directives") },
+ { "peephole2", &flag_peephole2, 1,
+ N_("Enables an rtl peephole pass run before sched2") },
+ { "guess-branch-probability", &flag_guess_branch_prob, 1,
+ N_("Enables guessing of branch probabilities") },
+ {"math-errno", &flag_errno_math, 1,
+ N_("Set errno after built-in math functions") },
+ {"trapping-math", &flag_trapping_math, 1,
+ N_("Floating-point operations can trap") },
+ {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
+ N_("Allow math optimizations that may violate IEEE or ANSI standards") },
+ {"bounded-pointers", &flag_bounded_pointers, 1,
+ N_("Compile pointers as triples: value, base & end") },
+ {"bounds-check", &flag_bounds_check, 1,
+ N_("Generate code to check bounds before dereferencing pointers and arrays") },
+ {"single-precision-constant", &flag_single_precision_constant, 1,
+ N_("Convert floating point constant to single precision constant") },
+ {"time-report", &time_report, 1,
+ N_("Report time taken by each compiler pass at end of run") },
+ {"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") },
};
-#define NUM_ELEM(a) (sizeof (a) / sizeof ((a)[0]))
-
/* Table of language-specific options. */
-static struct lang_opt
+static const struct lang_opt
{
- const char * option;
- const char * description;
+ const char *const option;
+ const char *const description;
}
documented_lang_options[] =
{
@@ -1004,160 +1187,173 @@ documented_lang_options[] =
used here is to only describe those options which are not
enabled by default. */
- { "-ansi", "Compile just for ANSI C" },
+ { "-ansi",
+ N_("Compile just for ISO C89") },
{ "-fallow-single-precision",
- "Do not promote floats to double if using -traditional" },
- { "-std= ", "Determine language standard"},
+ N_("Do not promote floats to double if using -traditional") },
+ { "-std= ",
+ N_("Determine language standard") },
{ "-fsigned-bitfields", "" },
- { "-funsigned-bitfields","Make bitfields by unsigned by default" },
+ { "-funsigned-bitfields",
+ N_("Make bit-fields by unsigned by default") },
{ "-fno-signed-bitfields", "" },
{ "-fno-unsigned-bitfields","" },
- { "-fsigned-char", "Make 'char' be signed by default"},
- { "-funsigned-char", "Make 'char' be unsigned by default"},
+ { "-fsigned-char",
+ N_("Make 'char' be signed by default") },
+ { "-funsigned-char",
+ N_("Make 'char' be unsigned by default") },
{ "-fno-signed-char", "" },
{ "-fno-unsigned-char", "" },
{ "-ftraditional", "" },
- { "-traditional", "Attempt to support traditional K&R style C"},
+ { "-traditional",
+ N_("Attempt to support traditional K&R style C") },
{ "-fnotraditional", "" },
{ "-fno-traditional", "" },
{ "-fasm", "" },
- { "-fno-asm", "Do not recognise the 'asm' keyword" },
+ { "-fno-asm",
+ N_("Do not recognize the 'asm' keyword") },
{ "-fbuiltin", "" },
- { "-fno-builtin", "Do not recognise any built in functions" },
- { "-fhosted", "Assume normal C execution environment" },
+ { "-fno-builtin",
+ N_("Do not recognize any built in functions") },
+ { "-fhosted",
+ N_("Assume normal C execution environment") },
{ "-fno-hosted", "" },
{ "-ffreestanding",
- "Assume that standard libraries & main might not exist" },
+ N_("Assume that standard libraries & main might not exist") },
{ "-fno-freestanding", "" },
- { "-fcond-mismatch", "Allow different types as args of ? operator"},
+ { "-fcond-mismatch",
+ N_("Allow different types as args of ? operator") },
{ "-fno-cond-mismatch", "" },
- { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
+ { "-fdollars-in-identifiers",
+ N_("Allow the use of $ inside identifiers") },
{ "-fno-dollars-in-identifiers", "" },
- { "-fshort-double", "Use the same size for double as for float" },
+ { "-fpreprocessed", "" },
+ { "-fno-preprocessed", "" },
+ { "-fshort-double",
+ N_("Use the same size for double as for float") },
{ "-fno-short-double", "" },
- { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
+ { "-fshort-enums",
+ N_("Use the smallest fitting integer to hold enums") },
{ "-fno-short-enums", "" },
+ { "-fshort-wchar",
+ N_("Override the underlying type for wchar_t to `unsigned short'") },
+ { "-fno-short-wchar", "" },
- { "-Wall", "Enable most warning messages" },
+ { "-Wall",
+ N_("Enable most warning messages") },
{ "-Wbad-function-cast",
- "Warn about casting functions to incompatible types" },
+ N_("Warn about casting functions to incompatible types") },
{ "-Wno-bad-function-cast", "" },
- { "-Wmissing-noreturn",
- "Warn about functions which might be candidates for attribute noreturn" },
{ "-Wno-missing-noreturn", "" },
- { "-Wcast-qual", "Warn about casts which discard qualifiers"},
+ { "-Wmissing-format-attribute",
+ N_("Warn about functions which might be candidates for format attributes") },
+ { "-Wno-missing-format-attribute", "" },
+ { "-Wcast-qual",
+ N_("Warn about casts which discard qualifiers") },
{ "-Wno-cast-qual", "" },
- { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
+ { "-Wchar-subscripts",
+ N_("Warn about subscripts whose type is 'char'") },
{ "-Wno-char-subscripts", "" },
- { "-Wcomment", "Warn if nested comments are detected" },
+ { "-Wcomment",
+ N_("Warn if nested comments are detected") },
{ "-Wno-comment", "" },
- { "-Wcomments", "Warn if nested comments are detected" },
+ { "-Wcomments",
+ N_("Warn if nested comments are detected") },
{ "-Wno-comments", "" },
- { "-Wconversion", "Warn about possibly confusing type conversions" },
+ { "-Wconversion",
+ N_("Warn about possibly confusing type conversions") },
{ "-Wno-conversion", "" },
- { "-Wformat", "Warn about printf format anomalies" },
+ { "-Wformat",
+ N_("Warn about printf/scanf/strftime/strfmon format anomalies") },
{ "-Wno-format", "" },
+ { "-Wformat-y2k", "" },
+ { "-Wno-format-y2k",
+ N_("Don't warn about strftime formats yielding 2 digit years") },
+ { "-Wformat-extra-args", "" },
+ { "-Wno-format-extra-args",
+ N_("Don't warn about too many arguments to format functions") },
+ { "-Wformat-nonliteral",
+ N_("Warn about non-string-literal format strings") },
+ { "-Wno-format-nonliteral", "" },
+ { "-Wformat-security",
+ N_("Warn about possible security problems with format functions") },
+ { "-Wno-format-security", "" },
{ "-Wimplicit-function-declaration",
- "Warn about implicit function declarations" },
+ N_("Warn about implicit function declarations") },
{ "-Wno-implicit-function-declaration", "" },
{ "-Werror-implicit-function-declaration", "" },
- { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
+ { "-Wimplicit-int",
+ N_("Warn when a declaration does not specify a type") },
{ "-Wno-implicit-int", "" },
{ "-Wimplicit", "" },
{ "-Wno-implicit", "" },
- { "-Wimport", "Warn about the use of the #import directive" },
+ { "-Wimport",
+ N_("Warn about the use of the #import directive") },
{ "-Wno-import", "" },
{ "-Wlong-long","" },
- { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
- { "-Wmain", "Warn about suspicious declarations of main" },
+ { "-Wno-long-long",
+ N_("Do not warn about using 'long long' when -pedantic") },
+ { "-Wmain",
+ N_("Warn about suspicious declarations of main") },
{ "-Wno-main", "" },
{ "-Wmissing-braces",
- "Warn about possibly missing braces around initialisers" },
+ N_("Warn about possibly missing braces around initializers") },
{ "-Wno-missing-braces", "" },
{ "-Wmissing-declarations",
- "Warn about global funcs without previous declarations"},
+ N_("Warn about global funcs without previous declarations") },
{ "-Wno-missing-declarations", "" },
- { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
+ { "-Wmissing-prototypes",
+ N_("Warn about global funcs without prototypes") },
{ "-Wno-missing-prototypes", "" },
- { "-Wmultichar", "Warn about use of multicharacter literals"},
+ { "-Wmultichar",
+ N_("Warn about use of multicharacter literals") },
{ "-Wno-multichar", "" },
- { "-Wnested-externs", "Warn about externs not at file scope level" },
+ { "-Wnested-externs",
+ N_("Warn about externs not at file scope level") },
{ "-Wno-nested-externs", "" },
- { "-Wparentheses", "Warn about possible missing parentheses" },
+ { "-Wparentheses",
+ N_("Warn about possible missing parentheses") },
{ "-Wno-parentheses", "" },
- { "-Wpointer-arith", "Warn about function pointer arithmetic" },
+ { "-Wsequence-point",
+ N_("Warn about possible violations of sequence point rules") },
+ { "-Wno-sequence-point", "" },
+ { "-Wpointer-arith",
+ N_("Warn about function pointer arithmetic") },
{ "-Wno-pointer-arith", "" },
{ "-Wredundant-decls",
- "Warn about multiple declarations of the same object" },
+ N_("Warn about multiple declarations of the same object") },
{ "-Wno-redundant-decls", "" },
- { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
+ { "-Wsign-compare",
+ N_("Warn about signed/unsigned comparisons") },
{ "-Wno-sign-compare", "" },
- { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
+ { "-Wfloat-equal",
+ N_("Warn about testing equality of floating point numbers") },
+ { "-Wno-float-equal", "" },
+ { "-Wunknown-pragmas",
+ N_("Warn about unrecognized pragmas") },
{ "-Wno-unknown-pragmas", "" },
- { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
+ { "-Wstrict-prototypes",
+ N_("Warn about non-prototyped function decls") },
{ "-Wno-strict-prototypes", "" },
- { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
+ { "-Wtraditional",
+ N_("Warn about constructs whose meaning change in ISO C") },
{ "-Wno-traditional", "" },
- { "-Wtrigraphs", "Warn when trigraphs are encountered" },
+ { "-Wtrigraphs",
+ N_("Warn when trigraphs are encountered") },
{ "-Wno-trigraphs", "" },
{ "-Wundef", "" },
{ "-Wno-undef", "" },
- { "-Wwrite-strings", "Mark strings as 'const char *'"},
+ { "-Wwrite-strings",
+ N_("Mark strings as 'const char *'") },
{ "-Wno-write-strings", "" },
- /* These are for languages with USE_CPPLIB. */
- /* These options are already documented in cpplib.c */
- { "--help", "" },
- { "-A", "" },
- { "-D", "" },
- { "-I", "" },
-#if USE_CPPLIB
- { "-MD", "Print dependencies to FILE.d" },
- { "-MMD", "Print dependencies to FILE.d" },
- { "-M", "Print dependencies to stdout" },
- { "-MM", "Print dependencies to stdout" },
-#endif /* USE_CPPLIB */
- { "-U", "" },
- { "-H", "" },
- { "-idirafter", "" },
- { "-imacros", "" },
- { "-include", "" },
- { "-iprefix", "" },
- { "-isystem", "" },
- { "-iwithprefix", "" },
- { "-iwithprefixbefore", "" },
- { "-lang-c", "" },
- { "-lang-c89", "" },
- { "-lang-c++", "" },
- { "-remap", "" },
- { "-nostdinc", "" },
- { "-nostdinc++", "" },
- { "-trigraphs", "" },
- { "-undef", "" },
-
#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
-
- /* These are for obj c. */
- DEFINE_LANG_NAME ("Objective C")
-
- { "-lang-objc", "" },
- { "-gen-decls", "Dump decls to a .decl file" },
- { "-fgnu-runtime", "Generate code for GNU runtime environment" },
- { "-fno-gnu-runtime", "" },
- { "-fnext-runtime", "Generate code for NeXT runtime environment" },
- { "-fno-next-runtime", "" },
- { "-Wselector", "Warn if a selector has multiple methods" },
- { "-Wno-selector", "" },
- { "-Wprotocol", "" },
- { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
- { "-print-objc-runtime-info",
- "Generate C header of platform specific features" },
#include "options.h"
-
+
};
/* Here is a table, controlled by the tm.h file, listing each -m switch
@@ -1166,32 +1362,36 @@ documented_lang_options[] =
If VALUE is negative, -VALUE is bits to clear.
(The sign bit is not used so there is no confusion.) */
-struct
+static const struct
{
- const char * name;
- int value;
- const char * description;
+ const char *const name;
+ const int value;
+ const char *const description;
}
target_switches [] = TARGET_SWITCHES;
/* This table is similar, but allows the switch to have a value. */
#ifdef TARGET_OPTIONS
-struct
+static const struct
{
- const char * prefix;
- const char ** variable;
- const char * description;
+ const char *const prefix;
+ const char **const variable;
+ const char *const description;
}
target_options [] = TARGET_OPTIONS;
#endif
-/* Options controlling warnings */
+/* Options controlling warnings. */
/* Don't print warning messages. -w. */
int inhibit_warnings = 0;
+/* Don't suppress warnings from system headers. -Wsystem-headers. */
+
+int warn_system_headers = 0;
+
/* Print various extra warnings. -W. */
int extra_warnings = 0;
@@ -1200,15 +1400,23 @@ int extra_warnings = 0;
int warnings_are_errors = 0;
-/* Nonzero to warn about unused local variables. */
+/* Nonzero to warn about unused variables, functions et.al. */
+
+int warn_unused_function;
+int warn_unused_label;
+int warn_unused_parameter;
+int warn_unused_variable;
+int warn_unused_value;
-int warn_unused;
+/* Nonzero to warn about code which is never reached. */
+
+int warn_notreached;
/* Nonzero to warn about variables used before they are initialized. */
int warn_uninitialized;
-/* Nonzero means warn about all declarations which shadow others. */
+/* Nonzero means warn about all declarations which shadow others. */
int warn_shadow;
@@ -1227,18 +1435,12 @@ int warn_return_type;
int warn_cast_align;
-/* Nonzero means warn about any identifiers that match in the first N
- characters. The value N is in `id_clash_len'. */
-
-int warn_id_clash;
-unsigned id_clash_len;
-
/* Nonzero means warn about any objects definitions whose size is larger
than N bytes. Also want about function definitions whose returned
values are larger than N bytes. The value N is in `larger_than_size'. */
-
+
int warn_larger_than;
-unsigned larger_than_size;
+HOST_WIDE_INT larger_than_size;
/* Nonzero means warn if inline function is too large. */
@@ -1249,24 +1451,107 @@ int warn_inline;
int warn_aggregate_return;
+/* Warn if packed attribute on struct is unnecessary and inefficient. */
+
+int warn_packed;
+
+/* Warn when gcc pads a structure to an alignment boundary. */
+
+int warn_padded;
+
+/* Warn when an optimization pass is disabled. */
+
+int warn_disabled_optimization;
+
+/* Warn about functions which might be candidates for attribute noreturn. */
+
+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", &warn_unused, 1, "Warn when a variable is unused" },
- {"error", &warnings_are_errors, 1, ""},
- {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
+ {"unused-function", &warn_unused_function, 1,
+ N_("Warn when a function is unused") },
+ {"unused-label", &warn_unused_label, 1,
+ N_("Warn when a label is unused") },
+ {"unused-parameter", &warn_unused_parameter, 1,
+ N_("Warn when a function parameter is unused") },
+ {"unused-variable", &warn_unused_variable, 1,
+ N_("Warn when a variable is unused") },
+ {"unused-value", &warn_unused_value, 1,
+ N_("Warn when an expression value is unused") },
+ {"system-headers", &warn_system_headers, 1,
+ N_("Do not suppress warnings from system headers") },
+ {"error", &warnings_are_errors, 1,
+ N_("Treat all warnings as errors") },
+ {"shadow", &warn_shadow, 1,
+ N_("Warn when one local variable shadows another") },
{"switch", &warn_switch, 1,
- "Warn about enumerated switches missing a specific case" },
+ N_("Warn about enumerated switches missing a specific case") },
{"aggregate-return", &warn_aggregate_return, 1,
- "Warn about returning structures, unions or arrays" },
+ N_("Warn about returning structures, unions or arrays") },
{"cast-align", &warn_cast_align, 1,
- "Warn about pointer casts which increase alignment" },
+ N_("Warn about pointer casts which increase alignment") },
+ {"unreachable-code", &warn_notreached, 1,
+ N_("Warn about code that will never be executed") },
{"uninitialized", &warn_uninitialized, 1,
- "Warn about unitialized automatic variables"},
+ N_("Warn about uninitialized automatic variables") },
{"inline", &warn_inline, 1,
- "Warn when an inlined function cannot be inlined"}
+ N_("Warn when an inlined function cannot be inlined") },
+ {"packed", &warn_packed, 1,
+ N_("Warn when the packed attribute has no effect on struct layout") },
+ {"padded", &warn_padded, 1,
+ 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. */
+
+void
+set_fast_math_flags ()
+{
+ flag_trapping_math = 0;
+ flag_unsafe_math_optimizations = 1;
+ flag_errno_math = 0;
+}
+
+void
+set_no_fast_math_flags ()
+{
+ flag_trapping_math = 1;
+ flag_unsafe_math_optimizations = 0;
+ flag_errno_math = 1;
+}
+
/* Output files for assembler code (real compiler output)
and debugging dumps. */
@@ -1278,8 +1563,8 @@ FILE *rtl_dump_file = NULL;
/* Decode the string P as an integral parameter.
If the string is indeed an integer return its numeric value else
issue an Invalid Option error for the option PNAME and return DEFVAL.
- If PNAME is zero just return DEFVAL, do not call error. */
-
+ If PNAME is zero just return DEFVAL, do not call error. */
+
int
read_integral_parameter (p, pname, defval)
const char *p;
@@ -1290,7 +1575,7 @@ read_integral_parameter (p, pname, defval)
while (*endp)
{
- if (*endp >= '0' && *endp <= '9')
+ if (ISDIGIT (*endp))
endp++;
else
break;
@@ -1299,211 +1584,17 @@ read_integral_parameter (p, pname, defval)
if (*endp != 0)
{
if (pname != 0)
- error ("Invalid option `%s'", pname);
+ error ("invalid option `%s'", pname);
return defval;
}
return atoi (p);
}
-
-/* Time accumulators, to count the total time spent in various passes. */
-
-int parse_time;
-int varconst_time;
-int integration_time;
-int jump_time;
-int cse_time;
-int gcse_time;
-int loop_time;
-int cse2_time;
-int branch_prob_time;
-int flow_time;
-int combine_time;
-int regmove_time;
-int sched_time;
-int local_alloc_time;
-int global_alloc_time;
-int flow2_time;
-int sched2_time;
-#ifdef DELAY_SLOTS
-int dbr_sched_time;
-#endif
-int shorten_branch_time;
-int stack_reg_time;
-int final_time;
-int symout_time;
-int dump_time;
-/* Return time used so far, in microseconds. */
-
-long
-get_run_time ()
-{
- if (quiet_flag)
- return 0;
-
-#ifdef __BEOS__
- return 0;
-#else /* not BeOS */
-#if defined (_WIN32) && !defined (__CYGWIN__)
- if (clock() < 0)
- return 0;
- else
- return (clock() * 1000);
-#else /* not _WIN32 */
-#ifdef _SC_CLK_TCK
- {
- static int tick;
- struct tms tms;
- if (tick == 0)
- tick = 1000000 / sysconf(_SC_CLK_TCK);
- times (&tms);
- return (tms.tms_utime + tms.tms_stime) * tick;
- }
-#else
-#ifdef USG
- {
- struct tms tms;
-# if HAVE_SYSCONF && defined _SC_CLK_TCK
-# define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
-# else
-# ifdef CLK_TCK
-# define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
-# else
-# define TICKS_PER_SECOND HZ /* traditional UNIX */
-# endif
-# endif
- times (&tms);
- return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
- }
-#else
-#ifndef VMS
- {
- struct rusage rusage;
- getrusage (0, &rusage);
- return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
- + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
- }
-#else /* VMS */
- {
- struct
- {
- int proc_user_time;
- int proc_system_time;
- int child_user_time;
- int child_system_time;
- } vms_times;
- times ((void *) &vms_times);
- return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
- }
-#endif /* VMS */
-#endif /* USG */
-#endif /* _SC_CLK_TCK */
-#endif /* _WIN32 */
-#endif /* __BEOS__ */
-}
-
-#define TIMEVAR(VAR, BODY) \
-do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
-
-void
-print_time (str, total)
- const char *str;
- int total;
-{
- fprintf (stderr,
- "time in %s: %d.%06d\n",
- str, total / 1000000, total % 1000000);
-}
-
-/* Count an error or warning. Return 1 if the message should be printed. */
-
-int
-count_error (warningp)
- int warningp;
-{
- if (warningp && inhibit_warnings)
- return 0;
-
- if (warningp && !warnings_are_errors)
- warningcount++;
- else
- {
- static int warning_message = 0;
-
- if (warningp && !warning_message)
- {
- notice ("%s: warnings being treated as errors\n", progname);
- warning_message = 1;
- }
- errorcount++;
- }
-
- return 1;
-}
-
-/* Print a fatal error message. NAME is the text.
- Also include a system error message based on `errno'. */
-
-void
-pfatal_with_name (name)
- const char *name;
-{
- fprintf (stderr, "%s: ", progname);
- perror (name);
- exit (FATAL_EXIT_CODE);
-}
-
-void
-fatal_io_error (name)
- const char *name;
-{
- notice ("%s: %s: I/O error\n", progname, name);
- exit (FATAL_EXIT_CODE);
-}
-
-/* Called to give a better error message for a bad insn rather than
- just calling abort(). */
-
-void
-fatal_insn VPROTO((const char *msgid, rtx insn, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
- rtx insn;
-#endif
- va_list ap;
-
- VA_START (ap, insn);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
- insn = va_arg (ap, rtx);
-#endif
-
- verror (msgid, ap);
- debug_rtx (insn);
- exit (FATAL_EXIT_CODE);
-}
-
-/* Called to give a better error message when we don't have an insn to match
- what we are looking for or if the insn's constraints aren't satisfied,
- rather than just calling abort(). */
-
-void
-fatal_insn_not_found (insn)
- rtx insn;
-{
- if (INSN_CODE (insn) < 0)
- fatal_insn ("internal error--unrecognizable insn:", insn);
- else
- fatal_insn ("internal error--insn does not satisfy its constraints:", insn);
-}
-
/* This is the default decl_printable_name function. */
-static char *
+static const char *
decl_name (decl, verbosity)
tree decl;
int verbosity ATTRIBUTE_UNUSED;
@@ -1511,782 +1602,6 @@ decl_name (decl, verbosity)
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
-static int need_error_newline;
-
-/* Function of last error message;
- more generally, function such that if next error message is in it
- then we don't have to mention the function name. */
-static tree last_error_function = NULL;
-
-/* Used to detect when input_file_stack has changed since last described. */
-static int last_error_tick;
-
-/* Called when the start of a function definition is parsed,
- this function prints on stderr the name of the function. */
-
-void
-announce_function (decl)
- tree decl;
-{
- if (! quiet_flag)
- {
- if (rtl_dump_and_exit)
- fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
- else
- fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
- fflush (stderr);
- need_error_newline = 1;
- last_error_function = current_function_decl;
- }
-}
-
-/* The default function to print out name of current function that caused
- an error. */
-
-void
-default_print_error_function (file)
- const char *file;
-{
- if (last_error_function != current_function_decl)
- {
- if (file)
- fprintf (stderr, "%s: ", file);
-
- if (current_function_decl == NULL)
- notice ("At top level:\n");
- else
- notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
- ? "In method `%s':\n"
- : "In function `%s':\n"),
- (*decl_printable_name) (current_function_decl, 2));
-
- last_error_function = current_function_decl;
- }
-}
-
-/* Called by report_error_function to print out function name.
- * Default may be overridden by language front-ends. */
-
-void (*print_error_function) PROTO((const char *)) =
- default_print_error_function;
-
-/* Prints out, if necessary, the name of the current function
- that caused an error. Called from all error and warning functions.
- We ignore the FILE parameter, as it cannot be relied upon. */
-
-void
-report_error_function (file)
- const char *file ATTRIBUTE_UNUSED;
-{
- struct file_stack *p;
-
- if (need_error_newline)
- {
- fprintf (stderr, "\n");
- need_error_newline = 0;
- }
-
- if (input_file_stack && input_file_stack->next != 0
- && input_file_stack_tick != last_error_tick)
- {
- for (p = input_file_stack->next; p; p = p->next)
- notice ((p == input_file_stack->next
- ? "In file included from %s:%d"
- : ",\n from %s:%d"),
- p->name, p->line);
- fprintf (stderr, ":\n");
- last_error_tick = input_file_stack_tick;
- }
-
- (*print_error_function) (input_filename);
-}
-
-/* Print a message. */
-
-static void
-vnotice (file, msgid, ap)
- FILE *file;
- char *msgid;
- va_list ap;
-{
- vfprintf (file, _(msgid), ap);
-}
-
-void
-notice VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, char *);
-#endif
-
- vnotice (stderr, msgid, ap);
- va_end (ap);
-}
-
-void
-fnotice VPROTO((FILE *file, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- FILE *file;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (ap, FILE *);
- msgid = va_arg (ap, const char *);
-#endif
-
- vnotice (file, msgid, ap);
- va_end (ap);
-}
-
-/* Report FILE and LINE (or program name), and optionally just WARN. */
-
-static void
-report_file_and_line (file, line, warn)
- char *file;
- int line;
- int warn;
-{
- if (file)
- fprintf (stderr, "%s:%d: ", file, line);
- else
- fprintf (stderr, "%s: ", progname);
-
- if (warn)
- notice ("warning: ");
-}
-
-/* Print a message. */
-
-static void
-vmessage (prefix, msgid, ap)
- const char *prefix;
- const char *msgid;
- va_list ap;
-{
- if (prefix)
- fprintf (stderr, "%s: ", prefix);
-
- vfprintf (stderr, msgid, ap);
-}
-
-/* Print a message relevant to line LINE of file FILE. */
-
-static void
-v_message_with_file_and_line (file, line, warn, msgid, ap)
- const char *file;
- int line;
- int warn;
- const char *msgid;
- va_list ap;
-{
- report_file_and_line (file, line, warn);
- vnotice (stderr, msgid, ap);
- fputc ('\n', stderr);
-}
-
-/* Print a message relevant to the given DECL. */
-
-static void
-v_message_with_decl (decl, warn, msgid, ap)
- tree decl;
- int warn;
- const char *msgid;
- va_list ap;
-{
- const char *p;
-
- report_file_and_line (DECL_SOURCE_FILE (decl),
- DECL_SOURCE_LINE (decl), warn);
-
- /* Do magic to get around lack of varargs support for insertion
- of arguments into existing list. We know that the decl is first;
- we ass_u_me that it will be printed with "%s". */
-
- for (p = _(msgid); *p; ++p)
- {
- if (*p == '%')
- {
- if (*(p + 1) == '%')
- ++p;
- else if (*(p + 1) != 's')
- abort ();
- else
- break;
- }
- }
-
- if (p > _(msgid)) /* Print the left-hand substring. */
- {
- char fmt[sizeof "%.255s"];
- long width = p - _(msgid);
-
- if (width > 255L) width = 255L; /* arbitrary */
- sprintf (fmt, "%%.%lds", width);
- fprintf (stderr, fmt, _(msgid));
- }
-
- if (*p == '%') /* Print the name. */
- {
- const char *n = (DECL_NAME (decl)
- ? (*decl_printable_name) (decl, 2)
- : "((anonymous))");
- fputs (n, stderr);
- while (*p)
- {
- ++p;
- if (ISALPHA (*(p - 1) & 0xFF))
- break;
- }
- }
-
- if (*p) /* Print the rest of the message. */
- vmessage ((char *)NULL, p, ap);
-
- fputc ('\n', stderr);
-}
-
-/* Figure file and line of the given INSN. */
-
-static void
-file_and_line_for_asm (insn, pfile, pline)
- rtx insn;
- char **pfile;
- int *pline;
-{
- rtx body = PATTERN (insn);
- rtx asmop;
-
- /* Find the (or one of the) ASM_OPERANDS in the insn. */
- if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
- asmop = SET_SRC (body);
- else if (GET_CODE (body) == ASM_OPERANDS)
- asmop = body;
- else if (GET_CODE (body) == PARALLEL
- && GET_CODE (XVECEXP (body, 0, 0)) == SET)
- asmop = SET_SRC (XVECEXP (body, 0, 0));
- else if (GET_CODE (body) == PARALLEL
- && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
- asmop = XVECEXP (body, 0, 0);
- else
- asmop = NULL;
-
- if (asmop)
- {
- *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
- *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
- }
- else
- {
- *pfile = input_filename;
- *pline = lineno;
- }
-}
-
-/* Report an error at line LINE of file FILE. */
-
-static void
-v_error_with_file_and_line (file, line, msgid, ap)
- const char *file;
- int line;
- const char *msgid;
- va_list ap;
-{
- count_error (0);
- report_error_function (file);
- v_message_with_file_and_line (file, line, 0, msgid, ap);
-}
-
-void
-error_with_file_and_line VPROTO((const char *file, int line,
- const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *file;
- int line;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (ap, const char *);
- line = va_arg (ap, int);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_error_with_file_and_line (file, line, msgid, ap);
- va_end (ap);
-}
-
-/* Report an error at the declaration DECL.
- MSGID is a format string which uses %s to substitute the declaration
- name; subsequent substitutions are a la printf. */
-
-static void
-v_error_with_decl (decl, msgid, ap)
- tree decl;
- const char *msgid;
- va_list ap;
-{
- count_error (0);
- report_error_function (DECL_SOURCE_FILE (decl));
- v_message_with_decl (decl, 0, msgid, ap);
-}
-
-void
-error_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- tree decl;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- decl = va_arg (ap, tree);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_error_with_decl (decl, msgid, ap);
- va_end (ap);
-}
-
-/* Report an error at the line number of the insn INSN.
- This is used only when INSN is an `asm' with operands,
- and each ASM_OPERANDS records its own source file and line. */
-
-static void
-v_error_for_asm (insn, msgid, ap)
- rtx insn;
- const char *msgid;
- va_list ap;
-{
- char *file;
- int line;
-
- count_error (0);
- file_and_line_for_asm (insn, &file, &line);
- report_error_function (file);
- v_message_with_file_and_line (file, line, 0, msgid, ap);
-}
-
-void
-error_for_asm VPROTO((rtx insn, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- rtx insn;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- insn = va_arg (ap, rtx);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_error_for_asm (insn, msgid, ap);
- va_end (ap);
-}
-
-/* Report an error at the current line number. */
-
-static void
-verror (msgid, ap)
- const char *msgid;
- va_list ap;
-{
- v_error_with_file_and_line (input_filename, lineno, msgid, ap);
-}
-
-void
-error VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
-
- verror (msgid, ap);
- va_end (ap);
-}
-
-/* Report a fatal error at the current line number. */
-
-static void
-vfatal (msgid, ap)
- const char *msgid;
- va_list ap;
-{
- verror (msgid, ap);
- exit (FATAL_EXIT_CODE);
-}
-
-void
-fatal VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
-
- vfatal (msgid, ap);
- va_end (ap);
-}
-
-/* Report a warning at line LINE of file FILE. */
-
-static void
-v_warning_with_file_and_line (file, line, msgid, ap)
- const char *file;
- int line;
- const char *msgid;
- va_list ap;
-{
- if (count_error (1))
- {
- report_error_function (file);
- v_message_with_file_and_line (file, line, 1, msgid, ap);
- }
-}
-
-void
-warning_with_file_and_line VPROTO((const char *file, int line,
- const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *file;
- int line;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (ap, const char *);
- line = va_arg (ap, int);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_warning_with_file_and_line (file, line, msgid, ap);
- va_end (ap);
-}
-
-/* Report a warning at the declaration DECL.
- MSGID is a format string which uses %s to substitute the declaration
- name; subsequent substitutions are a la printf. */
-
-static void
-v_warning_with_decl (decl, msgid, ap)
- tree decl;
- const char *msgid;
- va_list ap;
-{
- if (count_error (1))
- {
- report_error_function (DECL_SOURCE_FILE (decl));
- v_message_with_decl (decl, 1, msgid, ap);
- }
-}
-
-void
-warning_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- tree decl;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- decl = va_arg (ap, tree);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_warning_with_decl (decl, msgid, ap);
- va_end (ap);
-}
-
-/* Report a warning at the line number of the insn INSN.
- This is used only when INSN is an `asm' with operands,
- and each ASM_OPERANDS records its own source file and line. */
-
-static void
-v_warning_for_asm (insn, msgid, ap)
- rtx insn;
- const char *msgid;
- va_list ap;
-{
- if (count_error (1))
- {
- char *file;
- int line;
-
- file_and_line_for_asm (insn, &file, &line);
- report_error_function (file);
- v_message_with_file_and_line (file, line, 1, msgid, ap);
- }
-}
-
-void
-warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- rtx insn;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- insn = va_arg (ap, rtx);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_warning_for_asm (insn, msgid, ap);
- va_end (ap);
-}
-
-/* Report a warning at the current line number. */
-
-static void
-vwarning (msgid, ap)
- const char *msgid;
- va_list ap;
-{
- v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
-}
-
-void
-warning VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
-
- vwarning (msgid, ap);
- va_end (ap);
-}
-
-/* These functions issue either warnings or errors depending on
- -pedantic-errors. */
-
-static void
-vpedwarn (msgid, ap)
- const char *msgid;
- va_list ap;
-{
- if (flag_pedantic_errors)
- verror (msgid, ap);
- else
- vwarning (msgid, ap);
-}
-
-void
-pedwarn VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
-
- vpedwarn (msgid, ap);
- va_end (ap);
-}
-
-static void
-v_pedwarn_with_decl (decl, msgid, ap)
- tree decl;
- const char *msgid;
- va_list ap;
-{
- /* We don't want -pedantic-errors to cause the compilation to fail from
- "errors" in system header files. Sometimes fixincludes can't fix what's
- broken (eg: unsigned char bitfields - fixing it may change the alignment
- which will cause programs to mysteriously fail because the C library
- or kernel uses the original layout). There's no point in issuing a
- warning either, it's just unnecessary noise. */
-
- if (! DECL_IN_SYSTEM_HEADER (decl))
- {
- if (flag_pedantic_errors)
- v_error_with_decl (decl, msgid, ap);
- else
- v_warning_with_decl (decl, msgid, ap);
- }
-}
-
-void
-pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- tree decl;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- decl = va_arg (ap, tree);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_pedwarn_with_decl (decl, msgid, ap);
- va_end (ap);
-}
-
-static void
-v_pedwarn_with_file_and_line (file, line, msgid, ap)
- const char *file;
- int line;
- const char *msgid;
- va_list ap;
-{
- if (flag_pedantic_errors)
- v_error_with_file_and_line (file, line, msgid, ap);
- else
- v_warning_with_file_and_line (file, line, msgid, ap);
-}
-
-void
-pedwarn_with_file_and_line VPROTO((const char *file, int line,
- const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *file;
- int line;
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- file = va_arg (ap, const char *);
- line = va_arg (ap, int);
- msgid = va_arg (ap, const char *);
-#endif
-
- v_pedwarn_with_file_and_line (file, line, msgid, ap);
- va_end (ap);
-}
-
-/* Apologize for not implementing some feature. */
-
-static void
-vsorry (msgid, ap)
- const char *msgid;
- va_list ap;
-{
- sorrycount++;
- if (input_filename)
- fprintf (stderr, "%s:%d: ", input_filename, lineno);
- else
- fprintf (stderr, "%s: ", progname);
- notice ("sorry, not implemented: ");
- vnotice (stderr, msgid, ap);
- fputc ('\n', stderr);
-}
-
-void
-sorry VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
-
- vsorry (msgid, ap);
- va_end (ap);
-}
-
-/* Given a partial pathname as input, return another pathname that shares
- no elements with the pathname of __FILE__. This is used by abort() to
- print `Internal compiler error in expr.c' instead of `Internal compiler
- error in ../../egcs/gcc/expr.c'. */
-const char *
-trim_filename (name)
- const char *name;
-{
- static const char *this_file = __FILE__;
- const char *p = name, *q = this_file;
-
- while (*p == *q && *p != 0 && *q != 0) p++, q++;
- while (p > name && p[-1] != DIR_SEPARATOR
-#ifdef DIR_SEPARATOR_2
- && p[-1] != DIR_SEPARATOR_2
-#endif
- )
- p--;
-
- return p;
-}
-
-/* More 'friendly' abort that prints the line and file.
- config.h can #define abort fancy_abort if you like that sort of thing.
-
- I don't think this is actually a good idea.
- Other sorts of crashes will look a certain way.
- It is a good thing if crashes from calling abort look the same way.
- -- RMS */
-
-void
-fancy_abort ()
-{
- fatal ("internal gcc abort");
-}
/* This calls abort and is used to avoid problems when abort if a macro.
It is used when we need to pass the address of abort. */
@@ -2302,80 +1617,10 @@ do_abort ()
void
botch (s)
- const char * s ATTRIBUTE_UNUSED;
+ const char *s ATTRIBUTE_UNUSED;
{
abort ();
}
-
-/* Same as `malloc' but report error if no memory available. */
-
-PTR
-xmalloc (size)
- size_t size;
-{
- register PTR value;
-
- if (size == 0)
- size = 1;
-
- value = (PTR) malloc (size);
- if (value == 0)
- fatal ("virtual memory exhausted");
- return value;
-}
-
-/* Same as `calloc' but report error if no memory available. */
-
-PTR
-xcalloc (size1, size2)
- size_t size1, size2;
-{
- register PTR value;
-
- if (size1 == 0 || size2 == 0)
- size1 = size2 = 1;
-
- value = (PTR) calloc (size1, size2);
- if (value == 0)
- fatal ("virtual memory exhausted");
- return value;
-}
-
-
-/* Same as `realloc' but report error if no memory available.
- Also handle null PTR even if the vendor realloc gets it wrong. */
-
-PTR
-xrealloc (ptr, size)
- PTR ptr;
- size_t size;
-{
- register PTR result;
-
- if (size == 0)
- size = 1;
-
- result = (ptr ? (PTR) realloc (ptr, size) : (PTR) malloc (size));
-
- if (!result)
- fatal ("virtual memory exhausted");
-
- return result;
-}
-
-/* Same as `strdup' but report error if no memory available. */
-
-char *
-xstrdup (s)
- register const char *s;
-{
- register char *result = (char *) malloc (strlen (s) + 1);
-
- if (! result)
- fatal ("virtual memory exhausted");
- strcpy (result, s);
- return result;
-}
/* Return the logarithm of X, base 2, considering X unsigned,
if X is a power of 2. Otherwise, returns -1.
@@ -2384,9 +1629,9 @@ xstrdup (s)
int
exact_log2_wide (x)
- register unsigned HOST_WIDE_INT x;
+ unsigned HOST_WIDE_INT x;
{
- register int log = 0;
+ int log = 0;
/* Test for 0 or a power of 2. */
if (x == 0 || x != (x & -x))
return -1;
@@ -2402,9 +1647,9 @@ exact_log2_wide (x)
int
floor_log2_wide (x)
- register unsigned HOST_WIDE_INT x;
+ unsigned HOST_WIDE_INT x;
{
- register int log = -1;
+ int log = -1;
while (x != 0)
log++,
x >>= 1;
@@ -2423,11 +1668,11 @@ float_signal (signo)
int signo ATTRIBUTE_UNUSED;
{
if (float_handled == 0)
- abort ();
-#if defined (USG) || defined (hpux)
- signal (SIGFPE, float_signal); /* re-enable the signal catcher */
-#endif
+ crash_signal (signo);
float_handled = 0;
+
+ /* On System-V derived systems, we must reinstall the signal handler.
+ This is harmless on BSD-derived systems. */
signal (SIGFPE, float_signal);
longjmp (float_handler, 1);
}
@@ -2435,13 +1680,13 @@ float_signal (signo)
/* Specify where to longjmp to when a floating arithmetic error happens.
If HANDLER is 0, it means don't handle the errors any more. */
-void
+static void
set_float_handler (handler)
jmp_buf handler;
{
float_handled = (handler != 0);
if (handler)
- bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
+ memcpy (float_handler, handler, sizeof (float_handler));
if (float_handled && ! float_handler_set)
{
@@ -2455,18 +1700,19 @@ set_float_handler (handler)
pointer FN, and one argument DATA. DATA is usually a struct which
contains the real input and output for function FN. This function
returns 0 (failure) if longjmp was called (i.e. an exception
- occured.) It returns 1 (success) otherwise. */
+ occurred.) It returns 1 (success) otherwise. */
int
do_float_handler (fn, data)
- void (*fn) PROTO ((PTR));
- PTR data;
+ void (*fn) PARAMS ((PTR));
+ PTR data;
{
jmp_buf buf;
if (setjmp (buf))
{
- /* We got here via longjmp() caused by an exception in function fn() */
+ /* We got here via longjmp () caused by an exception in function
+ fn (). */
set_float_handler (NULL);
return 0;
}
@@ -2477,52 +1723,20 @@ do_float_handler (fn, data)
return 1;
}
-/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
- error happens, pushing the previous specification into OLD_HANDLER.
- Return an indication of whether there was a previous handler in effect. */
-
-int
-push_float_handler (handler, old_handler)
- jmp_buf handler, old_handler;
-{
- int was_handled = float_handled;
-
- float_handled = 1;
- if (was_handled)
- memcpy ((char *) old_handler, (char *) float_handler,
- sizeof (float_handler));
-
- memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
- return was_handled;
-}
-
-/* Restore the previous specification of whether and where to longjmp to
- when a floating arithmetic error happens. */
-
-void
-pop_float_handler (handled, handler)
- int handled;
- jmp_buf handler;
-{
- float_handled = handled;
- if (handled)
- bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
-}
-
-/* Handler for SIGPIPE. */
+/* Handler for fatal signals, such as SIGSEGV. These are transformed
+ into ICE messages, which is much more user friendly. */
static void
-pipe_closed (signo)
- /* If this is missing, some compilers complain. */
- int signo ATTRIBUTE_UNUSED;
+crash_signal (signo)
+ int signo;
{
- fatal ("output pipe has been closed");
+ internal_error ("internal error: %s", strsignal (signo));
}
/* Strip off a legitimate source ending from the input string NAME of
length LEN. Rather than having to know the names used by all of
our front ends, we strip off an ending of a period followed by
- up to five characters. (Java uses ".class".) */
+ up to five characters. (Java uses ".class".) */
void
strip_off_ending (name, len)
@@ -2576,12 +1790,8 @@ output_file_directive (asm_file, input_name)
/* NA gets INPUT_NAME sans directory names. */
while (na > input_name)
{
- if (na[-1] == '/')
- break;
-#ifdef DIR_SEPARATOR
- if (na[-1] == DIR_SEPARATOR)
- break;
-#endif
+ if (IS_DIR_SEPARATOR (na[-1]))
+ break;
na--;
}
@@ -2598,114 +1808,99 @@ output_file_directive (asm_file, input_name)
#endif
}
-#ifdef ASM_IDENTIFY_LANGUAGE
-/* Routine to build language identifier for object file. */
-static void
-output_lang_identify (asm_out_file)
- FILE *asm_out_file;
-{
- int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
- char *s = (char *) alloca (len);
- sprintf (s, "__gnu_compiled_%s", lang_identify ());
- ASM_OUTPUT_LABEL (asm_out_file, s);
-}
-#endif
+/* Routine to open a dump file. Return true if the dump file is enabled. */
-/* Routine to open a dump file. */
-static void
-open_dump_file (suffix, function_name)
- const char *suffix;
- const char *function_name;
+static int
+open_dump_file (index, decl)
+ enum dump_file_index index;
+ tree decl;
{
- char *dumpname;
-
- TIMEVAR
- (dump_time,
- {
- dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
-
- if (rtl_dump_file != NULL)
- fclose (rtl_dump_file);
-
- strcpy (dumpname, dump_base_name);
- strcat (dumpname, suffix);
-
- rtl_dump_file = fopen (dumpname, "a");
-
- if (rtl_dump_file == NULL)
- pfatal_with_name (dumpname);
-
- free (dumpname);
-
- if (function_name)
- fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
- });
-
- return;
-}
+ char *dump_name;
+ const char *open_arg;
+ char seq[16];
-/* Routine to close a dump file. */
-static void
-close_dump_file (func, insns)
- void (*func) PROTO ((FILE *, rtx));
- rtx insns;
-{
- TIMEVAR
- (dump_time,
- {
- if (func)
- func (rtl_dump_file, insns);
-
- fflush (rtl_dump_file);
- fclose (rtl_dump_file);
-
- rtl_dump_file = NULL;
- });
-
- return;
-}
+ if (! dump_file[index].enabled)
+ return 0;
-/* Routine to dump rtl into a file. */
-static void
-dump_rtl (suffix, decl, func, insns)
- const char *suffix;
- tree decl;
- void (*func) PROTO ((FILE *, rtx));
- rtx insns;
-{
- open_dump_file (suffix, decl_printable_name (decl, 2));
- close_dump_file (func, insns);
+ timevar_push (TV_DUMP);
+ if (rtl_dump_file != NULL)
+ fclose (rtl_dump_file);
+
+ sprintf (seq, DUMPFILE_FORMAT, index);
+
+ if (! dump_file[index].initialized)
+ {
+ /* If we've not initialized the files, do so now. */
+ if (graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ dump_name = concat (seq, dump_file[index].extension, NULL);
+ clean_graph_dump_file (dump_base_name, dump_name);
+ free (dump_name);
+ }
+ dump_file[index].initialized = 1;
+ open_arg = "w";
+ }
+ else
+ open_arg = "a";
+
+ dump_name = concat (dump_base_name, seq,
+ dump_file[index].extension, NULL);
+
+ rtl_dump_file = fopen (dump_name, open_arg);
+ if (rtl_dump_file == NULL)
+ fatal_io_error ("can't open %s", dump_name);
+
+ free (dump_name);
+
+ if (decl)
+ fprintf (rtl_dump_file, "\n;; Function %s\n\n",
+ decl_printable_name (decl, 2));
+
+ timevar_pop (TV_DUMP);
+ return 1;
}
-/* Routine to empty a dump file. */
+/* Routine to close a dump file. */
+
static void
-clean_dump_file (suffix)
- const char *suffix;
+close_dump_file (index, func, insns)
+ enum dump_file_index index;
+ void (*func) PARAMS ((FILE *, rtx));
+ rtx insns;
{
- char *dumpname;
-
- dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
+ if (! rtl_dump_file)
+ return;
- strcpy (dumpname, dump_base_name);
- strcat (dumpname, suffix);
-
- rtl_dump_file = fopen (dumpname, "w");
+ timevar_push (TV_DUMP);
+ if (insns
+ && graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
- if (rtl_dump_file == NULL)
- pfatal_with_name (dumpname);
+ 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);
+ }
- free (dumpname);
+ if (func && insns)
+ func (rtl_dump_file, insns);
+ fflush (rtl_dump_file);
fclose (rtl_dump_file);
+
rtl_dump_file = NULL;
-
- return;
+ timevar_pop (TV_DUMP);
}
/* Do any final processing required for the declarations in VEC, of
which there are LEN. We write out inline functions and variables
that have been deferred until this point, but which are required.
- Returns non-zero if anything was put out. */
+ Returns non-zero if anything was put out. */
+
int
wrapup_global_declarations (vec, len)
tree *vec;
@@ -2719,10 +1914,10 @@ wrapup_global_declarations (vec, len)
for (i = 0; i < len; i++)
{
decl = vec[i];
-
+
/* We're not deferring this any longer. */
DECL_DEFER_OUTPUT (decl) = 0;
-
+
if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0
&& incomplete_decl_finalize_hook != 0)
(*incomplete_decl_finalize_hook) (decl);
@@ -2767,13 +1962,15 @@ wrapup_global_declarations (vec, len)
defined in a main file, as opposed to an include file. */
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
- && (! TREE_READONLY (decl)
- || TREE_PUBLIC (decl)
- || (!optimize && flag_keep_static_consts)
+ && (((! TREE_READONLY (decl) || TREE_PUBLIC (decl))
+ && !DECL_COMDAT (decl))
+ || (!optimize
+ && flag_keep_static_consts
+ && !DECL_ARTIFICIAL (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
reconsider = 1;
- rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
+ rest_of_decl_compilation (decl, NULL, 1, 1);
}
if (TREE_CODE (decl) == FUNCTION_DECL
@@ -2784,9 +1981,7 @@ wrapup_global_declarations (vec, len)
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
reconsider = 1;
- temporary_allocation ();
output_inline_function (decl);
- permanent_allocation (1);
}
}
@@ -2800,6 +1995,7 @@ wrapup_global_declarations (vec, len)
/* Issue appropriate warnings for the global declarations in VEC (of
which there are LEN). Output debugging information for them. */
+
void
check_global_declarations (vec, len)
tree *vec;
@@ -2817,7 +2013,7 @@ check_global_declarations (vec, len)
/* Cancel the RTL for this decl so that, if debugging info
output for global variables is still to come,
this one will be omitted. */
- DECL_RTL (decl) = NULL;
+ SET_DECL_RTL (decl, NULL_RTX);
/* Warn about any function
declared static but not defined.
@@ -2825,7 +2021,7 @@ check_global_declarations (vec, len)
because many programs have static variables
that exist only to get some text into the object file. */
if (TREE_CODE (decl) == FUNCTION_DECL
- && (warn_unused
+ && (warn_unused_function
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
&& DECL_INITIAL (decl) == 0
&& DECL_EXTERNAL (decl)
@@ -2846,9 +2042,10 @@ check_global_declarations (vec, len)
/* Warn about static fns or vars defined but not used,
but not about inline functions or static consts
since defining those in header files is normal practice. */
- if (warn_unused
- && ((TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
- || (TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
+ if (((warn_unused_function
+ && TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl))
+ || (warn_unused_variable
+ && TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
@@ -2860,437 +2057,88 @@ check_global_declarations (vec, len)
&& ! TREE_USED (DECL_NAME (decl)))
warning_with_decl (decl, "`%s' defined but not used");
-#ifdef SDB_DEBUGGING_INFO
- /* The COFF linker can move initialized global vars to the end.
- And that can screw up the symbol ordering.
- By putting the symbols in that order to begin with,
- we avoid a problem. mcsun!unido!fauern!tumuc!pes@uunet.uu.net. */
- if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
- && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
- && ! DECL_EXTERNAL (decl)
- && DECL_RTL (decl) != 0)
- TIMEVAR (symout_time, sdbout_symbol (decl, 0));
-
- /* Output COFF information for non-global
- file-scope initialized variables. */
- if (write_symbols == SDB_DEBUG
- && TREE_CODE (decl) == VAR_DECL
- && DECL_INITIAL (decl)
- && ! DECL_EXTERNAL (decl)
- && DECL_RTL (decl) != 0
- && GET_CODE (DECL_RTL (decl)) == MEM)
- TIMEVAR (symout_time, sdbout_toplevel_data (decl));
-#endif /* SDB_DEBUGGING_INFO */
-#ifdef DWARF_DEBUGGING_INFO
- /* Output DWARF information for file-scope tentative data object
- declarations, file-scope (extern) function declarations (which
- had no corresponding body) and file-scope tagged type declarations
- and definitions which have not yet been forced out. */
-
- if (write_symbols == DWARF_DEBUG
- && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- /* Output DWARF2 information for file-scope tentative data object
- declarations, file-scope (extern) function declarations (which
- had no corresponding body) and file-scope tagged type declarations
- and definitions which have not yet been forced out. */
-
- if (write_symbols == DWARF2_DEBUG
- && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
- TIMEVAR (symout_time, dwarf2out_decl (decl));
-#endif
+ timevar_push (TV_SYMOUT);
+ (*debug_hooks->global_decl) (decl);
+ timevar_pop (TV_SYMOUT);
}
}
-/* Compile an entire file of output from cpp, named NAME.
- Write a file of assembly output and various debugging dumps. */
+/* Save the current INPUT_FILENAME and LINENO on the top entry in the
+ INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the
+ INPUT_FILENAME and LINENO accordingly. */
-static void
-compile_file (name)
- char *name;
+void
+push_srcloc (file, line)
+ const char *file;
+ int line;
{
- tree globals;
- int start_time;
-
- int name_specified = name != 0;
+ struct file_stack *fs;
- if (dump_base_name == 0)
- dump_base_name = name ? name : "gccdump";
-
- parse_time = 0;
- varconst_time = 0;
- integration_time = 0;
- jump_time = 0;
- cse_time = 0;
- gcse_time = 0;
- loop_time = 0;
- cse2_time = 0;
- branch_prob_time = 0;
- flow_time = 0;
- combine_time = 0;
- regmove_time = 0;
- sched_time = 0;
- local_alloc_time = 0;
- global_alloc_time = 0;
- flow2_time = 0;
- sched2_time = 0;
-#ifdef DELAY_SLOTS
- dbr_sched_time = 0;
-#endif
- shorten_branch_time = 0;
- stack_reg_time = 0;
- final_time = 0;
- symout_time = 0;
- dump_time = 0;
-
- /* Initialize data in various passes. */
-
- init_obstacks ();
- init_tree_codes ();
- name = init_parse (name);
- init_rtl ();
- init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
- || debug_info_level == DINFO_LEVEL_VERBOSE
- || flag_test_coverage);
- init_regs ();
- init_decl_processing ();
- init_optabs ();
- init_stmt ();
- init_expmed ();
- init_expr_once ();
- init_loop ();
- init_reload ();
- init_alias_once ();
-
- if (flag_caller_saves)
- init_caller_save ();
-
- /* 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)
+ if (input_file_stack)
{
- aux_info_file = fopen (aux_info_file_name, "w");
- if (aux_info_file == 0)
- pfatal_with_name (aux_info_file_name);
+ input_file_stack->name = input_filename;
+ input_file_stack->line = lineno;
}
- /* Clear the dump files. */
- if (rtl_dump)
- clean_dump_file (".rtl");
- if (jump_opt_dump)
- {
- clean_dump_file (".jump");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".jump");
- }
- if (addressof_dump)
- {
- clean_dump_file (".addressof");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".addressof");
- }
- if (cse_dump)
- {
- clean_dump_file (".cse");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".cse");
- }
- if (loop_dump)
- {
- clean_dump_file (".loop");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".loop");
- }
- if (cse2_dump)
- {
- clean_dump_file (".cse2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".cse2");
- }
- if (branch_prob_dump)
- {
- clean_dump_file (".bp");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".bp");
- }
- if (flow_dump)
- {
- clean_dump_file (".flow");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".flow");
- }
- if (combine_dump)
- {
- clean_dump_file (".combine");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".combine");
- }
- if (regmove_dump)
- {
- clean_dump_file (".regmove");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".regmove");
- }
- if (sched_dump)
- {
- clean_dump_file (".sched");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".sched");
- }
- if (local_reg_dump)
- {
- clean_dump_file (".lreg");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".lreg");
- }
- if (global_reg_dump)
- {
- clean_dump_file (".greg");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".greg");
- }
- if (flow2_dump)
- {
- clean_dump_file (".flow2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".flow2");
- }
- if (sched2_dump)
- {
- clean_dump_file (".sched2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".sched2");
- }
- if (jump2_opt_dump)
- {
- clean_dump_file (".jump2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".jump2");
- }
-#ifdef DELAY_SLOTS
- if (dbr_sched_dump)
- {
- clean_dump_file (".dbr");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".dbr");
- }
-#endif
- if (gcse_dump)
- {
- clean_dump_file (".gcse");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".gcse");
- }
-#ifdef STACK_REGS
- if (stack_reg_dump)
- {
- clean_dump_file (".stack");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".stack");
- }
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
- if (mach_dep_reorg_dump)
- {
- clean_dump_file (".mach");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".mach");
- }
-#endif
-
- /* Open assembler code output file. */
-
- if (flag_syntax_only)
- asm_out_file = NULL;
- else
- {
- if (! name_specified && asm_file_name == 0)
- asm_out_file = stdout;
- else
- {
- int len = strlen (dump_base_name);
- register char *dumpname = (char *) xmalloc (len + 6);
- strcpy (dumpname, dump_base_name);
- strip_off_ending (dumpname, len);
- strcat (dumpname, ".s");
- if (asm_file_name == 0)
- {
- asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
- strcpy (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)
- pfatal_with_name (asm_file_name);
- }
-
-#ifdef IO_BUFFER_SIZE
- setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
- _IOFBF, IO_BUFFER_SIZE);
-#endif
- }
-
- input_filename = name;
-
- /* Put an entry on the input file stack for the main input file. */
- input_file_stack
- = (struct file_stack *) xmalloc (sizeof (struct file_stack));
- input_file_stack->next = 0;
- input_file_stack->name = input_filename;
-
- /* Perform language-specific initialization.
- This may set main_input_filename. */
- lang_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
- {
- ASM_FILE_START (asm_out_file);
-
-#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
-
- /* Output something to inform GDB that this compilation was by GCC. */
-#ifndef ASM_IDENTIFY_GCC
- fprintf (asm_out_file, "gcc2_compiled.:\n");
-#else
- ASM_IDENTIFY_GCC (asm_out_file);
-#endif
-
- /* Output something to identify which front-end produced this file. */
-#ifdef ASM_IDENTIFY_LANGUAGE
- ASM_IDENTIFY_LANGUAGE (asm_out_file);
-#endif
- } /* ! flag_syntax_only */
-
-#ifndef ASM_OUTPUT_SECTION_NAME
- 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;
- }
-#endif
+ fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
+ fs->name = input_filename = file;
+ fs->line = lineno = line;
+ fs->indent_level = 0;
+ fs->next = input_file_stack;
+ input_file_stack = fs;
+ input_file_stack_tick++;
+}
- if (flag_function_sections
- && (profile_flag || profile_block_flag))
- {
- warning ("-ffunction-sections disabled; it makes profiling impossible.");
- flag_function_sections = 0;
- }
+/* Pop the top entry off the stack of presently open source files.
+ Restore the INPUT_FILENAME and LINENO from the new topmost entry on
+ the stack. */
-#ifndef OBJECT_FORMAT_ELF
- if (flag_function_sections && write_symbols != NO_DEBUG)
- warning ("-ffunction-sections may affect debugging on some targets.");
-#endif
+void
+pop_srcloc ()
+{
+ struct file_stack *fs;
+
+ fs = input_file_stack;
+ input_file_stack = fs->next;
+ free (fs);
+ input_file_stack_tick++;
+ /* The initial source file is never popped. */
+ if (!input_file_stack)
+ abort ();
+ input_filename = input_file_stack->name;
+ lineno = input_file_stack->line;
+}
- /* ??? Note: There used to be a conditional here
- to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
- This was to guarantee separation between gcc_compiled. and
- the first function, for the sake of dbx on Suns.
- However, having the extra zero here confused the Emacs
- code for unexec, and might confuse other programs too.
- Therefore, I took out that change.
- In future versions we should find another way to solve
- that dbx problem. -- rms, 23 May 93. */
-
- /* Don't let the first function fall at the same address
- as gcc_compiled., if profiling. */
- if (profile_flag || profile_block_flag)
- {
- /* It's best if we can write a nop here since some
- assemblers don't tolerate zeros in the text section. */
- if (insn_template[CODE_FOR_nop] != 0)
- output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
- else
- assemble_zeros (UNITS_PER_WORD);
- }
+/* Compile an entire translation unit. Write a file of assembly
+ output and various debugging dumps. */
- /* If dbx symbol table desired, initialize writing it
- and output the predefined types. */
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
- getdecls ()));
-#endif
-#ifdef SDB_DEBUGGING_INFO
- if (write_symbols == SDB_DEBUG)
- TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
- getdecls ()));
-#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
-#endif
-#ifdef DWARF2_UNWIND_INFO
- if (dwarf2out_do_frame ())
- dwarf2out_frame_init ();
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
-#endif
+static void
+compile_file ()
+{
+ tree globals;
/* Initialize yet another pass. */
init_final (main_input_filename);
init_branch_prob (dump_base_name);
- start_time = get_run_time ();
+ timevar_push (TV_PARSE);
/* Call the parser, which parses the entire file
(calling rest_of_compilation for each function). */
+ yyparse ();
- if (yyparse () != 0)
- {
- if (errorcount == 0)
- notice ("Errors detected in input file (your bison.simple is out of date)\n");
-
- /* In case there were missing closebraces,
- get us back to the global binding level. */
- while (! global_bindings_p ())
- poplevel (0, 0, 0);
- }
+ /* In case there were missing block closers,
+ get us back to the global binding level. */
+ (*lang_hooks.clear_binding_stack) ();
/* Compilation is now finished except for writing
what's left of the symbol table output. */
- parse_time += get_run_time () - start_time;
-
- parse_time -= integration_time;
- parse_time -= varconst_time;
+ timevar_pop (TV_PARSE);
if (flag_syntax_only)
- goto finish_syntax;
+ return;
globals = getdecls ();
@@ -3300,7 +2148,7 @@ compile_file (name)
{
int len = list_length (globals);
- tree *vec = (tree *) alloca (sizeof (tree) * len);
+ tree *vec = (tree *) xmalloc (sizeof (tree) * len);
int i;
tree decl;
@@ -3321,187 +2169,74 @@ compile_file (name)
loop above. */
output_func_start_profiler ();
- /* Now that all possible functions have been output, we can dump
- the exception table. */
-
- output_exception_table ();
-
check_global_declarations (vec, len);
+
+ /* Clean up. */
+ free (vec);
}
/* Write out any pending weak symbol declarations. */
weak_finish ();
- /* Do dbx symbols */
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time,
- {
- dbxout_finish (asm_out_file, main_input_filename);
- });
-#endif
-
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time,
- {
- dwarfout_finish ();
- });
-#endif
+ /* Do dbx symbols. */
+ timevar_push (TV_SYMOUT);
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_frame ())
dwarf2out_frame_finish ();
#endif
-#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time,
- {
- dwarf2out_finish ();
- });
-#endif
+ (*debug_hooks->finish) (main_input_filename);
+ timevar_pop (TV_SYMOUT);
/* Output some stuff at end of file if nec. */
- end_final (dump_base_name);
-
- if (branch_prob_dump)
- open_dump_file (".bp", NULL);
-
- TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
-
- if (branch_prob_dump)
- close_dump_file (NULL, NULL_RTX);
-
-#ifdef ASM_FILE_END
- ASM_FILE_END (asm_out_file);
-#endif
-
-
- /* Language-specific end of compilation actions. */
- finish_syntax:
- lang_finish ();
+ dw2_output_indirect_constants ();
- /* Close the dump files. */
+ end_final (dump_base_name);
- if (flag_gen_aux_info)
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- fclose (aux_info_file);
- if (errorcount)
- unlink (aux_info_file_name);
- }
+ timevar_push (TV_DUMP);
+ open_dump_file (DFI_bp, NULL);
- if (combine_dump)
- {
- open_dump_file (".combine", NULL);
- TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
- close_dump_file (NULL, NULL_RTX);
- }
+ end_branch_prob ();
- /* 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 ();
-
- if (! flag_syntax_only
- && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
- fatal_io_error (asm_file_name);
-
- /* Do whatever is necessary to finish printing the graphs. */
- if (graph_dump_format != no_graph)
- {
- if (jump_opt_dump)
- finish_graph_dump_file (dump_base_name, ".jump");
- if (addressof_dump)
- finish_graph_dump_file (dump_base_name, ".addressof");
- if (cse_dump)
- finish_graph_dump_file (dump_base_name, ".cse");
- if (loop_dump)
- finish_graph_dump_file (dump_base_name, ".loop");
- if (cse2_dump)
- finish_graph_dump_file (dump_base_name, ".cse2");
- if (branch_prob_dump)
- finish_graph_dump_file (dump_base_name, ".bp");
- if (flow_dump)
- finish_graph_dump_file (dump_base_name, ".flow");
- if (combine_dump)
- finish_graph_dump_file (dump_base_name, ".combine");
- if (regmove_dump)
- finish_graph_dump_file (dump_base_name, ".regmove");
- if (sched_dump)
- finish_graph_dump_file (dump_base_name, ".sched");
- if (local_reg_dump)
- finish_graph_dump_file (dump_base_name, ".lreg");
- if (global_reg_dump)
- finish_graph_dump_file (dump_base_name, ".greg");
- if (flow2_dump)
- finish_graph_dump_file (dump_base_name, ".flow2");
- if (sched2_dump)
- finish_graph_dump_file (dump_base_name, ".sched2");
- if (jump2_opt_dump)
- finish_graph_dump_file (dump_base_name, ".jump2");
-#ifdef DELAY_SLOTS
- if (dbr_sched_dump)
- finish_graph_dump_file (dump_base_name, ".dbr");
-#endif
- if (gcse_dump)
- finish_graph_dump_file (dump_base_name, ".gcse");
-#ifdef STACK_REGS
- if (stack_reg_dump)
- finish_graph_dump_file (dump_base_name, ".stack");
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
- if (mach_dep_reorg_dump)
- finish_graph_dump_file (dump_base_name, ".mach");
-#endif
+ close_dump_file (DFI_bp, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
}
- /* Free up memory for the benefit of leak detectors. */
- free_reg_info ();
+#ifdef ASM_FILE_END
+ ASM_FILE_END (asm_out_file);
+#endif
- /* Print the times. */
+ /* Attach a special .ident directive to the end of the file to identify
+ the version of GCC which compiled this code. The format of the .ident
+ string is patterned after the ones produced by native SVR4 compilers. */
+#ifdef IDENT_ASM_OP
+ if (!flag_no_ident)
+ fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n",
+ IDENT_ASM_OP, version_string);
+#endif
- if (! quiet_flag)
+ if (optimize > 0 && open_dump_file (DFI_combine, NULL))
{
- fprintf (stderr,"\n");
- print_time ("parse", parse_time);
-
- print_time ("integration", integration_time);
- print_time ("jump", jump_time);
- print_time ("cse", cse_time);
- print_time ("gcse", gcse_time);
- print_time ("loop", loop_time);
- print_time ("cse2", cse2_time);
- print_time ("branch-prob", branch_prob_time);
- print_time ("flow", flow_time);
- print_time ("combine", combine_time);
- print_time ("regmove", regmove_time);
- print_time ("sched", sched_time);
- print_time ("local-alloc", local_alloc_time);
- print_time ("global-alloc", global_alloc_time);
- print_time ("flow2", flow2_time);
- print_time ("sched2", sched2_time);
-#ifdef DELAY_SLOTS
- print_time ("dbranch", dbr_sched_time);
-#endif
- print_time ("shorten-branch", shorten_branch_time);
- print_time ("stack-reg", stack_reg_time);
- print_time ("final", final_time);
- print_time ("varconst", varconst_time);
- print_time ("symout", symout_time);
- print_time ("dump", dump_time);
+ timevar_push (TV_DUMP);
+ dump_combine_total_stats (rtl_dump_file);
+ close_dump_file (DFI_combine, NULL, NULL_RTX);
+ timevar_pop (TV_DUMP);
}
}
/* This is called from various places for FUNCTION_DECL, VAR_DECL,
and TYPE_DECL nodes.
- This does nothing for local (non-static) variables.
- Otherwise, it sets up the RTL and outputs any assembler code
- (label definition, storage allocation and initialization).
+ 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
@@ -3526,48 +2261,54 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
but we need to treat them as if they were. */
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
|| TREE_CODE (decl) == FUNCTION_DECL)
- TIMEVAR (varconst_time,
- {
- make_decl_rtl (decl, asmspec, top_level);
- /* Initialized extern variable exists to be replaced
- with its value, or represents something that will be
- output in another file. */
- if (! (TREE_CODE (decl) == VAR_DECL
- && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
- && DECL_INITIAL (decl) != 0
- && DECL_INITIAL (decl) != error_mark_node))
- /* Don't output anything
- when a tentative file-scope definition is seen.
- But at end of compilation, do output code for them. */
- if (! (! at_end && top_level
- && (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node)))
- assemble_variable (decl, top_level, at_end, 0);
- if (decl == last_assemble_variable_decl)
- {
- ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
- top_level, at_end);
- }
- });
+ {
+ timevar_push (TV_VARCONST);
+ if (asmspec)
+ make_decl_rtl (decl, asmspec);
+ /* Don't output anything
+ when a tentative file-scope definition is seen.
+ But at end of compilation, do output code for them. */
+ if (at_end || !DECL_DEFER_OUTPUT (decl))
+ assemble_variable (decl, top_level, at_end, 0);
+ if (decl == last_assemble_variable_decl)
+ {
+ ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
+ top_level, at_end);
+ }
+ timevar_pop (TV_VARCONST);
+ }
else if (DECL_REGISTER (decl) && asmspec != 0)
{
if (decode_reg_name (asmspec) >= 0)
{
- DECL_RTL (decl) = 0;
- make_decl_rtl (decl, asmspec, top_level);
+ SET_DECL_RTL (decl, NULL_RTX);
+ make_decl_rtl (decl, asmspec);
}
else
- error ("invalid register name `%s' for register variable", asmspec);
+ {
+ error ("invalid register name `%s' for register variable", asmspec);
+ DECL_REGISTER (decl) = 0;
+ if (!top_level)
+ expand_decl (decl);
+ }
}
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
&& TREE_CODE (decl) == TYPE_DECL)
- TIMEVAR (symout_time, dbxout_symbol (decl, 0));
+ {
+ timevar_push (TV_SYMOUT);
+ dbxout_symbol (decl, 0);
+ timevar_pop (TV_SYMOUT);
+ }
#endif
#ifdef SDB_DEBUGGING_INFO
else if (write_symbols == SDB_DEBUG && top_level
&& TREE_CODE (decl) == TYPE_DECL)
- TIMEVAR (symout_time, sdbout_symbol (decl, 0));
+ {
+ timevar_push (TV_SYMOUT);
+ sdbout_symbol (decl, 0);
+ timevar_pop (TV_SYMOUT);
+ }
#endif
}
@@ -3583,14 +2324,22 @@ rest_of_type_compilation (type, toplev)
int toplev ATTRIBUTE_UNUSED;
#endif
{
+ timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
+ dbxout_symbol (TYPE_STUB_DECL (type), !toplev);
#endif
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
- TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
+ sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+ if ((write_symbols == DWARF2_DEBUG
+ || write_symbols == VMS_AND_DWARF2_DEBUG)
+ && toplev)
+ dwarf2out_decl (TYPE_STUB_DECL (type));
#endif
+ timevar_pop (TV_SYMOUT);
}
/* This is called from finish_function (within yyparse)
@@ -3603,17 +2352,33 @@ void
rest_of_compilation (decl)
tree decl;
{
- register rtx insns;
- int start_time = get_run_time ();
+ rtx insns;
int tem;
- /* Nonzero if we have saved the original DECL_INITIAL of the function,
- to be restored after we finish compiling the function
- (for use when compiling inline calls to this function). */
- tree saved_block_tree = 0;
- /* Likewise, for DECL_ARGUMENTS. */
- tree saved_arguments = 0;
int failure = 0;
int rebuild_label_notes_after_reload;
+ int register_life_up_to_date;
+
+ timevar_push (TV_REST_OF_COMPILATION);
+
+ /* Now that we're out of the frontend, we shouldn't have any more
+ CONCATs anywhere. */
+ generating_concat_p = 0;
+
+ /* When processing delayed functions, prepare_function_start() won't
+ have been run to re-initialize it. */
+ cse_not_expected = ! optimize;
+
+ /* First, make sure that NOTE_BLOCK is set correctly for each
+ NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note. */
+ if (!cfun->x_whole_function_mode_p)
+ identify_blocks ();
+
+ /* 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)
+ reorder_blocks ();
+
+ init_flow ();
/* If we are reconsidering an inline function
at the end of compilation, skip the stuff for making it inline. */
@@ -3621,161 +2386,121 @@ rest_of_compilation (decl)
if (DECL_SAVED_INSNS (decl) == 0)
{
int inlinable = 0;
+ tree parent;
const char *lose;
+ /* If this is nested inside an inlined external function, pretend
+ it was only declared. Since we cannot inline such functions,
+ generating code for this one is not only not necessary but will
+ confuse some debugging output writers. */
+ for (parent = DECL_CONTEXT (current_function_decl);
+ parent != NULL_TREE;
+ parent = get_containing_scope (parent))
+ if (TREE_CODE (parent) == FUNCTION_DECL
+ && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
+ {
+ DECL_INITIAL (decl) = 0;
+ goto exit_rest_of_compilation;
+ }
+
/* If requested, consider whether to make this function inline. */
- if (DECL_INLINE (decl) || flag_inline_functions)
- TIMEVAR (integration_time,
- {
- lose = function_cannot_inline_p (decl);
- if (lose || ! optimize)
- {
- if (warn_inline && DECL_INLINE (decl))
- warning_with_decl (decl, lose);
- DECL_ABSTRACT_ORIGIN (decl) = 0;
- /* Don't really compile an extern inline function.
- If we can't make it inline, pretend
- it was only declared. */
- if (DECL_EXTERNAL (decl))
- {
- DECL_INITIAL (decl) = 0;
- goto exit_rest_of_compilation;
- }
- }
- else
- /* ??? Note that this has the effect of making it look
- like "inline" was specified for a function if we choose
- to inline it. This isn't quite right, but it's
- probably not worth the trouble to fix. */
- inlinable = DECL_INLINE (decl) = 1;
- });
+ if ((DECL_INLINE (decl) && !flag_no_inline)
+ || flag_inline_functions)
+ {
+ timevar_push (TV_INTEGRATION);
+ lose = function_cannot_inline_p (decl);
+ timevar_pop (TV_INTEGRATION);
+ if (lose || ! optimize)
+ {
+ if (warn_inline && DECL_INLINE (decl))
+ warning_with_decl (decl, lose);
+ DECL_ABSTRACT_ORIGIN (decl) = 0;
+ /* Don't really compile an extern inline function.
+ If we can't make it inline, pretend
+ it was only declared. */
+ if (DECL_EXTERNAL (decl))
+ {
+ DECL_INITIAL (decl) = 0;
+ goto exit_rest_of_compilation;
+ }
+ }
+ else
+ /* ??? Note that this has the effect of making it look
+ like "inline" was specified for a function if we choose
+ to inline it. This isn't quite right, but it's
+ probably not worth the trouble to fix. */
+ inlinable = DECL_INLINE (decl) = 1;
+ }
insns = get_insns ();
/* Dump the rtl code if we are dumping rtl. */
- if (rtl_dump)
+ if (open_dump_file (DFI_rtl, decl))
{
- open_dump_file (".rtl", decl_printable_name (decl, 2));
-
if (DECL_SAVED_INSNS (decl))
fprintf (rtl_dump_file, ";; (integrable)\n\n");
-
- close_dump_file (print_rtl, insns);
+ close_dump_file (DFI_rtl, print_rtl, insns);
}
- /* If we can, defer compiling inlines until EOF.
- save_for_inline_copying can be extremely expensive. */
- if (inlinable && ! decl_function_context (decl))
- DECL_DEFER_OUTPUT (decl) = 1;
+ /* Convert from NOTE_INSN_EH_REGION style notes, and do other
+ sorts of eh initialization. Delay this until after the
+ initial rtl dump so that we can see the original nesting. */
+ convert_from_eh_region_ranges ();
/* If function is inline, and we don't yet know whether to
compile it by itself, defer decision till end of compilation.
finish_compilation will call rest_of_compilation again
for those functions that need to be output. Also defer those
- functions that we are supposed to defer. We cannot defer
- functions containing nested functions since the nested function
- data is in our non-saved obstack. We cannot defer nested
- functions for the same reason. */
-
- /* If this is a nested inline, remove ADDRESSOF now so we can
- finish compiling ourselves. Otherwise, wait until EOF.
- We have to do this because the purge_addressof transformation
- changes the DECL_RTL for many variables, which confuses integrate. */
- if (inlinable)
- {
- if (decl_function_context (decl))
- purge_addressof (insns);
- else
- DECL_DEFER_OUTPUT (decl) = 1;
- }
+ functions that we are supposed to defer. */
+
+ if (inlinable
+ || (DECL_INLINE (decl)
+ && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
+ && ! flag_keep_inline_functions)
+ || DECL_EXTERNAL (decl))))
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ if (DECL_INLINE (decl))
+ /* DWARF wants separate debugging info for abstract and
+ concrete instances of all inline functions, including those
+ declared inline but not inlined, and those inlined even
+ though they weren't declared inline. Conveniently, that's
+ what DECL_INLINE means at this point. */
+ (*debug_hooks->deferred_inline_function) (decl);
- if (! current_function_contains_functions
- && (DECL_DEFER_OUTPUT (decl)
- || (DECL_INLINE (decl)
- && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
- && ! flag_keep_inline_functions)
- || DECL_EXTERNAL (decl)))))
+ if (DECL_DEFER_OUTPUT (decl))
{
- DECL_DEFER_OUTPUT (decl) = 1;
-
- /* If -Wreturn-type, we have to do a bit of compilation.
- However, if we just fall through we will call
- save_for_inline_copying() which results in excessive
- memory use. Instead, we just want to call
- jump_optimize() to figure out whether or not we can fall
- off the end of the function; we do the minimum amount of
- work necessary to make that safe. And, we set optimize
- to zero to keep jump_optimize from working too hard. */
+ /* If -Wreturn-type, we have to do a bit of compilation. We just
+ want to call cleanup the cfg to figure out whether or not we can
+ fall off the end of the function; we do the minimum amount of
+ work necessary to make that safe. */
if (warn_return_type)
{
int saved_optimize = optimize;
+
optimize = 0;
+ rebuild_jump_labels (insns);
find_exception_handler_labels ();
- jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
optimize = saved_optimize;
- }
-#ifdef DWARF_DEBUGGING_INFO
- /* Generate the DWARF info for the "abstract" instance
- of a function which we may later generate inlined and/or
- out-of-line instances of. */
- if (write_symbols == DWARF_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
- set_decl_abstract_flags (decl, 0);
- }
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- /* Generate the DWARF2 info for the "abstract" instance
- of a function which we may later generate inlined and/or
- out-of-line instances of. */
- if (write_symbols == DWARF2_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarf2out_decl (decl));
- set_decl_abstract_flags (decl, 0);
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
}
-#endif
- TIMEVAR (integration_time, save_for_inline_nocopy (decl));
- RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
- goto exit_rest_of_compilation;
- }
- /* If we have to compile the function now, save its rtl and subdecls
- so that its compilation will not affect what others get. */
- if (inlinable || DECL_DEFER_OUTPUT (decl))
- {
-#ifdef DWARF_DEBUGGING_INFO
- /* Generate the DWARF info for the "abstract" instance of
- a function which we will generate an out-of-line instance
- of almost immediately (and which we may also later generate
- various inlined instances of). */
- if (write_symbols == DWARF_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
- set_decl_abstract_flags (decl, 0);
- }
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- /* Generate the DWARF2 info for the "abstract" instance of
- a function which we will generate an out-of-line instance
- of almost immediately (and which we may also later generate
- various inlined instances of). */
- if (write_symbols == DWARF2_DEBUG)
- {
- set_decl_abstract_flags (decl, 1);
- TIMEVAR (symout_time, dwarf2out_decl (decl));
- set_decl_abstract_flags (decl, 0);
- }
-#endif
- saved_block_tree = DECL_INITIAL (decl);
- saved_arguments = DECL_ARGUMENTS (decl);
- TIMEVAR (integration_time, save_for_inline_copying (decl));
- RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
+ current_function_nothrow = nothrow_function_p ();
+ if (current_function_nothrow)
+ /* Now we know that this can't throw; set the flag for the benefit
+ of other functions later in this translation unit. */
+ TREE_NOTHROW (current_function_decl) = 1;
+
+ timevar_push (TV_INTEGRATION);
+ save_for_inline (decl);
+ timevar_pop (TV_INTEGRATION);
+ DECL_SAVED_INSNS (decl)->inlinable = inlinable;
+ goto exit_rest_of_compilation;
}
/* If specified extern inline but we aren't inlining it, we are
@@ -3785,22 +2510,76 @@ rest_of_compilation (decl)
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. */
+ init_function_for_compilation ();
+
if (! DECL_DEFER_OUTPUT (decl))
TREE_ASM_WRITTEN (decl) = 1;
- /* Now that integrate will no longer see our rtl, we need not distinguish
- between the return value of this function and the return value of called
- functions. */
+ /* Now that integrate will no longer see our rtl, we need not
+ distinguish between the return value of this function and the
+ return value of called functions. Also, we can remove all SETs
+ of subregs of hard registers; they are only here because of
+ integrate. Also, we can now initialize pseudos intended to
+ carry magic hard reg data throughout the function. */
rtx_equal_function_value_matters = 0;
+ purge_hard_subreg_sets (get_insns ());
+ emit_initial_value_sets ();
- /* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
+ /* Don't return yet if -Wreturn-type; we need to do cleanup_cfg. */
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
+ goto exit_rest_of_compilation;
+
+ /* We may have potential sibling or tail recursion sites. Select one
+ (of possibly multiple) methods of performing the call. */
+ if (flag_optimize_sibling_calls)
{
- goto exit_rest_of_compilation;
+ timevar_push (TV_JUMP);
+ open_dump_file (DFI_sibling, decl);
+
+ optimize_sibling_and_tail_recursive_calls ();
+
+ close_dump_file (DFI_sibling, print_rtl, get_insns ());
+ timevar_pop (TV_JUMP);
}
- /* Emit code to get eh context, if needed. */
- emit_eh_context ();
+ /* Complete generation of exception handling code. */
+ find_exception_handler_labels ();
+ if (doing_eh (0))
+ {
+ timevar_push (TV_JUMP);
+ open_dump_file (DFI_eh, decl);
+
+ finish_eh_generation ();
+
+ close_dump_file (DFI_eh, print_rtl, get_insns ());
+ timevar_pop (TV_JUMP);
+ }
#ifdef FINALIZE_PIC
/* If we are doing position-independent code generation, now
@@ -3811,54 +2590,153 @@ rest_of_compilation (decl)
FINALIZE_PIC;
#endif
- /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
- Note that that may have been done above, in save_for_inline_copying.
- The call to resume_temporary_allocation near the end of this function
- goes back to the usual state of affairs. This must be done after
- we've built up any unwinders for exception handling, and done
- the FINALIZE_PIC work, if necessary. */
-
- rtl_in_current_obstack ();
-
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
-
unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
- /* This must be performed before virutal register instantiation. */
+ /* This must be performed before virtual register instantiation. */
if (current_function_calls_alloca)
optimize_save_area_alloca (insns);
#endif
/* Instantiate all virtual registers. */
+ instantiate_virtual_regs (current_function_decl, insns);
- instantiate_virtual_regs (current_function_decl, get_insns ());
-
- /* See if we have allocated stack slots that are not directly addressable.
- If so, scan all the insns and create explicit address computation
- for all references to such slots. */
-/* fixup_stack_slots (); */
-
- /* Find all the EH handlers. */
- find_exception_handler_labels ();
+ open_dump_file (DFI_jump, decl);
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
+
+ timevar_push (TV_JUMP);
+ /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
+ before jump optimization switches branch directions. */
+ expected_value_to_br_prob ();
+
+ reg_scan (insns, max_reg_num (), 0);
+ rebuild_jump_labels (insns);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP);
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+ copy_loop_headers (insns);
+ purge_line_number_notes (insns);
+
+ timevar_pop (TV_JUMP);
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
- goto exit_rest_of_compilation;
+ {
+ close_dump_file (DFI_jump, print_rtl, insns);
+ goto exit_rest_of_compilation;
+ }
+
+ /* Long term, this should probably move before the jump optimizer too,
+ but I didn't want to disturb the rtl_dump_and_exit and related
+ stuff at this time. */
+ if (optimize > 0 && flag_ssa)
+ {
+ /* Convert to SSA form. */
+
+ 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 ();
+
+ close_dump_file (DFI_ssa, print_rtl_with_bb, 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_const_prop ();
+
+ 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);
+
+ insns = get_insns ();
+ ssa_eliminate_dead_code();
+
+ close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns);
+ timevar_pop (TV_SSA_DCE);
+ }
+
+ /* Convert from SSA form. */
+
+ timevar_push (TV_FROM_SSA);
+ open_dump_file (DFI_ussa, decl);
- /* Dump rtl code after jump, if we are doing that. */
+ convert_from_ssa ();
+ /* New registers have been created. Rescan their usage. */
+ reg_scan (insns, max_reg_num (), 1);
- if (jump_opt_dump)
- dump_rtl (".jump", decl, print_rtl, insns);
+ close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
+ timevar_pop (TV_FROM_SSA);
+
+ ggc_collect ();
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+ }
+
+ timevar_push (TV_JUMP);
+
+ if (optimize > 0)
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ /* ??? 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);
+
+ /* 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);
+ }
+
+ /* Jump optimization, and the removal of NULL pointer checks, may
+ have reduced the number of instructions substantially. CSE, and
+ future passes, allocate arrays whose dimensions involve the
+ maximum instruction UID, so if we can reduce the maximum UID
+ we'll save big on memory. */
+ renumber_insns (rtl_dump_file);
+ timevar_pop (TV_JUMP);
+
+ close_dump_file (DFI_jump, print_rtl, insns);
+
+ ggc_collect ();
/* Perform common subexpression elimination.
Nonzero value from `cse_main' means that jumps were simplified
@@ -3867,115 +2745,169 @@ rest_of_compilation (decl)
if (optimize > 0)
{
- if (cse_dump)
- open_dump_file (".cse", decl_printable_name (decl, 2));
+ open_dump_file (DFI_cse, decl);
+ timevar_push (TV_CSE);
- TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
+ reg_scan (insns, max_reg_num (), 1);
- if (flag_thread_jumps)
- /* Hacks by tiemann & kenner. */
- TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
+ tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+
+ /* 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;
- TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
- 0, rtl_dump_file));
if (tem || optimize > 1)
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ {
+ 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 ();
+ }
/* Run this after jump optmizations remove all the unreachable code
so that unreachable code will not keep values live. */
- TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
-
- /* Dump rtl code after cse, if we are doing that. */
+ delete_trivially_dead_insns (insns, max_reg_num (), 0);
- if (cse_dump)
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks || flag_thread_jumps)
{
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
+ timevar_push (TV_JUMP);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ 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);
+
+ timevar_pop (TV_CSE);
+ close_dump_file (DFI_cse, print_rtl, insns);
}
+ open_dump_file (DFI_addressof, decl);
+
purge_addressof (insns);
reg_scan (insns, max_reg_num (), 1);
- if (addressof_dump)
- {
- dump_rtl (".addressof", decl, print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
- }
+ close_dump_file (DFI_addressof, print_rtl, insns);
+
+ ggc_collect ();
/* Perform global cse. */
if (optimize > 0 && flag_gcse)
{
- if (gcse_dump)
- open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
-
- TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
-
- /* If gcse altered any jumps, rerun jump optimizations to clean
- things up. */
- if (tem)
+ int save_csb, save_cfj;
+ int tem2 = 0;
+
+ 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 (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
- }
+ timevar_push (TV_CSE);
+ reg_scan (insns, max_reg_num (), 1);
+ tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ timevar_pop (TV_CSE);
+ cse_not_expected = !flag_rerun_cse_after_loop;
+ }
- if (gcse_dump)
+ /* If gcse or cse altered any jumps, rerun jump optimizations to clean
+ things up. Then possibly re-run CSE again. */
+ while (tem || tem2)
{
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
+ 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);
+ 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);
+ timevar_pop (TV_CSE);
+ }
}
+
+ close_dump_file (DFI_gcse, print_rtl, insns);
+ timevar_pop (TV_GCSE);
+
+ ggc_collect ();
+ flag_cse_skip_blocks = save_csb;
+ flag_cse_follow_jumps = save_cfj;
}
+
/* Move constant computations out of loops. */
if (optimize > 0)
{
- if (loop_dump)
- open_dump_file (".loop", decl_printable_name (decl, 2));
-
- TIMEVAR
- (loop_time,
- {
- if (flag_rerun_loop_opt)
- {
- /* We only want to perform unrolling once. */
-
- loop_optimize (insns, rtl_dump_file, 0, 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. */
- delete_trivially_dead_insns (insns, max_reg_num ());
-
- /* The regscan pass is currently necessary as the alias
- analysis code depends on this information. */
- reg_scan (insns, max_reg_num (), 1);
- }
- loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
- });
+ timevar_push (TV_LOOP);
+ open_dump_file (DFI_loop, decl);
+ free_bb_for_insn ();
- /* Dump rtl code after loop opt, if we are doing that. */
-
- if (loop_dump)
+ if (flag_rerun_loop_opt)
{
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
+ cleanup_barriers ();
+
+ /* We only want to perform unrolling once. */
+
+ loop_optimize (insns, rtl_dump_file, 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. */
+ delete_trivially_dead_insns (insns, max_reg_num (), 0);
+
+ /* The regscan pass is currently necessary as the alias
+ analysis code depends on this information. */
+ 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));
+
+ close_dump_file (DFI_loop, print_rtl, insns);
+ timevar_pop (TV_LOOP);
+
+ ggc_collect ();
}
if (optimize > 0)
{
- if (cse2_dump)
- open_dump_file (".cse2", decl_printable_name (decl, 2));
+ timevar_push (TV_CSE2);
+ open_dump_file (DFI_cse2, decl);
if (flag_rerun_cse_after_loop)
{
@@ -3984,437 +2916,588 @@ rest_of_compilation (decl)
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 (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
-
- TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
- 1, rtl_dump_file));
- if (tem)
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
- }
+ timevar_push (TV_JUMP);
- if (flag_thread_jumps)
- {
- /* This pass of jump threading straightens out code
- that was kinked by loop optimization. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
- }
+ /* 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);
- /* Dump rtl code after cse, if we are doing that. */
+ reg_scan (insns, max_reg_num (), 0);
- if (cse2_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
- }
- }
+ timevar_push (TV_IFCVT);
- if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
- {
- if (branch_prob_dump)
- open_dump_file (".bp", decl_printable_name (decl, 2));
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ if_convert (0);
- TIMEVAR
- (branch_prob_time,
- {
- branch_prob (insns, rtl_dump_file);
- });
+ timevar_pop(TV_IFCVT);
- if (branch_prob_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
+ 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);
+
+ 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);
+ }
}
- }
- /* We are no longer anticipating cse in this function, at least. */
+ close_dump_file (DFI_cse2, print_rtl, insns);
+ timevar_pop (TV_CSE2);
+
+ ggc_collect ();
+ }
cse_not_expected = 1;
- /* Now we choose between stupid (pcc-like) register allocation
- (if we got the -noreg switch and not -opt)
- and smart register allocation. */
+ regclass_init ();
- if (optimize > 0) /* Stupid allocation probably won't work */
- obey_regdecls = 0; /* if optimizations being done. */
+ /* Do control and data flow analysis; wrote some of the results to
+ the dump file. */
- regclass_init ();
+ timevar_push (TV_FLOW);
+ open_dump_file (DFI_cfg, decl);
- /* Print function header into flow dump now
- because doing the flow analysis makes some of the dump. */
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+ check_function_return_warnings ();
- if (flow_dump)
- open_dump_file (".flow", decl_printable_name (decl, 2));
-
- if (obey_regdecls)
+ /* 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 (flow_time,
- {
- regclass (insns, max_reg_num ());
- stupid_life_analysis (insns, max_reg_num (),
- rtl_dump_file);
- });
+ 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);
}
- else
+
+ open_dump_file (DFI_life, decl);
+ if (optimize)
{
- /* Do control and data flow analysis,
- and write some of the results to dump file. */
+ struct loops loops;
- TIMEVAR
- (flow_time,
- {
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
- life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
- });
+ /* 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 (warn_uninitialized)
- {
- uninitialized_vars_warning (DECL_INITIAL (decl));
- setjmp_args_warning ();
- }
+ /* 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);
}
+ life_analysis (insns, rtl_dump_file, PROP_FINAL);
+ timevar_pop (TV_FLOW);
- /* Dump rtl after flow analysis. */
+ no_new_pseudos = 1;
- if (flow_dump)
+ if (warn_uninitialized || extra_warnings)
{
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
+ uninitialized_vars_warning (DECL_INITIAL (decl));
+ if (extra_warnings)
+ setjmp_args_warning ();
}
- /* The first life analysis pass has finished. From now on we can not
- generate any new pseudos. */
- no_new_pseudos = 1;
+ if (optimize)
+ {
+ if (initialize_uninitialized_subregs ())
+ {
+ /* Insns were inserted, so things might look a bit different. */
+ insns = get_insns ();
+ life_analysis (insns, rtl_dump_file,
+ (PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES));
+ }
+ }
+
+ close_dump_file (DFI_life, print_rtl_with_bb, insns);
+
+ ggc_collect ();
/* If -opt, try combining insns through substitution. */
if (optimize > 0)
{
- TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
+ int rebuild_jump_labels_after_combine = 0;
+
+ timevar_push (TV_COMBINE);
+ open_dump_file (DFI_combine, decl);
+
+ rebuild_jump_labels_after_combine
+ = combine_instructions (insns, max_reg_num ());
- /* Dump rtl code after insn combination. */
+ /* Always purge dead edges, as we may eliminate an insn throwing
+ exception. */
+ rebuild_jump_labels_after_combine |= purge_all_dead_edges (true);
- if (combine_dump)
+ /* Combining insns may have turned an indirect jump into a
+ direct jump. Rebuid the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_jump_labels_after_combine)
{
- dump_rtl (".combine", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (insns);
+ timevar_pop (TV_JUMP);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
}
+
+ close_dump_file (DFI_combine, print_rtl_with_bb, insns);
+ timevar_pop (TV_COMBINE);
+
+ ggc_collect ();
+ }
+
+ /* Rerun if-conversion, as combine may have simplified things enough to
+ now meet sequence length restrictions. */
+ if (optimize > 0)
+ {
+ timevar_push (TV_IFCVT);
+ open_dump_file (DFI_ce, decl);
+
+ no_new_pseudos = 0;
+ if_convert (1);
+ no_new_pseudos = 1;
+
+ close_dump_file (DFI_ce, print_rtl_with_bb, insns);
+ timevar_pop (TV_IFCVT);
}
/* Register allocation pre-pass, to reduce number of moves
necessary for two-address machines. */
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
{
- if (regmove_dump)
- open_dump_file (".regmove", decl_printable_name (decl, 2));
+ timevar_push (TV_REGMOVE);
+ open_dump_file (DFI_regmove, decl);
- TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
- rtl_dump_file));
+ regmove_optimize (insns, max_reg_num (), rtl_dump_file);
- if (regmove_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
- }
+ close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
+ timevar_pop (TV_REGMOVE);
+
+ ggc_collect ();
}
+ /* Do unconditional splitting before register allocation to allow machine
+ description to add extra information not needed previously. */
+ split_all_insns (1);
+
+ /* Any of the several passes since flow1 will have munged register
+ lifetime data a bit. */
+ register_life_up_to_date = 0;
+
+#ifdef OPTIMIZE_MODE_SWITCHING
+ 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;
+ }
+ no_new_pseudos = 1;
+
+ timevar_pop (TV_MODE_SWITCH);
+#endif
+
+ timevar_push (TV_SCHED);
+
+#ifdef INSN_SCHEDULING
+
/* Print function header into sched dump now
because doing the sched analysis makes some of the dump. */
-
if (optimize > 0 && flag_schedule_insns)
{
- if (sched_dump)
- open_dump_file (".sched", decl_printable_name (decl, 2));
+ open_dump_file (DFI_sched, decl);
/* Do control and data sched analysis,
and write some of the results to dump file. */
- TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
+ schedule_insns (rtl_dump_file);
- /* Dump rtl after instruction scheduling. */
+ close_dump_file (DFI_sched, print_rtl_with_bb, insns);
- if (sched_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
- }
+ /* Register lifetime information was updated as part of verifying
+ the schedule. */
+ register_life_up_to_date = 1;
}
+#endif
+ timevar_pop (TV_SCHED);
+
+ ggc_collect ();
/* Determine if the current function is a leaf before running reload
since this can impact optimizations done by the prologue and
epilogue thus changing register elimination offsets. */
current_function_is_leaf = leaf_function_p ();
- /* Unless we did stupid register allocation,
- allocate pseudo-regs that are used only within 1 basic block.
+ timevar_push (TV_LOCAL_ALLOC);
+ open_dump_file (DFI_lreg, decl);
+
+ /* Allocate pseudo-regs that are used only within 1 basic block.
RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
jump optimizer after register allocation and reloading are finished. */
- if (!obey_regdecls)
- TIMEVAR (local_alloc_time,
- {
- recompute_reg_usage (insns, ! optimize_size);
- regclass (insns, max_reg_num ());
- rebuild_label_notes_after_reload = local_alloc ();
- });
- else
- rebuild_label_notes_after_reload = 0;
+ if (! register_life_up_to_date)
+ recompute_reg_usage (insns, ! optimize_size);
+
+ /* 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 (insns, max_reg_num (), rtl_dump_file);
+ rebuild_label_notes_after_reload = local_alloc ();
- /* Dump rtl code after allocating regs within basic blocks. */
+ timevar_pop (TV_LOCAL_ALLOC);
- if (local_reg_dump)
+ if (dump_file[DFI_lreg].enabled)
{
- open_dump_file (".lreg", decl_printable_name (decl, 2));
+ timevar_push (TV_DUMP);
- TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
- TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
+ close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ 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)
+ failure = global_alloc (rtl_dump_file);
+ else
+ {
+ build_insn_chain (insns);
+ failure = reload (insns, 0);
}
- if (global_reg_dump)
- open_dump_file (".greg", decl_printable_name (decl, 2));
+ timevar_pop (TV_GLOBAL_ALLOC);
- /* Unless we did stupid register allocation,
- allocate remaining pseudo-regs, then do the reload pass
- fixing up any insns that are invalid. */
+ if (dump_file[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
- TIMEVAR (global_alloc_time,
- {
- if (!obey_regdecls)
- failure = global_alloc (rtl_dump_file);
- else
- failure = reload (insns, 0, rtl_dump_file);
- });
+ 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 ();
+
+ open_dump_file (DFI_postreload, decl);
+
/* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0)
- reload_cse_regs (insns);
+ {
+ timevar_push (TV_RELOAD_CSE_REGS);
+ reload_cse_regs (insns);
+ timevar_pop (TV_RELOAD_CSE_REGS);
+ }
/* Register allocation and reloading may have turned an indirect jump into
a direct jump. If so, we must rebuild the JUMP_LABEL fields of
jumping instructions. */
if (rebuild_label_notes_after_reload)
- TIMEVAR (jump_time, rebuild_jump_labels (insns));
+ {
+ timevar_push (TV_JUMP);
- /* If optimizing and we are performing instruction scheduling after
- reload, then go ahead and split insns now since we are about to
- recompute flow information anyway.
+ rebuild_jump_labels (insns);
- reload_cse_regs may expose more splitting opportunities, expecially
- for double-word operations. */
- if (optimize > 0 && flag_schedule_insns_after_reload)
- {
- rtx insn;
+ timevar_pop (TV_JUMP);
+ }
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- rtx last;
+ close_dump_file (DFI_postreload, print_rtl_with_bb, insns);
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
- continue;
+ /* Re-create the death notes which were deleted during reload. */
+ timevar_push (TV_FLOW2);
+ open_dump_file (DFI_flow2, decl);
- last = try_split (PATTERN (insn), insn, 1);
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
- if (last != insn)
- {
- PUT_CODE (insn, NOTE);
- NOTE_SOURCE_FILE (insn) = 0;
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- }
- }
- }
+ /* If optimizing, then go ahead and split insns now. */
+ if (optimize > 0)
+ split_all_insns (0);
- if (global_reg_dump)
- {
- TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
- }
+ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
+
+ /* On some machines, the prologue and epilogue code, or parts thereof,
+ can be represented as RTL. Doing so lets us schedule insns between
+ it and the rest of the code and also allows delayed branch
+ scheduling to operate in the epilogue. */
+ thread_prologue_and_epilogue_insns (insns);
- /* Re-create the death notes which were deleted during reload. */
- if (flow2_dump)
- open_dump_file (".flow2", decl_printable_name (decl, 2));
-
if (optimize)
{
- TIMEVAR
- (flow2_time,
- {
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
- life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
- });
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP);
+ life_analysis (insns, rtl_dump_file, PROP_FINAL);
+
+ /* This is kind of a heuristic. We need to run combine_stack_adjustments
+ even for machines with possibly nonzero RETURN_POPS_ARGS
+ and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
+ push instructions will have popping returns. */
+#ifndef PUSH_ROUNDING
+ if (!ACCUMULATE_OUTGOING_ARGS)
+#endif
+ combine_stack_adjustments ();
+
+ ggc_collect ();
}
flow2_completed = 1;
- /* On some machines, the prologue and epilogue code, or parts thereof,
- can be represented as RTL. Doing so lets us schedule insns between
- it and the rest of the code and also allows delayed branch
- scheduling to operate in the epilogue. */
+ close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
+ timevar_pop (TV_FLOW2);
- thread_prologue_and_epilogue_insns (insns);
+#ifdef HAVE_peephole2
+ if (optimize > 0 && flag_peephole2)
+ {
+ timevar_push (TV_PEEPHOLE2);
+ open_dump_file (DFI_peephole2, decl);
+
+ peephole2_optimize (rtl_dump_file);
+
+ close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
+ timevar_pop (TV_PEEPHOLE2);
+ }
+#endif
- if (flow2_dump)
+ if (flag_rename_registers || flag_cprop_registers)
{
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
+ timevar_push (TV_RENAME_REGISTERS);
+ open_dump_file (DFI_rnreg, decl);
+
+ 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);
+ }
+
+ if (optimize > 0)
+ {
+ timevar_push (TV_IFCVT2);
+ open_dump_file (DFI_ce2, decl);
+
+ if_convert (1);
+
+ close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+ timevar_pop (TV_IFCVT2);
}
+#ifdef STACK_REGS
+ if (optimize)
+ split_all_insns (1);
+#endif
+#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
{
- if (sched2_dump)
- open_dump_file (".sched2", decl_printable_name (decl, 2));
+ timevar_push (TV_SCHED2);
+ open_dump_file (DFI_sched2, decl);
/* Do control and data sched analysis again,
and write some more of the results to dump file. */
- TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
+ split_all_insns (1);
- /* Dump rtl after post-reorder instruction scheduling. */
+ schedule_insns (rtl_dump_file);
- if (sched2_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
- }
+ close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
+ timevar_pop (TV_SCHED2);
+
+ ggc_collect ();
}
+#endif
#ifdef LEAF_REGISTERS
current_function_uses_only_leaf_regs
= optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
#endif
- /* One more attempt to remove jumps to .+1
- left by dead-store-elimination.
- Also do cross-jumping this time
- and delete no-op move insns. */
+#ifdef STACK_REGS
+ timevar_push (TV_REG_STACK);
+ open_dump_file (DFI_stack, decl);
- if (optimize > 0)
- {
- TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
- JUMP_NOOP_MOVES,
- !JUMP_AFTER_REGSCAN));
+ reg_to_stack (insns, rtl_dump_file);
- /* Dump rtl code after jump, if we are doing that. */
+ close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+ timevar_pop (TV_REG_STACK);
- if (jump2_opt_dump)
+ ggc_collect ();
+#endif
+ if (optimize > 0)
+ {
+ timevar_push (TV_REORDER_BLOCKS);
+ open_dump_file (DFI_bbro, decl);
+
+ /* Last attempt to optimize CFG, as life analyzis possibly removed
+ some instructions. */
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+ | CLEANUP_CROSSJUMP);
+ if (flag_reorder_blocks)
{
- dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
+ reorder_basic_blocks ();
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
}
+
+ close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+ timevar_pop (TV_REORDER_BLOCKS);
}
+ compute_alignments ();
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
/* If a machine dependent reorganization is needed, call it. */
#ifdef MACHINE_DEPENDENT_REORG
- MACHINE_DEPENDENT_REORG (insns);
-
- if (mach_dep_reorg_dump)
- {
- dump_rtl (".mach", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
- }
+ timevar_push (TV_MACH_DEP);
+ open_dump_file (DFI_mach, decl);
+
+ MACHINE_DEPENDENT_REORG (insns);
+
+ close_dump_file (DFI_mach, print_rtl, insns);
+ timevar_pop (TV_MACH_DEP);
+
+ ggc_collect ();
#endif
+ purge_line_number_notes (insns);
+ cleanup_barriers ();
+
/* If a scheduling pass for delayed branches is to be done,
call the scheduling code. */
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
{
- if (dbr_sched_dump)
- open_dump_file (".dbr", decl_printable_name (decl, 2));
+ timevar_push (TV_DBR_SCHED);
+ open_dump_file (DFI_dbr, decl);
- TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
+ dbr_schedule (insns, rtl_dump_file);
- if (dbr_sched_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
- }
+ close_dump_file (DFI_dbr, print_rtl, insns);
+ timevar_pop (TV_DBR_SCHED);
+
+ ggc_collect ();
}
#endif
- /* Shorten branches. */
- TIMEVAR (shorten_branch_time,
- {
- shorten_branches (get_insns ());
- });
+#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
+ timevar_push (TV_SHORTEN_BRANCH);
+ split_all_insns_noflow ();
+ timevar_pop (TV_SHORTEN_BRANCH);
+#endif
-#ifdef STACK_REGS
- if (stack_reg_dump)
- open_dump_file (".stack", decl_printable_name (decl, 2));
+ convert_to_eh_region_ranges ();
- TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
+ /* Shorten branches. */
+ timevar_push (TV_SHORTEN_BRANCH);
+ shorten_branches (get_insns ());
+ timevar_pop (TV_SHORTEN_BRANCH);
- if (stack_reg_dump)
- {
- dump_rtl (".stack", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
- }
-#endif
+ current_function_nothrow = nothrow_function_p ();
+ if (current_function_nothrow)
+ /* Now we know that this can't throw; set the flag for the benefit
+ of other functions later in this translation unit. */
+ TREE_NOTHROW (current_function_decl) = 1;
/* Now turn the rtl into assembler code. */
- TIMEVAR (final_time,
- {
- rtx x;
- char *fnname;
+ timevar_push (TV_FINAL);
+ {
+ rtx x;
+ const char *fnname;
- /* Get the function's name, as described by its RTL.
- This may be different from the DECL_NAME name used
- in the source file. */
+ /* Get the function's name, as described by its RTL. This may be
+ different from the DECL_NAME name used in the source file. */
- x = DECL_RTL (decl);
- if (GET_CODE (x) != MEM)
- abort ();
- x = XEXP (x, 0);
- if (GET_CODE (x) != SYMBOL_REF)
- abort ();
- fnname = XSTR (x, 0);
+ x = DECL_RTL (decl);
+ if (GET_CODE (x) != MEM)
+ abort ();
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ abort ();
+ fnname = XSTR (x, 0);
- assemble_start_function (decl, fnname);
- final_start_function (insns, asm_out_file, optimize);
- final (insns, asm_out_file, optimize, 0);
- final_end_function (insns, asm_out_file, optimize);
- assemble_end_function (decl, fnname);
- if (! quiet_flag)
- fflush (asm_out_file);
+ assemble_start_function (decl, fnname);
+ final_start_function (insns, asm_out_file, optimize);
+ final (insns, asm_out_file, optimize, 0);
+ final_end_function ();
- /* Release all memory allocated by flow. */
- free_basic_block_vars (0);
+#ifdef IA64_UNWIND_INFO
+ /* ??? The IA-64 ".handlerdata" directive must be issued before
+ the ".endp" directive that closes the procedure descriptor. */
+ output_function_exception_table ();
+#endif
- /* Release all memory held by regsets now */
- regset_release_memory ();
- });
+ assemble_end_function (decl, fnname);
- /* Write DBX symbols if requested */
+#ifndef IA64_UNWIND_INFO
+ /* Otherwise, it feels unclean to switch sections in the middle. */
+ output_function_exception_table ();
+#endif
+
+ if (! quiet_flag)
+ fflush (asm_out_file);
+
+ /* Release all memory allocated by flow. */
+ free_basic_block_vars (0);
+
+ /* Release all memory held by regsets now. */
+ regset_release_memory ();
+ }
+ timevar_pop (TV_FINAL);
+
+ ggc_collect ();
+
+ /* Write DBX symbols if requested. */
/* Note that for those inline functions where we don't initially
know for certain that we will be generating an out-of-line copy,
@@ -4424,25 +3507,12 @@ rest_of_compilation (decl)
for those inline functions that need to have out-of-line copies
generated. During that call, we *will* be routed past here. */
-#ifdef DBX_DEBUGGING_INFO
- if (write_symbols == DBX_DEBUG)
- TIMEVAR (symout_time, dbxout_function (decl));
-#endif
-
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
-#endif
-
-#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG)
- TIMEVAR (symout_time, dwarf2out_decl (decl));
-#endif
+ timevar_push (TV_SYMOUT);
+ (*debug_hooks->function_decl) (decl);
+ timevar_pop (TV_SYMOUT);
exit_rest_of_compilation:
- free_bb_mem ();
-
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */
@@ -4451,38 +3521,27 @@ rest_of_compilation (decl)
sdbout_types (NULL_TREE);
#endif
- /* Put back the tree of subblocks and list of arguments
- from before we copied them.
- Code generation and the output of debugging info may have modified
- the copy, but the original is unchanged. */
-
- if (saved_block_tree != 0)
- {
- DECL_INITIAL (decl) = saved_block_tree;
- DECL_ARGUMENTS (decl) = saved_arguments;
- DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
- }
-
reload_completed = 0;
flow2_completed = 0;
no_new_pseudos = 0;
- TIMEVAR (final_time,
- {
- /* Clear out the insn_length contents now that they are no
- longer valid. */
- init_insn_lengths ();
+ timevar_push (TV_FINAL);
+
+ /* Clear out the insn_length contents now that they are no
+ longer valid. */
+ init_insn_lengths ();
+
+ /* Clear out the real_constant_chain before some of the rtx's
+ it runs through become garbage. */
+ clear_const_double_mem ();
- /* Clear out the real_constant_chain before some of the rtx's
- it runs through become garbage. */
- clear_const_double_mem ();
+ /* Show no temporary slots allocated. */
+ init_temp_slots ();
- /* Cancel the effect of rtl_in_current_obstack. */
- resume_temporary_allocation ();
+ free_basic_block_vars (0);
+ free_bb_for_insn ();
- /* Show no temporary slots allocated. */
- init_temp_slots ();
- });
+ timevar_pop (TV_FINAL);
/* Make sure volatile mem refs aren't considered valid operands for
arithmetic insns. We must call this here if this is a nested inline
@@ -4495,88 +3554,107 @@ rest_of_compilation (decl)
init_recog_no_volatile ();
- /* The parsing time is all the time spent in yyparse
- *except* what is spent in this function. */
+ /* We're done with this function. Free up memory if we can. */
+ free_after_parsing (cfun);
+ if (! DECL_DEFER_OUTPUT (decl))
+ {
+ free_after_compilation (cfun);
+
+ /* Clear integrate.c's pointer to the cfun structure we just
+ destroyed. */
+ DECL_SAVED_INSNS (decl) = 0;
+ }
+ cfun = 0;
- parse_time -= get_run_time () - start_time;
+ ggc_collect ();
- /* Reset global variables. */
- free_basic_block_vars (0);
+ timevar_pop (TV_REST_OF_COMPILATION);
}
static void
display_help ()
{
- int undoc;
- unsigned long i;
- const char * lang;
-
-#ifndef USE_CPPLIB
- printf ("Usage: %s input [switches]\n", progname);
- printf ("Switches:\n");
-#endif
- printf (" -ffixed-<register> Mark <register> as being unavailable to the compiler\n");
- printf (" -fcall-used-<register> Mark <register> as being corrupted by function calls\n");
- printf (" -fcall-saved-<register> Mark <register> as being preserved across functions\n");
- printf (" -finline-limit-<number> Limits the size of inlined functions to <number>\n");
-
- for (i = NUM_ELEM (f_options); i--;)
+ int undoc;
+ unsigned long i;
+ const char *lang;
+
+ printf (_(" -ffixed-<register> Mark <register> as being unavailable to the compiler\n"));
+ printf (_(" -fcall-used-<register> Mark <register> as being corrupted by function calls\n"));
+ printf (_(" -fcall-saved-<register> Mark <register> as being preserved across functions\n"));
+ printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
+ printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
+ printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
+
+ for (i = ARRAY_SIZE (f_options); i--;)
{
- const char * description = f_options[i].description;
-
+ const char *description = f_options[i].description;
+
if (description != NULL && * description != 0)
printf (" -f%-21s %s\n",
- f_options[i].string, description);
+ f_options[i].string, _(description));
+ }
+
+ 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;
+ const int length = 21-strlen(compiler_params[i].option);
+
+ if (description != NULL && * description != 0)
+ printf (" --param %s=<value>%.*s%s\n",
+ compiler_params[i].option,
+ length > 0 ? length : 1, " ",
+ _(description));
}
-
- printf (" -O[number] Set optimisation level to [number]\n");
- printf (" -Os Optimise for space rather than speed\n");
- printf (" -pedantic Issue warnings needed by strict compliance to ANSI C\n");
- printf (" -pedantic-errors Like -pedantic except that errors are produced\n");
- printf (" -w Suppress warnings\n");
- printf (" -W Enable extra warnings\n");
-
- for (i = NUM_ELEM (W_options); i--;)
+ printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n"));
+ printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n"));
+ printf (_(" -w Suppress warnings\n"));
+ printf (_(" -W Enable extra warnings\n"));
+
+ for (i = ARRAY_SIZE (W_options); i--;)
{
- const char * description = W_options[i].description;
-
+ const char *description = W_options[i].description;
+
if (description != NULL && * description != 0)
printf (" -W%-21s %s\n",
- W_options[i].string, description);
+ W_options[i].string, _(description));
}
-
- printf (" -Wid-clash-<num> Warn if 2 identifiers have the same first <num> chars\n");
- printf (" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n");
- printf (" -p Enable function profiling\n");
+
+ printf (_(" -Wunused Enable unused warnings\n"));
+ printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"));
+ printf (_(" -p Enable function profiling\n"));
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
- printf (" -a Enable block profiling \n");
-#endif
+ printf (_(" -a Enable block profiling \n"));
+#endif
#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
- printf (" -ax Enable jump profiling \n");
-#endif
- printf (" -o <file> Place output into <file> \n");
- printf (" -G <number> Put global and static data smaller than <number>\n");
- printf (" bytes into a special section (on some targets)\n");
-
- for (i = NUM_ELEM (debug_args); i--;)
+ printf (_(" -ax Enable jump profiling \n"));
+#endif
+ printf (_(" -o <file> Place output into <file> \n"));
+ printf (_("\
+ -G <number> Put global and static data smaller than <number>\n\
+ bytes into a special section (on some targets)\n"));
+
+ for (i = ARRAY_SIZE (debug_args); i--;)
{
if (debug_args[i].description != NULL)
- printf (" -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
+ printf (" -g%-21s %s\n",
+ debug_args[i].arg, _(debug_args[i].description));
}
-
- printf (" -aux-info <file> Emit declaration info into <file>.X\n");
- printf (" -quiet Do not display functions compiled or elapsed time\n");
- printf (" -version Display the compiler's version\n");
- printf (" -d[letters] Enable dumps from specific passes of the compiler\n");
- printf (" -dumpbase <file> Base name to be used for dumps from specific passes\n");
-#if defined HAIFA || defined INSN_SCHEDULING
- printf (" -sched-verbose-<number> Set the verbosity level of the scheduler\n");
+
+ printf (_(" -aux-info <file> Emit declaration info into <file>\n"));
+ printf (_(" -quiet Do not display functions compiled or elapsed time\n"));
+ printf (_(" -version Display the compiler's version\n"));
+ printf (_(" -d[letters] Enable dumps from specific passes of the compiler\n"));
+ printf (_(" -dumpbase <file> Base name to be used for dumps from specific passes\n"));
+#if defined INSN_SCHEDULING
+ printf (_(" -fsched-verbose=<number> Set the verbosity level of the scheduler\n"));
#endif
- printf (" --help Display this information\n");
+ printf (_(" --help Display this information\n"));
undoc = 0;
lang = "language";
-
+
/* Display descriptions of language specific options.
If there is no description, note that there is an undocumented option.
If the description is empty, do not display anything. (This allows
@@ -4584,920 +3662,675 @@ display_help ()
If the option string is missing, then this is a marker, indicating
that the description string is in fact the name of a language, whose
language specific options are to follow. */
-
- if (NUM_ELEM (documented_lang_options) > 1)
+
+ if (ARRAY_SIZE (documented_lang_options) > 1)
{
- printf ("\nLanguage specific options:\n");
+ printf (_("\nLanguage specific options:\n"));
- for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
+ for (i = 0; i < ARRAY_SIZE (documented_lang_options); i++)
{
- const char * description = documented_lang_options[i].description;
- const char * option = documented_lang_options[i].option;
+ const char *description = documented_lang_options[i].description;
+ const char *option = documented_lang_options[i].option;
if (description == NULL)
{
undoc = 1;
if (extra_warnings)
- printf (" %-23.23s [undocumented]\n", option);
+ printf (_(" %-23.23s [undocumented]\n"), option);
}
- else if (* description == 0)
+ else if (*description == 0)
continue;
else if (option == NULL)
{
if (undoc)
printf
- ("\nThere are undocumented %s specific options as well.\n",
+ (_("\nThere are undocumented %s specific options as well.\n"),
lang);
undoc = 0;
-
- printf ("\n Options for %s:\n", description);
+
+ printf (_("\n Options for %s:\n"), description);
lang = description;
}
else
- printf (" %-23.23s %s\n", option, description);
+ printf (" %-23.23s %s\n", option, _(description));
}
}
if (undoc)
- printf ("\nThere are undocumented %s specific options as well.\n", lang);
+ printf (_("\nThere are undocumented %s specific options as well.\n"),
+ lang);
- if (NUM_ELEM (target_switches) > 1
+ display_target_options ();
+}
+
+static void
+display_target_options ()
+{
+ 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
- || NUM_ELEM (target_options) > 1
+ || ARRAY_SIZE (target_options) > 1
#endif
)
{
int doc = 0;
-
+
undoc = 0;
-
- printf ("\nTarget specific options:\n");
- for (i = NUM_ELEM (target_switches); i--;)
+ printf (_("\nTarget specific options:\n"));
+
+ for (i = ARRAY_SIZE (target_switches); i--;)
{
- const char * option = target_switches[i].name;
- const char * description = target_switches[i].description;
+ const char *option = target_switches[i].name;
+ const char *description = target_switches[i].description;
- if (option == NULL || * option == 0)
+ if (option == NULL || *option == 0)
continue;
else if (description == NULL)
{
undoc = 1;
-
+
if (extra_warnings)
- printf (" -m%-21.21s [undocumented]\n", option);
+ printf (_(" -m%-23.23s [undocumented]\n"), option);
}
else if (* description != 0)
- doc += printf (" -m%-21.21s %s\n", option, description);
+ doc += printf (" -m%-23.23s %s\n", option, _(description));
}
-
-#ifdef TARGET_OPTIONS
- for (i = NUM_ELEM (target_options); i--;)
+
+#ifdef TARGET_OPTIONS
+ for (i = ARRAY_SIZE (target_options); i--;)
{
- const char * option = target_options[i].prefix;
- const char * description = target_options[i].description;
+ const char *option = target_options[i].prefix;
+ const char *description = target_options[i].description;
- if (option == NULL || * option == 0)
+ if (option == NULL || *option == 0)
continue;
else if (description == NULL)
{
undoc = 1;
-
+
if (extra_warnings)
- printf (" -m%-21.21s [undocumented]\n", option);
+ printf (_(" -m%-23.23s [undocumented]\n"), option);
}
else if (* description != 0)
- doc += printf (" -m%-21.21s %s\n", option, description);
+ doc += printf (" -m%-23.23s %s\n", option, _(description));
}
#endif
if (undoc)
{
if (doc)
- printf ("\nThere are undocumented target specific options as well.\n");
+ printf (_("\nThere are undocumented target specific options as well.\n"));
else
- printf (" They exist, but they are not documented.\n");
+ printf (_(" They exist, but they are not documented.\n"));
}
}
}
+
+/* Parse a -d... command line switch. */
-/* Compare the user specified 'option' with the language
- specific 'lang_option'. Return true if they match, or
- if 'option' is a viable prefix of 'lang_option'. */
-
-static int
-check_lang_option (option, lang_option)
- char * option;
- char * lang_option;
+static void
+decode_d_option (arg)
+ const char *arg;
{
- lang_independent_options * indep_options;
- int len;
- int numopts;
- long k;
- char * space;
-
- /* Ignore NULL entries. */
- if (option == NULL || lang_option == NULL)
- return 0;
+ int i, c, matched;
- if ((space = strchr (lang_option, ' ')) != NULL)
- len = space - lang_option;
- else
- len = strlen (lang_option);
-
- /* If they do not match to the first n characters then fail. */
- if (strncmp (option, lang_option, len) != 0)
- return 0;
-
- /* Do not accept a lang option, if it matches a normal -f or -W
- option. Chill defines a -fpack, but we want to support
- -fpack-struct. */
-
- /* An exact match is OK */
- if ((int) strlen (option) == len)
- return 1;
-
- /* If it is not an -f or -W option allow the match */
- if (option[0] != '-')
- return 1;
-
- switch (option[1])
- {
- case 'f':
- indep_options = f_options;
- numopts = NUM_ELEM (f_options);
- break;
- case 'W':
- indep_options = W_options;
- numopts = NUM_ELEM (W_options);
- break;
- default: return 1;
- }
-
- /* The option is a -f or -W option.
- Skip past the prefix and search for the remainder in the
- appropriate table of options. */
- option += 2;
-
- if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
- option += 3;
-
- for (k = numopts; k--;)
- {
- if (!strcmp (option, indep_options[k].string))
- {
- /* The option matched a language independent option,
- do not allow the language specific match. */
-
- return 0;
- }
- }
-
- /* The option matches the start of the langauge specific option
- and it is not an exact match for a language independent option. */
- return 1;
-}
-
-/* Entry point of cc1/c++. Decode command args, then call compile_file.
- Exit code is 35 if can't open files, 34 if fatal error,
- 33 if had nonfatal errors, else success. */
+ while (*arg)
+ switch (c = *arg++)
+ {
+ case 'a':
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ dump_file[i].enabled = 1;
+ break;
+ case 'A':
+ flag_debug_asm = 1;
+ break;
+ case 'p':
+ flag_print_asm_name = 1;
+ break;
+ case 'P':
+ flag_dump_rtl_in_asm = 1;
+ flag_print_asm_name = 1;
+ break;
+ case 'v':
+ graph_dump_format = vcg;
+ break;
+ case 'x':
+ rtl_dump_and_exit = 1;
+ break;
+ case 'y':
+ (*lang_hooks.set_yydebug) (1);
+ break;
+ case 'D': /* These are handled by the preprocessor. */
+ case 'I':
+ break;
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- register int i;
- char *filename = 0;
- int flag_print_mem = 0;
- int version_flag = 0;
- char *p;
+ default:
+ matched = 0;
+ for (i = 0; i < (int) DFI_MAX; ++i)
+ if (c == dump_file[i].debug_switch)
+ {
+ dump_file[i].enabled = 1;
+ matched = 1;
+ }
- /* save in case md file wants to emit args as a comment. */
- save_argc = argc;
- save_argv = argv;
+ if (! matched)
+ warning ("unrecognized gcc debugging option: %c", c);
+ break;
+ }
+}
- p = argv[0] + strlen (argv[0]);
- while (p != argv[0] && p[-1] != '/'
-#ifdef DIR_SEPARATOR
- && p[-1] != DIR_SEPARATOR
-#endif
- )
- --p;
- progname = p;
+/* Parse a -f... command line switch. ARG is the value after the -f.
+ It is safe to access 'ARG - 2' to generate the full switch name.
+ Return the number of strings consumed. */
-#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
- /* Get rid of any avoidable limit on stack size. */
- {
- struct rlimit rlim;
+static int
+decode_f_option (arg)
+ const char *arg;
+{
+ int j;
+ const char *option_value = NULL;
- /* Set the stack limit huge so that alloca does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif
+ /* Search for the option in the table of binary f options. */
+ for (j = ARRAY_SIZE (f_options); j--;)
+ {
+ if (!strcmp (arg, f_options[j].string))
+ {
+ *f_options[j].variable = f_options[j].on_value;
+ return 1;
+ }
-#ifdef HAVE_LC_MESSAGES
- setlocale (LC_MESSAGES, "");
-#endif
- (void) bindtextdomain (PACKAGE, localedir);
- (void) textdomain (PACKAGE);
+ if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
+ && ! strcmp (arg + 3, f_options[j].string))
+ {
+ *f_options[j].variable = ! f_options[j].on_value;
+ return 1;
+ }
+ }
- signal (SIGFPE, float_signal);
+ if (!strcmp (arg, "fast-math"))
+ set_fast_math_flags ();
+ else if (!strcmp (arg, "no-fast-math"))
+ set_no_fast_math_flags ();
+ else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
+ || (option_value = skip_leading_substring (arg, "inline-limit=")))
+ {
+ int val =
+ read_integral_parameter (option_value, arg - 2,
+ MAX_INLINE_INSNS);
+ set_param_value ("max-inline-insns", val);
+ }
+#ifdef INSN_SCHEDULING
+ else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
+ fix_sched_param ("verbose", option_value);
+#endif
+ else if ((option_value = skip_leading_substring (arg, "fixed-")))
+ fix_register (option_value, 1, 1);
+ else if ((option_value = skip_leading_substring (arg, "call-used-")))
+ fix_register (option_value, 0, 1);
+ else if ((option_value = skip_leading_substring (arg, "call-saved-")))
+ fix_register (option_value, 0, 0);
+ else if ((option_value = skip_leading_substring (arg, "align-loops=")))
+ align_loops = read_integral_parameter (option_value, arg - 2, align_loops);
+ else if ((option_value = skip_leading_substring (arg, "align-functions=")))
+ align_functions
+ = read_integral_parameter (option_value, arg - 2, align_functions);
+ else if ((option_value = skip_leading_substring (arg, "align-jumps=")))
+ align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps);
+ else if ((option_value = skip_leading_substring (arg, "align-labels=")))
+ align_labels
+ = read_integral_parameter (option_value, arg - 2, align_labels);
+ else if ((option_value
+ = skip_leading_substring (arg, "stack-limit-register=")))
+ {
+ int reg = decode_reg_name (option_value);
+ if (reg < 0)
+ error ("unrecognized register name `%s'", option_value);
+ else
+ stack_limit_rtx = gen_rtx_REG (Pmode, reg);
+ }
+ else if ((option_value
+ = skip_leading_substring (arg, "stack-limit-symbol=")))
+ {
+ const char *nm;
+ nm = ggc_strdup (option_value);
+ stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
+ }
+ else if ((option_value
+ = skip_leading_substring (arg, "message-length=")))
+ output_set_maximum_length
+ (&global_dc->buffer, read_integral_parameter
+ (option_value, arg - 2, diagnostic_line_cutoff (global_dc)));
+ else if ((option_value
+ = skip_leading_substring (arg, "diagnostics-show-location=")))
+ {
+ if (!strcmp (option_value, "once"))
+ diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ else if (!strcmp (option_value, "every-line"))
+ diagnostic_prefixing_rule (global_dc)
+ = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+ else
+ error ("unrecognized option `%s'", arg - 2);
+ }
+ else if (!strcmp (arg, "no-stack-limit"))
+ stack_limit_rtx = NULL_RTX;
+ else if (!strcmp (arg, "preprocessed"))
+ /* Recognise this switch but do nothing. This prevents warnings
+ about an unrecognized switch if cpplib has not been linked in. */
+ ;
+ else
+ return 0;
-#ifdef SIGPIPE
- signal (SIGPIPE, pipe_closed);
-#endif
+ return 1;
+}
- decl_printable_name = decl_name;
- lang_expand_expr = (lang_expand_expr_t) do_abort;
+/* Parse a -W... command line switch. ARG is the value after the -W.
+ It is safe to access 'ARG - 2' to generate the full switch name.
+ Return the number of strings consumed. */
- /* 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
+static int
+decode_W_option (arg)
+ const char *arg;
+{
+ const char *option_value = NULL;
+ int j;
- /* Perform language-specific options intialization. */
- lang_init_options ();
+ /* Search for the option in the table of binary W options. */
- /* Scan to see what optimization level has been specified. That will
- determine the default value of many flags. */
- for (i = 1; i < argc; i++)
+ for (j = ARRAY_SIZE (W_options); j--;)
{
- if (!strcmp (argv[i], "-O"))
+ if (!strcmp (arg, W_options[j].string))
{
- optimize = 1;
- optimize_size = 0;
+ *W_options[j].variable = W_options[j].on_value;
+ return 1;
}
- else if (argv[i][0] == '-' && argv[i][1] == 'O')
- {
- /* Handle -Os, -O2, -O3, -O69, ... */
- char *p = &argv[i][2];
-
- if ((p[0] == 's') && (p[1] == 0))
- {
- optimize_size = 1;
-
- /* Optimizing for size forces optimize to be 2. */
- optimize = 2;
- }
- else
- {
- const int optimize_val = read_integral_parameter (p, p - 2, -1);
- if (optimize_val != -1)
- {
- optimize = optimize_val;
-#ifdef FORCE_OPTIMIZATION_DOWNGRADE
-#warning FORCE_OPTIMIZATION_DOWNGRADE
- if (optimize > FORCE_OPTIMIZATION_DOWNGRADE)
- {
- optimize = FORCE_OPTIMIZATION_DOWNGRADE;
- warning ("\n***\n***\t-O%d converted to \"-O%d\" due to optimizer bugs on this platform\n***\n",
- optimize_val,
- FORCE_OPTIMIZATION_DOWNGRADE);
- }
-#endif /*FORCE_OPTIMIZATION_DOWNGRADE*/
-#if defined(__alpha__)
- if (optimize > 1)
- {
- warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n",
- optimize_val);
- }
-#endif /*__alpha__*/
- optimize_size = 0;
- }
- }
+ if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
+ && ! strcmp (arg + 3, W_options[j].string))
+ {
+ *W_options[j].variable = ! W_options[j].on_value;
+ return 1;
}
}
- obey_regdecls = (optimize == 0);
-
- if (optimize >= 1)
+ if ((option_value = skip_leading_substring (arg, "id-clash-")))
+ warning ("-Wid-clash-LEN is no longer supported");
+ else if ((option_value = skip_leading_substring (arg, "larger-than-")))
{
- flag_defer_pop = 1;
- flag_thread_jumps = 1;
-#ifdef DELAY_SLOTS
- flag_delayed_branch = 1;
-#endif
-#ifdef CAN_DEBUG_WITHOUT_FP
- flag_omit_frame_pointer = 1;
-#endif
- }
+ larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
- if (optimize >= 2)
+ warn_larger_than = larger_than_size != -1;
+ }
+ else if (!strcmp (arg, "unused"))
{
- flag_cse_follow_jumps = 1;
- flag_cse_skip_blocks = 1;
- flag_gcse = 1;
- flag_expensive_optimizations = 1;
- flag_strength_reduce = 1;
- flag_rerun_cse_after_loop = 1;
- flag_rerun_loop_opt = 1;
- flag_caller_saves = 1;
- flag_force_mem = 1;
-#ifdef INSN_SCHEDULING
- flag_schedule_insns = 1;
- flag_schedule_insns_after_reload = 1;
-#endif
- flag_regmove = 1;
+ set_Wunused (1);
}
-
- if (optimize >= 3)
+ else if (!strcmp (arg, "no-unused"))
{
- flag_inline_functions = 1;
+ set_Wunused (0);
}
+ else
+ return 0;
- /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
- modify it. */
- target_flags = 0;
- set_target_switch ("");
+ return 1;
+}
-#ifdef OPTIMIZATION_OPTIONS
- /* Allow default optimizations to be specified on a per-machine basis. */
- OPTIMIZATION_OPTIONS (optimize, optimize_size);
-#endif
+/* Parse a -g... command line switch. ARG is the value after the -g.
+ It is safe to access 'ARG - 2' to generate the full switch name.
+ Return the number of strings consumed. */
- /* Initialize register usage now so switches may override. */
- init_reg_sets ();
+static int
+decode_g_option (arg)
+ const char *arg;
+{
+ static unsigned level=0;
+ /* A lot of code assumes write_symbols == NO_DEBUG if the
+ debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
+ of what debugging type has been selected). This records the
+ selected type. It is an error to specify more than one
+ debugging type. */
+ static enum debug_info_type selected_debug_type = NO_DEBUG;
+ /* Non-zero if debugging format has been explicitly set.
+ -g and -ggdb don't explicitly set the debugging format so
+ -gdwarf -g3 is equivalent to -gdwarf3. */
+ static int type_explicitly_set_p = 0;
+ /* Indexed by enum debug_info_type. */
+ static const char *const debug_type_names[] =
+ {
+ "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
+ };
- for (i = 1; i < argc; i++)
+ /* The maximum admissible debug level value. */
+ static const unsigned max_debug_level = 3;
+
+ /* Look up ARG in the table. */
+ for (da = debug_args; da->arg; da++)
{
- size_t j;
-
- /* If this is a language-specific option,
- decode it in a language-specific way. */
- for (j = NUM_ELEM (documented_lang_options); j--;)
- if (check_lang_option (argv[i], documented_lang_options[j].option))
- break;
-
- if (j != (size_t)-1)
- {
- /* If the option is valid for *some* language,
- treat it as valid even if this language doesn't understand it. */
- int strings_processed = lang_decode_option (argc - i, argv + i);
-
- if (!strcmp (argv[i], "--help"))
- {
- display_help ();
- exit (0);
- }
-
- if (strings_processed != 0)
- i += strings_processed - 1;
- }
- else if (argv[i][0] == '-' && argv[i][1] != 0)
+ const int da_len = strlen (da->arg);
+
+ if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
{
- register char *str = argv[i] + 1;
- if (str[0] == 'Y')
- str++;
+ enum debug_info_type type = da->debug_type;
+ const char *p = arg + da_len;
- if (str[0] == 'm')
- set_target_switch (&str[1]);
- else if (!strcmp (str, "dumpbase"))
- {
- dump_base_name = argv[++i];
- }
- else if (str[0] == 'd')
- {
- register char *p = &str[1];
- while (*p)
- switch (*p++)
- {
- case 'a':
- branch_prob_dump = 1;
- combine_dump = 1;
-#ifdef DELAY_SLOTS
- dbr_sched_dump = 1;
-#endif
- flow_dump = 1;
- flow2_dump = 1;
- global_reg_dump = 1;
- jump_opt_dump = 1;
- addressof_dump = 1;
- jump2_opt_dump = 1;
- local_reg_dump = 1;
- loop_dump = 1;
- regmove_dump = 1;
- rtl_dump = 1;
- cse_dump = 1, cse2_dump = 1;
- gcse_dump = 1;
- sched_dump = 1;
- sched2_dump = 1;
-#ifdef STACK_REGS
- stack_reg_dump = 1;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
- mach_dep_reorg_dump = 1;
-#endif
- break;
- case 'A':
- flag_debug_asm = 1;
- break;
- case 'b':
- branch_prob_dump = 1;
- break;
- case 'c':
- combine_dump = 1;
- break;
-#ifdef DELAY_SLOTS
- case 'd':
- dbr_sched_dump = 1;
- break;
-#endif
- case 'f':
- flow_dump = 1;
- break;
- case 'F':
- addressof_dump = 1;
- break;
- case 'g':
- global_reg_dump = 1;
- break;
- case 'G':
- gcse_dump = 1;
- break;
- case 'j':
- jump_opt_dump = 1;
- break;
- case 'J':
- jump2_opt_dump = 1;
- break;
-#ifdef STACK_REGS
- case 'k':
- stack_reg_dump = 1;
- break;
-#endif
- case 'l':
- local_reg_dump = 1;
- break;
- case 'L':
- loop_dump = 1;
- break;
- case 'm':
- flag_print_mem = 1;
- break;
-#ifdef MACHINE_DEPENDENT_REORG
- case 'M':
- mach_dep_reorg_dump = 1;
- break;
-#endif
- case 'p':
- flag_print_asm_name = 1;
- break;
- case 'r':
- rtl_dump = 1;
- break;
- case 'R':
- sched2_dump = 1;
- break;
- case 's':
- cse_dump = 1;
- break;
- case 'S':
- sched_dump = 1;
- break;
- case 't':
- cse2_dump = 1;
- break;
- case 'N':
- regmove_dump = 1;
- break;
- case 'v':
- graph_dump_format = vcg;
- break;
- case 'w':
- flow2_dump = 1;
- break;
- case 'y':
- set_yydebug (1);
- break;
- case 'x':
- rtl_dump_and_exit = 1;
- break;
- case 'D': /* these are handled by the preprocessor */
- case 'I':
- break;
- default:
- warning ("unrecognised gcc debugging option: %c", p[-1]);
- break;
- }
- }
- else if (str[0] == 'f')
- {
- register char *p = &str[1];
- int found = 0;
+ if (*p && ! ISDIGIT (*p))
+ continue;
- /* Some kind of -f option.
- P's value is the option sans `-f'.
- Search for it in the table of options. */
+ /* A debug flag without a level defaults to level 2.
+ Note we do not want to call read_integral_parameter
+ for that case since it will call atoi which
+ will return zero.
- for (j = 0;
- !found && j < sizeof (f_options) / sizeof (f_options[0]);
- j++)
- {
- if (!strcmp (p, f_options[j].string))
- {
- *f_options[j].variable = f_options[j].on_value;
- /* A goto here would be cleaner,
- but breaks the vax pcc. */
- found = 1;
- }
- if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
- && ! strcmp (p+3, f_options[j].string))
- {
- *f_options[j].variable = ! f_options[j].on_value;
- found = 1;
- }
- }
+ ??? We may want to generalize the interface to
+ read_integral_parameter to better handle this case
+ if this case shows up often. */
+ if (*p)
+ level = read_integral_parameter (p, 0, max_debug_level + 1);
+ else
+ level = (level == 0) ? 2 : level;
- if (found)
- ;
- else if (!strncmp (p, "inline-limit-", 13))
- inline_max_insns =
- read_integral_parameter (p + 13, p - 2, inline_max_insns);
-#ifdef HAIFA
-#ifdef INSN_SCHEDULING
- else if (!strncmp (p, "sched-verbose-",14))
- fix_sched_param("verbose",&p[14]);
-#endif
-#endif /* HAIFA */
- else if (!strncmp (p, "fixed-", 6))
- fix_register (&p[6], 1, 1);
- else if (!strncmp (p, "call-used-", 10))
- fix_register (&p[10], 0, 1);
- else if (!strncmp (p, "call-saved-", 11))
- fix_register (&p[11], 0, 0);
- else
- error ("Invalid option `%s'", argv[i]);
- }
- else if (str[0] == 'O')
- {
- /* Already been treated above. Do nothing. */
- }
- else if (!strcmp (str, "pedantic"))
- pedantic = 1;
- else if (!strcmp (str, "pedantic-errors"))
- flag_pedantic_errors = pedantic = 1;
- else if (!strcmp (str, "quiet"))
- quiet_flag = 1;
- else if (!strcmp (str, "version"))
- version_flag = 1;
- else if (!strcmp (str, "w"))
- inhibit_warnings = 1;
- else if (!strcmp (str, "W"))
+ if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
{
- extra_warnings = 1;
- /* We save the value of warn_uninitialized, since if they put
- -Wuninitialized on the command line, we need to generate a
- warning about not using it without also specifying -O. */
- if (warn_uninitialized != 1)
- warn_uninitialized = 2;
+ error ("use -gdwarf -g%d for DWARF v1, level %d",
+ level, level);
+ if (level == 2)
+ error ("use -gdwarf-2 for DWARF v2");
}
- else if (str[0] == 'W')
- {
- register char *p = &str[1];
- int found = 0;
- /* Some kind of -W option.
- P's value is the option sans `-W'.
- Search for it in the table of options. */
-
- for (j = 0;
- !found && j < sizeof (W_options) / sizeof (W_options[0]);
- j++)
- {
- if (!strcmp (p, W_options[j].string))
- {
- *W_options[j].variable = W_options[j].on_value;
- /* A goto here would be cleaner,
- but breaks the vax pcc. */
- found = 1;
- }
- if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
- && ! strcmp (p+3, W_options[j].string))
- {
- *W_options[j].variable = ! W_options[j].on_value;
- found = 1;
- }
- }
-
- if (found)
- ;
- else if (!strncmp (p, "id-clash-", 9))
- {
- const int id_clash_val
- = read_integral_parameter (p + 9, p - 2, -1);
- if (id_clash_val != -1)
- {
- id_clash_len = id_clash_val;
- warn_id_clash = 1;
- }
- }
- else if (!strncmp (p, "larger-than-", 12))
- {
- const int larger_than_val
- = read_integral_parameter (p + 12, p - 2, -1);
- if (larger_than_val != -1)
- {
- larger_than_size = larger_than_val;
- warn_larger_than = 1;
- }
- }
- else
- error ("Invalid option `%s'", argv[i]);
- }
- else if (!strcmp (str, "p"))
- {
- profile_flag = 1;
- }
- else if (!strcmp (str, "a"))
- {
-#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 (str, "ax"))
+ if (level > max_debug_level)
{
-#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
+ warning ("\
+ignoring option `%s' due to invalid debug level specification",
+ arg - 2);
+ level = debug_info_level;
}
- else if (str[0] == 'g')
+
+ if (type == NO_DEBUG)
{
- unsigned level;
- /* A lot of code assumes write_symbols == NO_DEBUG if the
- debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
- of what debugging type has been selected). This records the
- selected type. It is an error to specify more than one
- debugging type. */
- static enum debug_info_type selected_debug_type = NO_DEBUG;
- /* Non-zero if debugging format has been explicitly set.
- -g and -ggdb don't explicitly set the debugging format so
- -gdwarf -g3 is equivalent to -gdwarf3. */
- static int type_explicitly_set_p = 0;
- /* Indexed by enum debug_info_type. */
- static const char *debug_type_names[] =
- {
- "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
- };
-
- /* The maximum admissible debug level value. */
- static const unsigned max_debug_level = 3;
-
- /* Look up STR in the table. */
- for (da = debug_args; da->arg; da++)
- {
- const int da_len = strlen (da->arg);
+ type = PREFERRED_DEBUGGING_TYPE;
- if (! strncmp (str, da->arg, da_len))
- {
- enum debug_info_type type = da->debug_type;
- const char *p = str + da_len;
-
- if (*p && (*p < '0' || *p > '9'))
- continue;
-
- /* A debug flag without a level defaults to level 2.
- Note we do not want to call read_integral_parameter
- for that case since it will call atoi which
- will return zero.
-
- ??? We may want to generalize the interface to
- read_integral_parameter to better handle this case
- if this case shows up often. */
- if (*p)
- level = read_integral_parameter (p, 0,
- max_debug_level + 1);
- else
- level = 2;
-
- if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
- {
- error ("use -gdwarf -g%d for DWARF v1, level %d",
- level, level);
- if (level == 2)
- error ("use -gdwarf-2 for DWARF v2");
- }
-
- if (level > max_debug_level)
- {
- warning ("ignoring option `%s' due to invalid debug level specification",
- str - 1);
- level = debug_info_level;
- }
-
- if (type == NO_DEBUG)
- {
- type = PREFERRED_DEBUGGING_TYPE;
- if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
- {
+ if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
+ {
#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
- type = DWARF2_DEBUG;
+ type = DWARF2_DEBUG;
#else
#ifdef DBX_DEBUGGING_INFO
- type = DBX_DEBUG;
+ type = DBX_DEBUG;
#endif
#endif
- }
- }
-
- if (type == NO_DEBUG)
- warning ("`-%s' not supported by this configuration of GCC",
- str);
-
- /* Does it conflict with an already selected type? */
- if (type_explicitly_set_p
- /* -g/-ggdb don't conflict with anything */
- && da->debug_type != NO_DEBUG
- && type != selected_debug_type)
- warning ("`-%s' ignored, conflicts with `-g%s'",
- str, debug_type_names[(int) selected_debug_type]);
- else
- {
- /* If the format has already been set, -g/-ggdb
- only change the debug level. */
- if (type_explicitly_set_p
- && da->debug_type == NO_DEBUG)
- ; /* don't change debugging type */
- else
- {
- selected_debug_type = type;
- type_explicitly_set_p = da->debug_type != NO_DEBUG;
- }
- write_symbols = (level == 0
- ? NO_DEBUG
- : selected_debug_type);
- use_gnu_debug_info_extensions = da->use_extensions_p;
- debug_info_level = (enum debug_info_level) level;
- }
- break;
- }
}
- if (! da->arg)
- warning ("`-%s' not supported by this configuration of GCC",
- str);
}
- else if (!strcmp (str, "o"))
- {
- asm_file_name = argv[++i];
- }
- else if (str[0] == 'G')
+
+ if (type == NO_DEBUG)
+ warning ("`%s': unknown or unsupported -g option", arg - 2);
+
+ /* Does it conflict with an already selected type? */
+ if (type_explicitly_set_p
+ /* -g/-ggdb don't conflict with anything. */
+ && da->debug_type != NO_DEBUG
+ && type != selected_debug_type)
+ warning ("`%s' ignored, conflicts with `-g%s'",
+ arg - 2, debug_type_names[(int) selected_debug_type]);
+ else
{
- const int g_switch_val = (str[1] != '\0') ?
- read_integral_parameter(str + 1, 0, -1) :
- read_integral_parameter(argv[++i], 0, -1);
-
- if (g_switch_val != -1)
- {
- g_switch_set = TRUE;
- g_switch_value = g_switch_val;
- }
+ /* If the format has already been set, -g/-ggdb
+ only change the debug level. */
+ if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
+ /* Don't change debugging type. */
+ ;
else
- {
- error("Invalid option `-%s'",str);
+ {
+ selected_debug_type = type;
+ type_explicitly_set_p = da->debug_type != NO_DEBUG;
}
+
+ write_symbols = (level == 0
+ ? NO_DEBUG
+ : selected_debug_type);
+ use_gnu_debug_info_extensions = da->use_extensions_p;
+ debug_info_level = (enum debug_info_level) level;
}
- else if (!strncmp (str, "aux-info", 8))
- {
- flag_gen_aux_info = 1;
- aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
- }
- else if (!strcmp (str, "-help"))
- {
- display_help ();
- exit (0);
- }
- else
- error ("Invalid option `%s'", argv[i]);
+
+ break;
}
- else if (argv[i][0] == '+')
- error ("Invalid option `%s'", argv[i]);
- else
- filename = argv[i];
}
- /* Checker uses the frame pointer. */
- if (flag_check_memory_usage)
- flag_omit_frame_pointer = 0;
+ if (! da->arg)
+ return 0;
- if (optimize == 0)
+ return 1;
+}
+
+/* Decode the first argument in the argv as a language-independent option.
+ Return the number of strings consumed. */
+
+static unsigned int
+independent_decode_option (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *arg = argv[0];
+
+ if (arg[0] != '-' || arg[1] == 0)
{
- /* Inlining does not work if not optimizing,
- so force it not to be done. */
- flag_no_inline = 1;
- warn_inline = 0;
+ if (arg[0] == '+')
+ return 0;
- /* The c_decode_option and lang_decode_option functions set
- this to `2' if -Wall is used, so we can avoid giving out
- lots of errors for people who don't realize what -Wall does. */
- if (warn_uninitialized == 1)
- warning ("-Wuninitialized is not supported without -O");
+ filename = arg;
+
+ return 1;
}
-#ifdef OVERRIDE_OPTIONS
- /* Some machines may reject certain combinations of options. */
- OVERRIDE_OPTIONS;
-#endif
+ arg++;
- if (exceptions_via_longjmp == 2)
+ if (!strcmp (arg, "-help"))
{
-#ifdef DWARF2_UNWIND_INFO
- exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
-#else
- exceptions_via_longjmp = 1;
-#endif
+ display_help ();
+ exit_after_options = 1;
}
- if (profile_block_flag == 3)
+ if (!strcmp (arg, "-target-help"))
{
- warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
- profile_block_flag = 2;
+ display_target_options ();
+ exit_after_options = 1;
}
- /* Unrolling all loops implies that standard loop unrolling must also
- be done. */
- if (flag_unroll_all_loops)
- flag_unroll_loops = 1;
- /* Loop unrolling requires that strength_reduction be on also. Silently
- turn on strength reduction here if it isn't already on. Also, the loop
- unrolling code assumes that cse will be run after loop, so that must
- be turned on also. */
- if (flag_unroll_loops)
+ if (!strcmp (arg, "-version"))
{
- flag_strength_reduce = 1;
- flag_rerun_cse_after_loop = 1;
+ print_version (stderr, "");
+ exit_after_options = 1;
}
- /* Warn about options that are not supported on this machine. */
-#ifndef INSN_SCHEDULING
- if (flag_schedule_insns || flag_schedule_insns_after_reload)
- warning ("instruction scheduling not supported on this target machine");
-#endif
-#ifndef DELAY_SLOTS
- if (flag_delayed_branch)
- warning ("this target machine does not have delayed branches");
-#endif
-
- user_label_prefix = USER_LABEL_PREFIX;
- if (flag_leading_underscore != -1)
+ /* Handle '--param <name>=<value>'. */
+ if (strcmp (arg, "-param") == 0)
{
- /* If the default prefix is more complicated than "" or "_",
- issue a warning and ignore this option. */
- if (user_label_prefix[0] == 0 ||
- (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
+ char *equal;
+
+ if (argc == 1)
{
- user_label_prefix = flag_leading_underscore ? "_" : "";
+ error ("-param option missing argument");
+ return 1;
}
+
+ /* Get the '<name>=<value>' parameter. */
+ arg = argv[1];
+ /* Look for the `='. */
+ equal = strchr (arg, '=');
+ if (!equal)
+ error ("invalid --param option: %s", arg);
else
- warning ("-f%sleading-underscore not supported on this target machine",
- flag_leading_underscore ? "" : "no-");
- }
+ {
+ int val;
+
+ /* Zero out the `=' sign so that we get two separate strings. */
+ *equal = '\0';
+ /* Figure out what value is specified. */
+ val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL);
+ if (val != INVALID_PARAM_VAL)
+ set_param_value (arg, val);
+ else
+ error ("invalid parameter value `%s'", equal + 1);
+ }
- /* If we are in verbose mode, write out the version and maybe all the
- option flags in use. */
- if (version_flag)
- {
- print_version (stderr, "");
- if (! quiet_flag)
- print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
+ return 2;
}
- compile_file (filename);
+ if (*arg == 'Y')
+ arg++;
-#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
- if (flag_print_mem)
+ switch (*arg)
{
- char *lim = (char *) sbrk (0);
+ default:
+ return 0;
+
+ case 'O':
+ /* Already been treated in main (). Do nothing. */
+ break;
- notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
- fflush (stderr);
+ case 'm':
+ set_target_switch (arg + 1);
+ break;
-#ifndef __MSDOS__
-#ifdef USG
- system ("ps -l 1>&2");
-#else /* not USG */
- system ("ps v");
-#endif /* not USG */
-#endif
+ case 'f':
+ return decode_f_option (arg + 1);
+
+ case 'g':
+ return decode_g_option (arg + 1);
+
+ case 'd':
+ if (!strcmp (arg, "dumpbase"))
+ {
+ if (argc == 1)
+ return 0;
+
+ dump_base_name = argv[1];
+ return 2;
+ }
+ else
+ decode_d_option (arg + 1);
+ break;
+
+ case 'p':
+ if (!strcmp (arg, "pedantic"))
+ pedantic = 1;
+ else if (!strcmp (arg, "pedantic-errors"))
+ flag_pedantic_errors = pedantic = 1;
+ else if (arg[1] == 0)
+ profile_flag = 1;
+ else
+ return 0;
+ break;
+
+ case 'q':
+ if (!strcmp (arg, "quiet"))
+ quiet_flag = 1;
+ else
+ return 0;
+ break;
+
+ case 'v':
+ if (!strcmp (arg, "version"))
+ version_flag = 1;
+ else
+ return 0;
+ break;
+
+ case 'w':
+ if (arg[1] == 0)
+ inhibit_warnings = 1;
+ else
+ return 0;
+ break;
+
+ case 'W':
+ if (arg[1] == 0)
+ {
+ extra_warnings = 1;
+ /* We save the value of warn_uninitialized, since if they put
+ -Wuninitialized on the command line, we need to generate a
+ warning about not using it without also specifying -O. */
+ if (warn_uninitialized != 1)
+ warn_uninitialized = 2;
+ }
+ else
+ return decode_W_option (arg + 1);
+ break;
+
+ case 'a':
+ if (!strncmp (arg, "aux-info", 8))
+ {
+ if (arg[8] == '\0')
+ {
+ if (argc == 1)
+ return 0;
+
+ aux_info_file_name = argv[1];
+ flag_gen_aux_info = 1;
+ return 2;
+ }
+ else if (arg[8] == '=')
+ {
+ aux_info_file_name = arg + 9;
+ flag_gen_aux_info = 1;
+ }
+ else
+ return 0;
+ }
+ else
+ return 0;
+ break;
+
+ case 'o':
+ if (arg[1] == 0)
+ {
+ if (argc == 1)
+ return 0;
+
+ asm_file_name = argv[1];
+ return 2;
+ }
+ return 0;
+
+ case 'G':
+ {
+ int g_switch_val;
+ int return_val;
+
+ if (arg[1] == 0)
+ {
+ if (argc == 1)
+ return 0;
+
+ g_switch_val = read_integral_parameter (argv[1], 0, -1);
+ return_val = 2;
+ }
+ else
+ {
+ g_switch_val = read_integral_parameter (arg + 1, 0, -1);
+ return_val = 1;
+ }
+
+ if (g_switch_val == -1)
+ return_val = 0;
+ else
+ {
+ g_switch_set = TRUE;
+ g_switch_value = g_switch_val;
+ }
+
+ return return_val;
+ }
}
-#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX */
-
- if (errorcount)
- exit (FATAL_EXIT_CODE);
- if (sorrycount)
- exit (FATAL_EXIT_CODE);
- exit (SUCCESS_EXIT_CODE);
- return 0;
+
+ return 1;
}
/* Decode -m switches. */
@@ -5505,12 +4338,12 @@ main (argc, argv)
static void
set_target_switch (name)
- const char *name;
+ const char *name;
{
- register size_t j;
+ size_t j;
int valid_target_option = 0;
- for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
+ for (j = 0; j < ARRAY_SIZE (target_switches); j++)
if (!strcmp (target_switches[j].name, name))
{
if (target_switches[j].value < 0)
@@ -5522,7 +4355,7 @@ set_target_switch (name)
#ifdef TARGET_OPTIONS
if (!valid_target_option)
- for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
+ for (j = 0; j < ARRAY_SIZE (target_options); j++)
{
int len = strlen (target_options[j].prefix);
if (!strncmp (target_options[j].prefix, name, len))
@@ -5534,7 +4367,7 @@ set_target_switch (name)
#endif
if (!valid_target_option)
- error ("Invalid option `%s'", name);
+ error ("invalid option `%s'", name);
}
/* Print version information to FILE.
@@ -5551,12 +4384,13 @@ print_version (file, indent)
#endif
fnotice (file,
#ifdef __GNUC__
- "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
+ "%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 ? " " : "",
- language_string, version_string, TARGET_NAME, __VERSION__);
+ lang_hooks.name, version_string, TARGET_NAME,
+ indent, __VERSION__);
}
/* Print an option value and return the adjusted position in the line.
@@ -5588,7 +4422,7 @@ print_single_switch (file, pos, max, indent, sep, term, 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.
@@ -5637,14 +4471,14 @@ print_switch_values (file, pos, max, indent, sep, term)
pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
_("options enabled: "), "");
- for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
+ 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 < sizeof target_switches / sizeof target_switches[0]; j++)
+ 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)
@@ -5655,7 +4489,7 @@ print_switch_values (file, pos, max, indent, sep, term)
}
#ifdef TARGET_OPTIONS
- for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
+ for (j = 0; j < ARRAY_SIZE (target_options); j++)
if (*target_options[j].variable != NULL)
{
char prefix[256];
@@ -5667,98 +4501,743 @@ print_switch_values (file, pos, max, indent, sep, term)
fprintf (file, "%s", term);
}
+
+/* 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);
+ }
-/* Record the beginning of a new source file, named FILENAME. */
+#ifdef IO_BUFFER_SIZE
+ setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+ _IOFBF, IO_BUFFER_SIZE);
+#endif
-void
-debug_start_source_file (filename)
- register char *filename ATTRIBUTE_UNUSED;
+ 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
+ }
+}
+
+/* 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;
{
-#ifdef DBX_DEBUGGING_INFO
- if (write_symbols == DBX_DEBUG)
- dbxout_start_new_source_file (filename);
+ char *p;
+
+ p = argv0 + strlen (argv0);
+ while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
+ --p;
+ progname = p;
+
+ xmalloc_set_program_name (progname);
+
+ gcc_init_libintl ();
+
+ /* Install handler for SIGFPE, which may be received while we do
+ compile-time floating point arithmetic. */
+ signal (SIGFPE, float_signal);
+
+ /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
+#ifdef SIGSEGV
+ signal (SIGSEGV, crash_signal);
#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_start_new_source_file (filename);
-#endif /* DWARF_DEBUGGING_INFO */
-#ifdef DWARF2_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF2_DEBUG)
- dwarf2out_start_source_file (filename);
-#endif /* DWARF2_DEBUGGING_INFO */
-#ifdef SDB_DEBUGGING_INFO
- if (write_symbols == SDB_DEBUG)
- sdbout_start_new_source_file (filename);
+#ifdef SIGILL
+ signal (SIGILL, crash_signal);
#endif
+#ifdef SIGBUS
+ signal (SIGBUS, crash_signal);
+#endif
+#ifdef SIGABRT
+ signal (SIGABRT, crash_signal);
+#endif
+#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
+ signal (SIGIOT, crash_signal);
+#endif
+
+ /* Initialize the diagnostics reporting machinery, so option parsing
+ can give warnings and errors. */
+ diagnostic_initialize (global_dc);
}
+
+/* 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;
-/* Record the resumption of a source file. LINENO is the line number in
- the source file we are returning to. */
+ /* Save in case md file wants to emit args as a comment. */
+ save_argc = argc;
+ save_argv = argv;
-void
-debug_end_source_file (lineno)
- register unsigned lineno ATTRIBUTE_UNUSED;
+ /* 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 initialization. */
+ (*lang_hooks.init_options) ();
+
+ /* Scan to see what optimization level has been specified. That will
+ determine the default value of many flags. */
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp (argv[i], "-O"))
+ {
+ optimize = 1;
+ optimize_size = 0;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'O')
+ {
+ /* Handle -Os, -O2, -O3, -O69, ... */
+ char *p = &argv[i][2];
+
+ if ((p[0] == 's') && (p[1] == 0))
+ {
+ optimize_size = 1;
+
+ /* Optimizing for size forces optimize to be 2. */
+ optimize = 2;
+ }
+ else
+ {
+ const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ if (optimize_val != -1)
+ {
+ optimize = optimize_val;
+
+#ifdef FORCE_OPTIMIZATION_DOWNGRADE
+#warning FORCE_OPTIMIZATION_DOWNGRADE
+ if (optimize > FORCE_OPTIMIZATION_DOWNGRADE)
+ {
+ optimize = FORCE_OPTIMIZATION_DOWNGRADE;
+ warning ("\n***\n***\t-O%d converted to \"-O%d\" due to optimizer bugs on this platform\n***\n",
+ optimize_val,
+ FORCE_OPTIMIZATION_DOWNGRADE);
+
+ }
+#endif /*FORCE_OPTIMIZATION_DOWNGRADE*/
+
+#if defined(__alpha__)
+ if (optimize > 1)
+ {
+ warning ("\n***\n***\tThe -O%d flag TRIGGERS KNOWN OPTIMIZER BUGS ON THIS PLATFORM\n***\n",
+ optimize_val);
+ }
+#endif /*__alpha__*/
+
+ optimize_size = 0;
+ }
+ }
+ }
+ }
+
+ if (!optimize)
+ {
+ flag_merge_constants = 0;
+ }
+
+ if (optimize >= 1)
+ {
+ flag_defer_pop = 1;
+ flag_thread_jumps = 1;
+#ifdef DELAY_SLOTS
+ flag_delayed_branch = 1;
+#endif
+#ifdef CAN_DEBUG_WITHOUT_FP
+ flag_omit_frame_pointer = 1;
+#endif
+ flag_guess_branch_prob = 1;
+ flag_cprop_registers = 1;
+ }
+
+ if (optimize >= 2)
+ {
+ flag_optimize_sibling_calls = 1;
+ flag_cse_follow_jumps = 1;
+ flag_cse_skip_blocks = 1;
+ flag_gcse = 1;
+ flag_expensive_optimizations = 1;
+ flag_strength_reduce = 1;
+ flag_rerun_cse_after_loop = 1;
+ flag_rerun_loop_opt = 1;
+ flag_caller_saves = 1;
+ flag_force_mem = 1;
+ flag_peephole2 = 1;
+#ifdef INSN_SCHEDULING
+ flag_schedule_insns = 1;
+ flag_schedule_insns_after_reload = 1;
+#endif
+ flag_regmove = 1;
+ flag_strict_aliasing = 1;
+ flag_delete_null_pointer_checks = 1;
+ flag_reorder_blocks = 1;
+ }
+
+ if (optimize >= 3)
+ {
+ flag_inline_functions = 1;
+ flag_rename_registers = 1;
+ }
+
+ if (optimize < 2 || optimize_size)
+ {
+ align_loops = 1;
+ align_jumps = 1;
+ align_labels = 1;
+ 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;
+ set_target_switch ("");
+
+ /* Unwind tables are always present in an ABI-conformant IA-64
+ object file, so the default should be ON. */
+#ifdef IA64_UNWIND_INFO
+ flag_unwind_tables = IA64_UNWIND_INFO;
+#endif
+
+#ifdef OPTIMIZATION_OPTIONS
+ /* Allow default optimizations to be specified on a per-machine basis. */
+ OPTIMIZATION_OPTIONS (optimize, optimize_size);
+#endif
+
+ /* Perform normal command line switch decoding. */
+ for (i = 1; i < argc;)
+ {
+ int lang_processed;
+ int indep_processed;
+
+ /* Give the language a chance to decode the option for itself. */
+ lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i);
+
+ if (lang_processed >= 0)
+ /* Now see if the option also has a language independent meaning.
+ Some options are both language specific and language independent,
+ eg --help. */
+ indep_processed = independent_decode_option (argc - i, argv + i);
+ else
+ {
+ lang_processed = -lang_processed;
+ indep_processed = 0;
+ }
+
+ if (lang_processed || indep_processed)
+ i += MAX (lang_processed, indep_processed);
+ else
+ {
+ const char *option = NULL;
+ const char *lang = NULL;
+ unsigned int j;
+
+ /* It is possible that the command line switch is not valid for the
+ current language, but it is valid for another language. In order
+ to be compatible with previous versions of the compiler (which
+ did not issue an error message in this case) we check for this
+ possibility here. If we do find a match, then if extra_warnings
+ is set we generate a warning message, otherwise we will just
+ ignore the option. */
+ for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++)
+ {
+ option = documented_lang_options[j].option;
+
+ if (option == NULL)
+ lang = documented_lang_options[j].description;
+ else if (! strncmp (argv[i], option, strlen (option)))
+ break;
+ }
+
+ if (j != ARRAY_SIZE (documented_lang_options))
+ {
+ if (extra_warnings)
+ {
+ warning ("ignoring command line option '%s'", argv[i]);
+ if (lang)
+ warning
+ ("(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]);
+
+ i++;
+ }
+ }
+
+ /* 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,
+ so force it not to be done. */
+ flag_no_inline = 1;
+ warn_inline = 0;
+
+ /* The c_decode_option function and decode_option hook set
+ this to `2' if -Wall is used, so we can avoid giving out
+ lots of errors for people who don't realize what -Wall does. */
+ if (warn_uninitialized == 1)
+ warning ("-Wuninitialized is not supported without -O");
+ }
+
+ /* All command line options have been parsed; allow the front end to
+ perform consistency checks, etc. */
+ (*lang_hooks.post_options) ();
+}
+
+/* Process the options that have been parsed. */
+static void
+process_options ()
{
-#ifdef DBX_DEBUGGING_INFO
+#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);
+
+ /* Unrolling all loops implies that standard loop unrolling must also
+ be done. */
+ if (flag_unroll_all_loops)
+ flag_unroll_loops = 1;
+ /* Loop unrolling requires that strength_reduction be on also. Silently
+ turn on strength reduction here if it isn't already on. Also, the loop
+ unrolling code assumes that cse will be run after loop, so that must
+ be turned on also. */
+ if (flag_unroll_loops)
+ {
+ flag_strength_reduce = 1;
+ flag_rerun_cse_after_loop = 1;
+ }
+
+ if (flag_non_call_exceptions)
+ flag_asynchronous_unwind_tables = 1;
+ if (flag_asynchronous_unwind_tables)
+ flag_unwind_tables = 1;
+
+ /* Warn about options that are not supported on this machine. */
+#ifndef INSN_SCHEDULING
+ if (flag_schedule_insns || flag_schedule_insns_after_reload)
+ warning ("instruction scheduling not supported on this target machine");
+#endif
+#ifndef DELAY_SLOTS
+ if (flag_delayed_branch)
+ warning ("this target machine does not have delayed branches");
+#endif
+
+ /* Some operating systems do not allow profiling without a frame
+ pointer. */
+ if (!TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER
+ && profile_flag
+ && flag_omit_frame_pointer)
+ {
+ error ("profiling does not work without a frame pointer");
+ flag_omit_frame_pointer = 0;
+ }
+
+ user_label_prefix = USER_LABEL_PREFIX;
+ if (flag_leading_underscore != -1)
+ {
+ /* If the default prefix is more complicated than "" or "_",
+ issue a warning and ignore this option. */
+ if (user_label_prefix[0] == 0 ||
+ (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
+ {
+ user_label_prefix = flag_leading_underscore ? "_" : "";
+ }
+ else
+ warning ("-f%sleading-underscore not supported on this target machine",
+ flag_leading_underscore ? "" : "no-");
+ }
+
+ /* If we are in verbose mode, write out the version and maybe all the
+ option flags in use. */
+ if (version_flag)
+ {
+ print_version (stderr, "");
+ if (! quiet_flag)
+ print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
+ }
+
+ if (! quiet_flag)
+ time_report = 1;
+
+ 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)
- dbxout_resume_previous_source_file ();
+ debug_hooks = &dbx_debug_hooks;
+#endif
+#if defined(XCOFF_DEBUGGING_INFO)
+ if (write_symbols == XCOFF_DEBUG)
+ debug_hooks = &xcoff_debug_hooks;
#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_resume_previous_source_file (lineno);
-#endif /* DWARF_DEBUGGING_INFO */
-#ifdef DWARF2_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF2_DEBUG)
- dwarf2out_end_source_file ();
-#endif /* DWARF2_DEBUGGING_INFO */
#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
- sdbout_resume_previous_source_file ();
+ 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
}
+
+/* Language-independent initialization, before language-dependent
+ initialization. */
+static void
+lang_independent_init ()
+{
+ decl_printable_name = decl_name;
+ lang_expand_expr = (lang_expand_expr_t) do_abort;
-/* Called from check_newline in c-parse.y. The `buffer' parameter contains
- the tail part of the directive line, i.e. the part which is past the
- initial whitespace, #, whitespace, directive-name, whitespace part. */
+ /* 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));
-void
-debug_define (lineno, buffer)
- register unsigned lineno ATTRIBUTE_UNUSED;
- register char *buffer ATTRIBUTE_UNUSED;
+ /* Initialize the garbage-collector, and string pools. */
+ init_ggc ();
+ ggc_add_rtx_root (&stack_limit_rtx, 1);
+ ggc_add_tree_root (&current_function_decl, 1);
+ ggc_add_tree_root (&current_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 ();
+}
+
+/* Language-dependent initialization. Returns non-zero on success. */
+static int
+lang_dependent_init (name)
+ const char *name;
{
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_define (lineno, buffer);
-#endif /* DWARF_DEBUGGING_INFO */
-#ifdef DWARF2_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF2_DEBUG)
- dwarf2out_define (lineno, buffer);
-#endif /* DWARF2_DEBUGGING_INFO */
+ if (dump_base_name == 0)
+ dump_base_name = name ? name : "gccdump";
+
+ /* 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;
+
+ /* 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
+
+ /* Now we have the correct original filename, we can initialize
+ debug output. */
+ (*debug_hooks->init) (name);
+
+ timevar_pop (TV_SYMOUT);
+
+ return 1;
}
+
+/* Clean up: close opened files, etc. */
+
+static void
+finalize ()
+{
+ /* Close the dump files. */
+ if (flag_gen_aux_info)
+ {
+ fclose (aux_info_file);
+ if (errorcount)
+ unlink (aux_info_file_name);
+ }
-/* Called from check_newline in c-parse.y. The `buffer' parameter contains
- the tail part of the directive line, i.e. the part which is past the
- initial whitespace, #, whitespace, directive-name, whitespace part. */
+ /* 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. */
-void
-debug_undef (lineno, buffer)
- register unsigned lineno ATTRIBUTE_UNUSED;
- register char *buffer ATTRIBUTE_UNUSED;
+ 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);
+ }
+
+ /* 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, DUMPFILE_FORMAT, 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 ();
+
+ /* Language-specific end of compilation actions. */
+ (*lang_hooks.finish) ();
+}
+
+/* Initialize the compiler, and compile the input file. */
+static void
+do_compile ()
{
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_undef (lineno, buffer);
-#endif /* DWARF_DEBUGGING_INFO */
-#ifdef DWARF2_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF2_DEBUG)
- dwarf2out_undef (lineno, buffer);
-#endif /* DWARF2_DEBUGGING_INFO */
+ /* The bulk of command line switch processing. */
+ process_options ();
+
+ /* We cannot start timing until after options are processed since that
+ says if we run timers or not. */
+ init_timevar ();
+ timevar_start (TV_TOTAL);
+
+ /* Language-independent initialization. Also sets up GC, identifier
+ hashes etc. */
+ lang_independent_init ();
+
+ /* Language-dependent initialization. Returns true on success. */
+ if (lang_dependent_init (filename))
+ compile_file ();
+
+ finalize ();
+
+ /* Stop timing and print the times. */
+ timevar_stop (TV_TOTAL);
+ timevar_print (stderr);
+}
+
+/* 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. */
+
+int
+toplev_main (argc, argv)
+ int argc;
+ char **argv;
+{
+ hex_init ();
+
+ /* 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);
+
+ /* Exit early if we can (e.g. -help). */
+ if (!exit_after_options)
+ do_compile ();
+
+ if (errorcount || sorrycount)
+ return (FATAL_EXIT_CODE);
+
+ return (SUCCESS_EXIT_CODE);
}
OpenPOWER on IntegriCloud