X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftoplev.c;h=4f13543a88081bb4ca66f52d39021ab59ad5e338;hb=b0d8e49cb34af0a14e5e21c23a7933d482c5d3ec;hp=273db7793ad856ab4ae86f714a96a69bc983bb9e;hpb=f8142eb13e4ced4b972ed9e3d493cbad00a69b64;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/toplev.c b/gcc/toplev.c index 273db7793ad..4f13543a880 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1,6 +1,7 @@ + /* Top level of GNU C compiler Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GCC. @@ -29,7 +30,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #undef FFS /* Some systems define this in param.h. */ #include "system.h" #include -#include #ifdef HAVE_SYS_RESOURCE_H # include @@ -70,6 +70,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "debug.h" #include "target.h" #include "langhooks.h" +#include "cfglayout.h" #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) #include "dwarf2out.h" @@ -87,38 +88,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #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; -{ - /* The in the gcc-vms-1.42 distribution prototypes fopen with two - fixed arguments, which matches ANSI's specification but not VAXCRTL's - pre-ANSI implementation. This hack circumvents the mismatch problem. */ - FILE *(*vmslib_fopen)() = (FILE *(*)()) fopen; - - if (*type == 'w') - return (*vmslib_fopen) (fname, type, "mbc=32", - "deq=64", "fop=tef", "shr=nil"); - else - return (*vmslib_fopen) (fname, type, "mbc=32"); -} - -#define fopen vms_fopen -#endif /* VMS */ - -#if defined (HAVE_DECL_ENVIRON) && !HAVE_DECL_ENVIRON -extern char **environ; -#endif - /* Carry information from ASM_DECLARE_OBJECT_NAME to ASM_FINISH_DECLARE_OBJECT. */ @@ -135,11 +105,8 @@ 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)); @@ -157,6 +124,9 @@ static int print_single_switch PARAMS ((FILE *, int, int, const char *, static void print_switch_values PARAMS ((FILE *, int, int, const char *, const char *, const char *)); +/* Nonzero to dump debug info whilst parsing (-dy option). */ +static int set_yydebug; + /* Length of line when printing switch values. */ #define MAX_LINE 75 @@ -210,7 +180,7 @@ extern int target_flags; /* Debug hooks - dependent upon command line options. */ -struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; +const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks; /* Describes a dump file. */ @@ -244,13 +214,15 @@ enum dump_file_index DFI_ssa_ccp, DFI_ssa_dce, DFI_ussa, + DFI_null, DFI_cse, DFI_addressof, DFI_gcse, DFI_loop, - DFI_cse2, DFI_cfg, DFI_bp, + DFI_tracer, + DFI_cse2, DFI_life, DFI_combine, DFI_ce, @@ -276,7 +248,7 @@ enum dump_file_index Remaining -d letters: - " o q u " + " o q " " H JK OPQ TUV YZ" */ @@ -290,13 +262,15 @@ static struct dump_file_info dump_file[DFI_MAX] = { "ssaccp", 'W', 1, 0, 0 }, { "ssadce", 'X', 1, 0, 0 }, { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */ + { "null", 'u', 0, 0, 0 }, { "cse", 's', 0, 0, 0 }, { "addressof", 'F', 0, 0, 0 }, { "gcse", 'G', 1, 0, 0 }, { "loop", 'L', 1, 0, 0 }, - { "cse2", 't', 1, 0, 0 }, { "cfg", 'f', 1, 0, 0 }, { "bp", 'b', 1, 0, 0 }, + { "tracer", 'T', 1, 0, 0 }, + { "cse2", 't', 1, 0, 0 }, { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ { "combine", 'c', 1, 0, 0 }, { "ce", 'C', 1, 0, 0 }, @@ -378,29 +352,6 @@ tree current_function_decl; 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. - VERBOSITY determines what information will be printed: - 0: DECL_NAME, demangled as necessary. - 1: and scope information. - 2: and any other information that might be interesting, such as function - parameter types in C++. */ - -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) - PARAMS ((union tree_node *, rtx, enum machine_mode, - enum expand_modifier modifier)); - -lang_expand_expr_t lang_expand_expr = 0; - -/* Pointer to function to finish handling an incomplete decl at the - end of compilation. */ - -void (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0; - /* Nonzero if doing dwarf2 duplicate elimination. */ int flag_eliminate_dwarf2_dups = 0; @@ -413,6 +364,11 @@ int profile_flag = 0; int profile_arc_flag = 0; +/* Nonzero if we should not attempt to generate thread-safe + code to profile program flow graph arcs. */ + +int flag_unsafe_profile_arcs = 0; + /* Nonzero if generating info for gcov to calculate line test coverage. */ int flag_test_coverage = 0; @@ -425,6 +381,10 @@ int flag_branch_probabilities = 0; int flag_reorder_blocks = 0; +/* Nonzero if functions should be reordered. */ + +int flag_reorder_functions = 0; + /* Nonzero if registers should be renamed. */ int flag_rename_registers = 0; @@ -641,6 +601,22 @@ int flag_syntax_only = 0; static int flag_gcse; +/* Nonzero means perform loop optimizer. */ + +static int flag_loop_optimize; + +/* Nonzero means perform crossjumping. */ + +static int flag_crossjumping; + +/* Nonzero means perform if conversion. */ + +static int flag_if_conversion; + +/* Nonzero means perform if conversion after reload. */ + +static int flag_if_conversion2; + /* Nonzero means to use global dataflow analysis to eliminate useless null pointer tests. */ @@ -680,7 +656,12 @@ int flag_keep_inline_functions; /* Nonzero means that functions will not be inlined. */ -int flag_no_inline; +int flag_no_inline = 2; + +/* Nonzero means that we don't want inlining by virtue of -fno-inline, + not just because the tree inliner turned us off. */ + +int flag_really_no_inline = 2; /* Nonzero means that we should emit static const variables regardless of whether or not optimization is turned on. */ @@ -704,12 +685,15 @@ int flag_shared_data; int flag_delayed_branch; /* Nonzero if we are compiling pure (sharable) code. - Value is 1 if we are doing reasonable (i.e. simple - offset into offset table) pic. Value is 2 if we can - only perform register offsets. */ + Value is 1 if we are doing "small" pic; value is 2 if we're doing + "large" pic. */ int flag_pic; +/* Set to the default thread-local storage (tls) model to use. */ + +enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; + /* Nonzero means generate extra code for exception handling and enable exception handling. */ @@ -728,12 +712,6 @@ int flag_asynchronous_unwind_tables = 0; int flag_no_common; -/* Nonzero means pretend it is OK to examine bits of target floats, - even if that isn't true. The resulting code will have incorrect constants, - but the same series of instructions that the native compiler would make. */ - -int flag_pretend_float; - /* Nonzero means change certain warnings into errors. Usually these are warnings about failure to conform to some standard. */ @@ -805,6 +783,9 @@ int flag_gnu_linker = 0; int flag_gnu_linker = 1; #endif +/* Nonzero means put zero initialized data in the bss section. */ +int flag_zero_initialized_in_bss = 1; + /* Enable SSA. */ int flag_ssa = 0; @@ -884,6 +865,10 @@ int flag_merge_constants = 1; one, unconditionally renumber instruction UIDs. */ int flag_renumber_insns = 1; +/* Nonzero if we perform superblock formation. */ + +int flag_tracer = 0; + /* 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 @@ -935,6 +920,9 @@ debug_args[] = #ifdef SDB_DEBUGGING_INFO { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") }, #endif +#ifdef VMS_DEBUGGING_INFO + { "vms", VMS_DEBUG, 0, N_("Generate VMS format debug info") }, +#endif { 0, 0, 0, 0 } }; @@ -992,6 +980,8 @@ static const lang_independent_options f_options[] = N_("When possible do not generate stack frames") }, {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1, N_("Optimize sibling and tail recursive calls") }, + {"tracer", &flag_tracer, 1, + N_("Perform superblock formation via tail duplication") }, {"cse-follow-jumps", &flag_cse_follow_jumps, 1, N_("When running CSE, follow jumps to their targets") }, {"cse-skip-blocks", &flag_cse_skip_blocks, 1, @@ -1048,14 +1038,20 @@ static const lang_independent_options f_options[] = N_("Perform enhanced load motion during global subexpression elimination") }, {"gcse-sm", &flag_gcse_sm, 1, N_("Perform store motion after global subexpression elimination") }, + {"loop-optimize", &flag_loop_optimize, 1, + N_("Perform the loop optimizations") }, + {"crossjumping", &flag_crossjumping, 1, + N_("Perform cross-jumping optimization") }, + {"if-conversion", &flag_if_conversion, 1, + N_("Perform conversion of conditional jumps to branchless equivalents") }, + {"if-conversion2", &flag_if_conversion2, 1, + N_("Perform conversion of conditional jumps to conditional execution") }, {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1, N_("Run CSE pass after loop optimizations") }, {"rerun-loop-opt", &flag_rerun_loop_opt, 1, N_("Run the loop optimizer twice") }, {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1, N_("Delete useless null pointer checks") }, - {"pretend-float", &flag_pretend_float, 1, - N_("Pretend that host and target use the same FP format") }, {"schedule-insns", &flag_schedule_insns, 1, N_("Reschedule instructions before register allocation") }, {"schedule-insns2", &flag_schedule_insns_after_reload, 1, @@ -1083,12 +1079,18 @@ static const lang_independent_options f_options[] = N_("Support synchronous non-call exceptions") }, {"profile-arcs", &profile_arc_flag, 1, N_("Insert arc based program profiling code") }, + {"unsafe-profile-arcs", &flag_unsafe_profile_arcs, 1, + N_("Avoid thread safety profiling overhead") }, {"test-coverage", &flag_test_coverage, 1, N_("Create data files needed by gcov") }, {"branch-probabilities", &flag_branch_probabilities, 1, N_("Use profiling information for branch probabilities") }, + {"profile", &profile_flag, 1, + N_("Enable basic program profiling code") }, {"reorder-blocks", &flag_reorder_blocks, 1, N_("Reorder basic blocks to improve code placement") }, + {"reorder-functions", &flag_reorder_functions, 1, + N_("Reorder functions to improve code placement") }, {"rename-registers", &flag_rename_registers, 1, N_("Do the register renaming optimization pass") }, {"cprop-registers", &flag_cprop_registers, 1, @@ -1137,6 +1139,8 @@ static const lang_independent_options f_options[] = N_("Suppress output of instruction numbers and line number notes in debugging dumps") }, {"instrument-functions", &flag_instrument_function_entry_exit, 1, N_("Instrument function entry/exit with profiling calls") }, + {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1, + N_("Put zero initialized data in the bss section") }, {"ssa", &flag_ssa, 1, N_("Enable SSA optimizations") }, {"ssa-ccp", &flag_ssa_ccp, 1, @@ -1184,11 +1188,9 @@ documented_lang_options[] = used here is to only describe those options which are not enabled by default. */ - { "-ansi", + { "-ansi", N_("Compile just for ISO C89") }, - { "-fallow-single-precision", - N_("Do not promote floats to double if using -traditional") }, - { "-std= ", + { "-std= ", N_("Determine language standard") }, { "-fsigned-bitfields", "" }, @@ -1196,104 +1198,103 @@ documented_lang_options[] = N_("Make bit-fields by unsigned by default") }, { "-fno-signed-bitfields", "" }, { "-fno-unsigned-bitfields","" }, - { "-fsigned-char", + { "-fsigned-char", N_("Make 'char' be signed by default") }, - { "-funsigned-char", + { "-funsigned-char", N_("Make 'char' be unsigned by default") }, { "-fno-signed-char", "" }, { "-fno-unsigned-char", "" }, - { "-ftraditional", "" }, - { "-traditional", - N_("Attempt to support traditional K&R style C") }, - { "-fnotraditional", "" }, - { "-fno-traditional", "" }, - { "-fasm", "" }, - { "-fno-asm", + { "-fno-asm", N_("Do not recognize the 'asm' keyword") }, { "-fbuiltin", "" }, - { "-fno-builtin", + { "-fno-builtin", N_("Do not recognize any built in functions") }, - { "-fhosted", + { "-fhosted", N_("Assume normal C execution environment") }, { "-fno-hosted", "" }, { "-ffreestanding", N_("Assume that standard libraries & main might not exist") }, { "-fno-freestanding", "" }, - { "-fcond-mismatch", + { "-fcond-mismatch", N_("Allow different types as args of ? operator") }, { "-fno-cond-mismatch", "" }, - { "-fdollars-in-identifiers", + { "-fdollars-in-identifiers", N_("Allow the use of $ inside identifiers") }, { "-fno-dollars-in-identifiers", "" }, { "-fpreprocessed", "" }, { "-fno-preprocessed", "" }, - { "-fshort-double", + { "-fshort-double", N_("Use the same size for double as for float") }, { "-fno-short-double", "" }, - { "-fshort-enums", + { "-fshort-enums", N_("Use the smallest fitting integer to hold enums") }, { "-fno-short-enums", "" }, - { "-fshort-wchar", + { "-fshort-wchar", N_("Override the underlying type for wchar_t to `unsigned short'") }, { "-fno-short-wchar", "" }, - { "-Wall", + { "-Wall", N_("Enable most warning messages") }, { "-Wbad-function-cast", N_("Warn about casting functions to incompatible types") }, { "-Wno-bad-function-cast", "" }, - { "-Wno-missing-noreturn", "" }, { "-Wmissing-format-attribute", N_("Warn about functions which might be candidates for format attributes") }, { "-Wno-missing-format-attribute", "" }, - { "-Wcast-qual", + { "-Wcast-qual", N_("Warn about casts which discard qualifiers") }, { "-Wno-cast-qual", "" }, - { "-Wchar-subscripts", + { "-Wchar-subscripts", N_("Warn about subscripts whose type is 'char'") }, { "-Wno-char-subscripts", "" }, - { "-Wcomment", + { "-Wcomment", N_("Warn if nested comments are detected") }, { "-Wno-comment", "" }, - { "-Wcomments", + { "-Wcomments", N_("Warn if nested comments are detected") }, { "-Wno-comments", "" }, - { "-Wconversion", + { "-Wconversion", N_("Warn about possibly confusing type conversions") }, { "-Wno-conversion", "" }, - { "-Wformat", + { "-Wdiv-by-zero", "" }, + { "-Wno-div-by-zero", + N_("Do not warn about compile-time integer division by zero") }, + { "-Wfloat-equal", + N_("Warn about testing equality of floating point numbers") }, + { "-Wno-float-equal", "" }, + { "-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", + { "-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", "" }, + { "-Wformat-y2k", "" }, + { "-Wno-format-y2k", + N_("Don't warn about strftime formats yielding 2 digit years") }, { "-Wimplicit-function-declaration", N_("Warn about implicit function declarations") }, { "-Wno-implicit-function-declaration", "" }, { "-Werror-implicit-function-declaration", "" }, - { "-Wimplicit-int", + { "-Wimplicit-int", N_("Warn when a declaration does not specify a type") }, { "-Wno-implicit-int", "" }, { "-Wimplicit", "" }, { "-Wno-implicit", "" }, - { "-Wimport", + { "-Wimport", N_("Warn about the use of the #import directive") }, { "-Wno-import", "" }, { "-Wlong-long","" }, - { "-Wno-long-long", + { "-Wno-long-long", N_("Do not warn about using 'long long' when -pedantic") }, - { "-Wmain", + { "-Wmain", N_("Warn about suspicious declarations of main") }, { "-Wno-main", "" }, { "-Wmissing-braces", @@ -1302,48 +1303,48 @@ documented_lang_options[] = { "-Wmissing-declarations", N_("Warn about global funcs without previous declarations") }, { "-Wno-missing-declarations", "" }, - { "-Wmissing-prototypes", + { "-Wmissing-prototypes", N_("Warn about global funcs without prototypes") }, { "-Wno-missing-prototypes", "" }, - { "-Wmultichar", + { "-Wmultichar", N_("Warn about use of multicharacter literals") }, { "-Wno-multichar", "" }, - { "-Wnested-externs", + { "-Wnested-externs", N_("Warn about externs not at file scope level") }, { "-Wno-nested-externs", "" }, - { "-Wparentheses", + { "-Wparentheses", N_("Warn about possible missing parentheses") }, { "-Wno-parentheses", "" }, - { "-Wsequence-point", - N_("Warn about possible violations of sequence point rules") }, - { "-Wno-sequence-point", "" }, - { "-Wpointer-arith", + { "-Wpointer-arith", N_("Warn about function pointer arithmetic") }, { "-Wno-pointer-arith", "" }, { "-Wredundant-decls", N_("Warn about multiple declarations of the same object") }, { "-Wno-redundant-decls", "" }, - { "-Wsign-compare", + { "-Wreturn-type", + N_("Warn whenever a function's return-type defaults to int") }, + { "-Wno-return-type", "" }, + { "-Wsequence-point", + N_("Warn about possible violations of sequence point rules") }, + { "-Wno-sequence-point", "" }, + { "-Wsign-compare", N_("Warn about signed/unsigned comparisons") }, { "-Wno-sign-compare", "" }, - { "-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", + { "-Wstrict-prototypes", N_("Warn about non-prototyped function decls") }, { "-Wno-strict-prototypes", "" }, - { "-Wtraditional", - N_("Warn about constructs whose meaning change in ISO C") }, + { "-Wtraditional", + N_("Warn about constructs whose meanings change in ISO C") }, { "-Wno-traditional", "" }, - { "-Wtrigraphs", + { "-Wtrigraphs", N_("Warn when trigraphs are encountered") }, { "-Wno-trigraphs", "" }, { "-Wundef", "" }, { "-Wno-undef", "" }, - { "-Wwrite-strings", + { "-Wunknown-pragmas", + N_("Warn about unrecognized pragmas") }, + { "-Wno-unknown-pragmas", "" }, + { "-Wwrite-strings", N_("Mark strings as 'const char *'") }, { "-Wno-write-strings", "" }, @@ -1365,7 +1366,7 @@ static const struct const int value; const char *const description; } -target_switches [] = TARGET_SWITCHES; +target_switches[] = TARGET_SWITCHES; /* This table is similar, but allows the switch to have a value. */ @@ -1376,7 +1377,7 @@ static const struct const char **const variable; const char *const description; } -target_options [] = TARGET_OPTIONS; +target_options[] = TARGET_OPTIONS; #endif /* Options controlling warnings. */ @@ -1417,10 +1418,20 @@ int warn_uninitialized; int warn_shadow; -/* Warn if a switch on an enum fails to have a case for every enum value. */ +/* Warn if a switch on an enum, that does not have a default case, + fails to have a case for every enum value. */ int warn_switch; +/* Warn if a switch does not have a default case. */ + +int warn_switch_default; + +/* Warn if a switch on an enum fails to have a case for every enum + value (regardless of the presence or otherwise of a default case). */ + +int warn_switch_enum; + /* Nonzero means warn about function definitions that default the return type or that use a null return and have a return-type other than void. */ @@ -1464,6 +1475,11 @@ int warn_disabled_optimization; int warn_missing_noreturn; +/* Nonzero means warn about uses of __attribute__((deprecated)) + declarations. */ + +int warn_deprecated_decl = 1; + /* Likewise for -W. */ static const lang_independent_options W_options[] = @@ -1485,7 +1501,11 @@ static const lang_independent_options W_options[] = {"shadow", &warn_shadow, 1, N_("Warn when one local variable shadows another") }, {"switch", &warn_switch, 1, - N_("Warn about enumerated switches missing a specific case") }, + N_("Warn about enumerated switches, with no default, missing a case") }, + {"switch-default", &warn_switch_default, 1, + N_("Warn about enumerated switches missing a default case") }, + {"switch-enum", &warn_switch_enum, 1, + N_("Warn about all enumerated switches missing a specific case") }, {"aggregate-return", &warn_aggregate_return, 1, N_("Warn about returning structures, unions or arrays") }, {"cast-align", &warn_cast_align, 1, @@ -1502,6 +1522,8 @@ static const lang_independent_options W_options[] = 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") } }; @@ -1527,19 +1549,20 @@ set_Wunused (setting) -ffast-math and -fno-fast-math imply. */ void -set_fast_math_flags () +set_fast_math_flags (int set) { - flag_trapping_math = 0; - flag_unsafe_math_optimizations = 1; - flag_errno_math = 0; + flag_trapping_math = !set; + flag_unsafe_math_optimizations = set; + flag_errno_math = !set; } -void -set_no_fast_math_flags () +/* Return true iff flags are set as if -ffast-math. */ +bool +fast_math_flags_set_p () { - flag_trapping_math = 1; - flag_unsafe_math_optimizations = 0; - flag_errno_math = 1; + return (!flag_trapping_math + && flag_unsafe_math_optimizations + && !flag_errno_math); } @@ -1580,19 +1603,7 @@ read_integral_parameter (p, pname, defval) return atoi (p); } - -/* This is the default decl_printable_name function. */ - -static const char * -decl_name (decl, verbosity) - tree decl; - int verbosity ATTRIBUTE_UNUSED; -{ - return IDENTIFIER_POINTER (DECL_NAME (decl)); -} - - /* 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. */ @@ -1646,73 +1657,6 @@ floor_log2_wide (x) return log; } -static int float_handler_set; -int float_handled; -jmp_buf float_handler; - -/* Signals actually come here. */ - -static void -float_signal (signo) - /* If this is missing, some compilers complain. */ - int signo ATTRIBUTE_UNUSED; -{ - if (float_handled == 0) - 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); -} - -/* Specify where to longjmp to when a floating arithmetic error happens. - If HANDLER is 0, it means don't handle the errors any more. */ - -static void -set_float_handler (handler) - jmp_buf handler; -{ - float_handled = (handler != 0); - if (handler) - memcpy (float_handler, handler, sizeof (float_handler)); - - if (float_handled && ! float_handler_set) - { - signal (SIGFPE, float_signal); - float_handler_set = 1; - } -} - -/* This is a wrapper function for code which might elicit an - arithmetic exception. That code should be passed in as a function - 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 - occurred.) It returns 1 (success) otherwise. */ - -int -do_float_handler (fn, 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 (). */ - set_float_handler (NULL); - return 0; - } - - set_float_handler (buf); - (*fn)(data); - set_float_handler (NULL); - return 1; -} - /* Handler for fatal signals, such as SIGSEGV. These are transformed into ICE messages, which is much more user friendly. */ @@ -1734,7 +1678,7 @@ strip_off_ending (name, len) int len; { int i; - for (i = 2; i < 6 && len > i; i++) + for (i = 2; i < 6 && len > i; i++) { if (name[len - i] == '.') { @@ -1759,14 +1703,37 @@ output_quoted_string (asm_file, string) putc ('\"', asm_file); while ((c = *string++) != 0) { - if (c == '\"' || c == '\\') - putc ('\\', asm_file); - putc (c, asm_file); + if (ISPRINT (c)) + { + if (c == '\"' || c == '\\') + putc ('\\', asm_file); + putc (c, asm_file); + } + else + fprintf (asm_file, "\\%03o", (unsigned char) c); } putc ('\"', asm_file); #endif } +/* Output NAME into FILE after having turned it into something + usable as an identifier in a target's assembly file. */ +void +output_clean_symbol_name (file, name) + FILE *file; + const char *name; +{ + /* Make a copy of NAME. */ + char *id = xstrdup (name); + + /* Make it look like a valid identifier for an assembler. */ + clean_symbol_name (id); + + fputs (id, file); + free (id); +} + + /* Output a file name in the form wanted by System V. */ void @@ -1781,7 +1748,7 @@ output_file_directive (asm_file, input_name) while (na > input_name) { if (IS_DIR_SEPARATOR (na[-1])) - break; + break; na--; } @@ -1844,8 +1811,13 @@ open_dump_file (index, decl) free (dump_name); if (decl) - fprintf (rtl_dump_file, "\n;; Function %s\n\n", - decl_printable_name (decl, 2)); + fprintf (rtl_dump_file, "\n;; Function %s%s\n\n", + (*lang_hooks.decl_printable_name) (decl, 2), + cfun->function_frequency == FUNCTION_FREQUENCY_HOT + ? " (hot)" + : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + ? " (unlikely executed)" + : ""); timevar_pop (TV_DUMP); return 1; @@ -1908,9 +1880,8 @@ wrapup_global_declarations (vec, len) /* 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); + if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0) + (*lang_hooks.finish_incomplete_decl) (decl); } /* Now emit any global variables or functions that we have been @@ -1951,16 +1922,24 @@ wrapup_global_declarations (vec, len) to force a constant to be written if and only if it is 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)) - && !DECL_COMDAT (decl)) - || (!optimize - && flag_keep_static_consts - && !DECL_ARTIFICIAL (decl)) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))) + if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)) { - reconsider = 1; - rest_of_decl_compilation (decl, NULL, 1, 1); + bool needed = 1; + + if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))) + /* needed */; + else if (DECL_COMDAT (decl)) + needed = 0; + else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) + && (optimize || !flag_keep_static_consts + || DECL_ARTIFICIAL (decl))) + needed = 0; + + if (needed) + { + reconsider = 1; + rest_of_decl_compilation (decl, NULL, 1, 1); + } } if (TREE_CODE (decl) == FUNCTION_DECL @@ -2029,22 +2008,19 @@ check_global_declarations (vec, len) assemble_external (decl); } - /* 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_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) + /* Warn about static fns or vars defined but not used. */ + if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL) + || (warn_unused_variable && TREE_CODE (decl) == VAR_DECL)) + && ! TREE_USED (decl) + /* The TREE_USED bit for file-scope decls is kept in the identifier, + to handle multiple external decls in different scopes. */ + && ! TREE_USED (DECL_NAME (decl)) && ! DECL_EXTERNAL (decl) && ! TREE_PUBLIC (decl) - && ! TREE_USED (decl) - && (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) - /* The TREE_USED bit for file-scope decls - is kept in the identifier, to handle multiple - external decls in different scopes. */ - && ! TREE_USED (DECL_NAME (decl))) + /* Global register variables must be declared to reserve them. */ + && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) + /* Otherwise, ask the language. */ + && (*lang_hooks.decls.warn_unused_global) (decl)) warning_with_decl (decl, "`%s' defined but not used"); timevar_push (TV_SYMOUT); @@ -2073,7 +2049,6 @@ push_srcloc (file, line) 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++; @@ -2114,9 +2089,9 @@ compile_file () timevar_push (TV_PARSE); - /* Call the parser, which parses the entire file - (calling rest_of_compilation for each function). */ - yyparse (); + /* Call the parser, which parses the entire file (calling + rest_of_compilation for each function). */ + (*lang_hooks.parse_file) (set_yydebug); /* In case there were missing block closers, get us back to the global binding level. */ @@ -2124,13 +2099,12 @@ compile_file () /* Compilation is now finished except for writing what's left of the symbol table output. */ - timevar_pop (TV_PARSE); if (flag_syntax_only) return; - globals = getdecls (); + globals = (*lang_hooks.decls.getdecls) (); /* Really define vars that have had only a tentative definition. Really output inline functions that must actually be callable @@ -2247,17 +2221,31 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) #define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END) #endif + /* We deferred calling assemble_alias so that we could collect + other attributes such as visibility. Emit the alias now. */ + { + tree alias; + alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); + if (alias) + { + alias = TREE_VALUE (TREE_VALUE (alias)); + alias = get_identifier (TREE_STRING_POINTER (alias)); + assemble_alias (decl, alias); + } + } + /* Forward declarations for nested functions are not "external", but we need to treat them as if they were. */ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL) { 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. */ + + /* 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) @@ -2265,6 +2253,7 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, top_level, at_end); } + timevar_pop (TV_VARCONST); } else if (DECL_REGISTER (decl) && asmspec != 0) @@ -2332,7 +2321,7 @@ rest_of_type_compilation (type, toplev) timevar_pop (TV_SYMOUT); } -/* This is called from finish_function (within yyparse) +/* This is called from finish_function (within langhooks.parse_file) after each top-level definition is parsed. It is supposed to compile that function or variable and output the assembler code for it. @@ -2363,11 +2352,6 @@ rest_of_compilation (decl) if (!cfun->x_whole_function_mode_p) identify_blocks (); - /* Then remove any notes we don't need. That will make iterating - over the instruction sequence faster, and allow the garbage - collector to reclaim the memory used by the notes. */ - remove_unnecessary_notes (); - /* In function-at-a-time mode, we do not attempt to keep the BLOCK tree in sensible shape. So, we just recalculate it here. */ if (cfun->x_whole_function_mode_p) @@ -2452,6 +2436,7 @@ rest_of_compilation (decl) if (inlinable || (DECL_INLINE (decl) && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl) + && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) && ! flag_keep_inline_functions) || DECL_EXTERNAL (decl)))) DECL_DEFER_OUTPUT (decl) = 1; @@ -2505,6 +2490,29 @@ 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. */ @@ -2517,31 +2525,59 @@ rest_of_compilation (decl) 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 + 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 cleanup_cfg. */ - if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) + /* Early return if there were errors. We can run afoul of our + consistency checks, and there's not really much point in fixing them. + Don't return yet if -Wreturn-type; we need to do cleanup_cfg. */ + if (((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type) + || errorcount || sorrycount) goto exit_rest_of_compilation; + timevar_push (TV_JUMP); + open_dump_file (DFI_sibling, decl); + insns = get_insns (); + rebuild_jump_labels (insns); + find_exception_handler_labels (); + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + + delete_unreachable_blocks (); + + /* Turn NOTE_INSN_PREDICTIONs into branch predictions. */ + note_prediction_to_br_prob (); + /* We may have potential sibling or tail recursion sites. Select one (of possibly multiple) methods of performing the call. */ if (flag_optimize_sibling_calls) { - timevar_push (TV_JUMP); - open_dump_file (DFI_sibling, decl); - + rtx insn; optimize_sibling_and_tail_recursive_calls (); - close_dump_file (DFI_sibling, print_rtl, get_insns ()); - timevar_pop (TV_JUMP); + /* Recompute the CFG as sibling optimization clobbers it randomly. */ + free_bb_for_insn (); + find_exception_handler_labels (); + rebuild_jump_labels (insns); + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + + /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION + notes before simplifying cfg and we must do lowering after sibcall + that unhides parts of RTL chain and cleans up the CFG. + + Until sibcall is replaced by tree-level optimizer, lets just + sweep away the NOTE_INSN_PREDICTION notes that leaked out. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (GET_CODE (insn) == NOTE + && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION) + delete_insn (insn); } + close_dump_file (DFI_sibling, print_rtl, get_insns ()); + timevar_pop (TV_JUMP); + scope_to_insns_initialize (); /* Complete generation of exception handling code. */ - find_exception_handler_labels (); if (doing_eh (0)) { timevar_push (TV_JUMP); @@ -2553,6 +2589,10 @@ rest_of_compilation (decl) timevar_pop (TV_JUMP); } + /* Delay emitting hard_reg_initial_value sets until after EH landing pad + generation, which might create new sets. */ + emit_initial_value_sets (); + #ifdef FINALIZE_PIC /* If we are doing position-independent code generation, now is the time to output special prologues and epilogues. @@ -2568,7 +2608,10 @@ rest_of_compilation (decl) unshare_all_rtl (current_function_decl, insns); #ifdef SETJMP_VIA_SAVE_AREA - /* This must be performed before virtual register instantiation. */ + /* This must be performed before virtual register instantiation. + Please be aware the everything in the compiler that can look + at the RTL up to this point must understand that REG_SAVE_AREA + is just like a use of the REG contained inside. */ if (current_function_calls_alloca) optimize_save_area_alloca (insns); #endif @@ -2590,7 +2633,10 @@ rest_of_compilation (decl) 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); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); /* CFG is no longer maintained up-to-date. */ free_bb_for_insn (); @@ -2598,11 +2644,11 @@ rest_of_compilation (decl) purge_line_number_notes (insns); timevar_pop (TV_JUMP); + close_dump_file (DFI_jump, print_rtl, insns); /* Now is when we stop if -fsyntax-only and -Wreturn-type. */ if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl)) { - close_dump_file (DFI_jump, print_rtl, insns); goto exit_rest_of_compilation; } @@ -2652,7 +2698,7 @@ rest_of_compilation (decl) open_dump_file (DFI_ssa_dce, decl); insns = get_insns (); - ssa_eliminate_dead_code(); + ssa_eliminate_dead_code (); close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns); timevar_pop (TV_SSA_DCE); @@ -2677,25 +2723,20 @@ rest_of_compilation (decl) timevar_push (TV_JUMP); - if (optimize > 0) + if (flag_delete_null_pointer_checks || flag_if_conversion) { + open_dump_file (DFI_null, decl); 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); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - /* 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); + + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); + close_dump_file (DFI_null, print_rtl_with_bb, insns); } /* Jump optimization, and the removal of NULL pointer checks, may @@ -2704,9 +2745,11 @@ rest_of_compilation (decl) maximum instruction UID, so if we can reduce the maximum UID we'll save big on memory. */ renumber_insns (rtl_dump_file); + if (optimize) + compute_bb_for_insn (); timevar_pop (TV_JUMP); - close_dump_file (DFI_jump, print_rtl, insns); + close_dump_file (DFI_jump, print_rtl_with_bb, insns); ggc_collect (); @@ -2718,58 +2761,50 @@ rest_of_compilation (decl) if (optimize > 0) { open_dump_file (DFI_cse, decl); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + if (tem) + rebuild_jump_labels (insns); + purge_all_dead_edges (0); + + delete_trivially_dead_insns (insns, max_reg_num ()); /* If we are not running more CSE passes, then we are no longer expecting CSE to be run. But always rerun it in a cheap mode. */ cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; if (tem || optimize > 1) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (insns); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - timevar_pop (TV_JUMP); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); - } - - /* Run this after jump optmizations remove all the unreachable code - so that unreachable code will not keep values live. */ - delete_trivially_dead_insns (insns, max_reg_num (), 0); - + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); /* Try to identify useless null pointer tests and delete them. */ if (flag_delete_null_pointer_checks || flag_thread_jumps) { 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); + compute_bb_for_insn (); timevar_pop (TV_CSE); - close_dump_file (DFI_cse, print_rtl, insns); + close_dump_file (DFI_cse, print_rtl_with_bb, insns); } open_dump_file (DFI_addressof, decl); purge_addressof (insns); + if (optimize) + purge_all_dead_edges (0); reg_scan (insns, max_reg_num (), 1); close_dump_file (DFI_addressof, print_rtl, insns); @@ -2786,16 +2821,15 @@ rest_of_compilation (decl) 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); + delete_trivially_dead_insns (insns, max_reg_num ()); 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) @@ -2803,6 +2837,8 @@ rest_of_compilation (decl) timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + purge_all_dead_edges (0); + delete_trivially_dead_insns (insns, max_reg_num ()); timevar_pop (TV_CSE); cse_not_expected = !flag_rerun_cse_after_loop; } @@ -2814,11 +2850,7 @@ rest_of_compilation (decl) 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) @@ -2826,24 +2858,32 @@ rest_of_compilation (decl) timevar_push (TV_CSE); reg_scan (insns, max_reg_num (), 1); tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file); + purge_all_dead_edges (0); + delete_trivially_dead_insns (insns, max_reg_num ()); timevar_pop (TV_CSE); } } - close_dump_file (DFI_gcse, print_rtl, insns); + close_dump_file (DFI_gcse, print_rtl_with_bb, insns); timevar_pop (TV_GCSE); ggc_collect (); flag_cse_skip_blocks = save_csb; flag_cse_follow_jumps = save_cfj; - } +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif + } /* Move constant computations out of loops. */ - if (optimize > 0) + if (optimize > 0 && flag_loop_optimize) { timevar_push (TV_LOOP); + delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); open_dump_file (DFI_loop, decl); + /* CFG is no longer maintained up-to-date. */ free_bb_for_insn (); if (flag_rerun_loop_opt) @@ -2851,14 +2891,13 @@ rest_of_compilation (decl) cleanup_barriers (); /* We only want to perform unrolling once. */ - - loop_optimize (insns, rtl_dump_file, 0); + loop_optimize (insns, rtl_dump_file, LOOP_FIRST_PASS); /* 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); + delete_trivially_dead_insns (insns, max_reg_num ()); /* The regscan pass is currently necessary as the alias analysis code depends on this information. */ @@ -2869,62 +2908,113 @@ rest_of_compilation (decl) (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT | (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0)); + /* Loop can create trivially dead instructions. */ + delete_trivially_dead_insns (insns, max_reg_num ()); close_dump_file (DFI_loop, print_rtl, insns); timevar_pop (TV_LOOP); ggc_collect (); } + /* Do control and data flow analysis; wrote some of the results to + the dump file. */ + + timevar_push (TV_FLOW); + open_dump_file (DFI_cfg, decl); + + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + + /* It may make more sense to mark constant functions after dead code is + eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs + may insert code making function non-constant, but we still must consider + it as constant, otherwise -fbranch-probabilities will not read data back. + + life_analyzis rarely eliminates modification of external memory. + */ + if (optimize) + mark_constant_function (); + + close_dump_file (DFI_cfg, print_rtl_with_bb, insns); + + /* Do branch profiling and static profile estimation passes. */ + if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities) + { + struct loops loops; + + timevar_push (TV_BRANCH_PROB); + open_dump_file (DFI_bp, decl); + if (cfun->arc_profile || flag_branch_probabilities) + branch_prob (); + + /* Discover and record the loop depth at the head of each basic + block. The loop infrastructure does the real job for us. */ + flow_loops_find (&loops, LOOP_TREE); + + /* Estimate using heuristics if no profiling info is available. */ + if (flag_guess_branch_prob) + estimate_probability (&loops); + + if (rtl_dump_file) + flow_loops_dump (&loops, rtl_dump_file, NULL, 0); + + flow_loops_free (&loops); + close_dump_file (DFI_bp, print_rtl_with_bb, insns); + timevar_pop (TV_BRANCH_PROB); + } + if (flag_tracer) + { + timevar_push (TV_TRACER); + open_dump_file (DFI_tracer, decl); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE); + tracer (); + cleanup_cfg (CLEANUP_EXPENSIVE); + close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ()); + timevar_pop (TV_TRACER); + reg_scan (get_insns (), max_reg_num (), 0); + } + if (optimize > 0) { timevar_push (TV_CSE2); open_dump_file (DFI_cse2, decl); + if (rtl_dump_file) + dump_flow_info (rtl_dump_file); if (flag_rerun_cse_after_loop) { - /* Running another jump optimization pass before the second - cse pass sometimes simplifies the RTL enough to allow - the second CSE pass to do a better job. Jump_optimize can change - max_reg_num so we must rerun reg_scan afterwards. - ??? Rework to not call reg_scan so often. */ timevar_push (TV_JUMP); - /* The previous call to loop_optimize makes some instructions - trivially dead. We delete those instructions now in the - hope that doing so will make the heuristics in jump work - better and possibly speed up compilation. */ - delete_trivially_dead_insns (insns, max_reg_num (), 0); - reg_scan (insns, max_reg_num (), 0); timevar_push (TV_IFCVT); - - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); cleanup_cfg (CLEANUP_EXPENSIVE); - if_convert (0); - - timevar_pop(TV_IFCVT); + if (flag_if_conversion) + if_convert (0); + timevar_pop (TV_IFCVT); timevar_pop (TV_JUMP); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); reg_scan (insns, max_reg_num (), 0); tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file); + purge_all_dead_edges (0); + delete_trivially_dead_insns (insns, max_reg_num ()); 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); } } - close_dump_file (DFI_cse2, print_rtl, insns); + close_dump_file (DFI_cse2, print_rtl_with_bb, insns); timevar_pop (TV_CSE2); ggc_collect (); @@ -2932,60 +3022,18 @@ rest_of_compilation (decl) cse_not_expected = 1; + open_dump_file (DFI_life, decl); regclass_init (); - /* Do control and data flow analysis; wrote some of the results to - the dump file. */ - - timevar_push (TV_FLOW); - open_dump_file (DFI_cfg, decl); - - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); - cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0 - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); check_function_return_warnings (); - /* It may make more sense to mark constant functions after dead code is - eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs - may insert code making function non-constant, but we still must consider - it as constant, otherwise -fbranch-probabilities will not read data back. - - life_analyzis rarely eliminates modification of external memory. - */ - mark_constant_function (); - - close_dump_file (DFI_cfg, print_rtl_with_bb, insns); - - if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) - { - timevar_push (TV_BRANCH_PROB); - open_dump_file (DFI_bp, decl); - - branch_prob (); - - close_dump_file (DFI_bp, print_rtl_with_bb, insns); - timevar_pop (TV_BRANCH_PROB); - } - - open_dump_file (DFI_life, decl); - if (optimize) - { - struct loops loops; - - /* Discover and record the loop depth at the head of each basic - block. The loop infrastructure does the real job for us. */ - flow_loops_find (&loops, LOOP_TREE); - - /* Estimate using heuristics if no profiling info is available. */ - if (flag_guess_branch_prob) - estimate_probability (&loops); - - if (rtl_dump_file) - flow_loops_dump (&loops, rtl_dump_file, NULL, 0); - - flow_loops_free (&loops); - } +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif life_analysis (insns, rtl_dump_file, PROP_FINAL); + if (optimize) + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); timevar_pop (TV_FLOW); no_new_pseudos = 1; @@ -2999,12 +3047,14 @@ rest_of_compilation (decl) if (optimize) { + clear_bb_flags (); 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)); + insns = get_insns (); + update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES, + PROP_LOG_LINKS | PROP_REG_INFO + | PROP_DEATH_NOTES); } } @@ -3024,10 +3074,6 @@ rest_of_compilation (decl) rebuild_jump_labels_after_combine = combine_instructions (insns, max_reg_num ()); - /* Always purge dead edges, as we may eliminate an insn throwing - exception. */ - rebuild_jump_labels_after_combine |= purge_all_dead_edges (true); - /* Combining insns may have turned an indirect jump into a direct jump. Rebuid the JUMP_LABEL fields of jumping instructions. */ @@ -3048,7 +3094,7 @@ rest_of_compilation (decl) /* Rerun if-conversion, as combine may have simplified things enough to now meet sequence length restrictions. */ - if (optimize > 0) + if (flag_if_conversion) { timevar_push (TV_IFCVT); open_dump_file (DFI_ce, decl); @@ -3070,6 +3116,7 @@ rest_of_compilation (decl) regmove_optimize (insns, max_reg_num (), rtl_dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); close_dump_file (DFI_regmove, print_rtl_with_bb, insns); timevar_pop (TV_REGMOVE); @@ -3088,13 +3135,7 @@ rest_of_compilation (decl) timevar_push (TV_MODE_SWITCH); no_new_pseudos = 0; - if (optimize_mode_switching (NULL)) - { - /* We did work, and so had to regenerate global life information. - Take advantage of this and don't re-recompute register life - information below. */ - register_life_up_to_date = 1; - } + optimize_mode_switching (NULL); no_new_pseudos = 1; timevar_pop (TV_MODE_SWITCH); @@ -3217,6 +3258,7 @@ rest_of_compilation (decl) timevar_push (TV_JUMP); rebuild_jump_labels (insns); + purge_all_dead_edges (0); timevar_pop (TV_JUMP); } @@ -3245,8 +3287,9 @@ rest_of_compilation (decl) if (optimize) { - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP); life_analysis (insns, rtl_dump_file, PROP_FINAL); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE + | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); /* This is kind of a heuristic. We need to run combine_stack_adjustments even for machines with possibly nonzero RETURN_POPS_ARGS @@ -3278,21 +3321,21 @@ rest_of_compilation (decl) } #endif - if (flag_rename_registers || flag_cprop_registers) + if (optimize > 0 && (flag_rename_registers || flag_cprop_registers)) { timevar_push (TV_RENAME_REGISTERS); open_dump_file (DFI_rnreg, decl); if (flag_rename_registers) - regrename_optimize (); + regrename_optimize (); if (flag_cprop_registers) - copyprop_hardreg_forward (); + copyprop_hardreg_forward (); close_dump_file (DFI_rnreg, print_rtl_with_bb, insns); timevar_pop (TV_RENAME_REGISTERS); } - if (optimize > 0) + if (flag_if_conversion2) { timevar_push (TV_IFCVT2); open_dump_file (DFI_ce2, decl); @@ -3348,10 +3391,12 @@ rest_of_compilation (decl) timevar_push (TV_REORDER_BLOCKS); open_dump_file (DFI_bbro, decl); - /* Last attempt to optimize CFG, as life analyzis possibly removed - some instructions. */ + /* Last attempt to optimize CFG, as scheduling, peepholing and insn + splitting possibly introduced more crossjumping oppurtuntities. + Except that we can't actually run crossjumping without running + another DCE pass, which we can't do after reg-stack. */ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK - | CLEANUP_CROSSJUMP); + | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); if (flag_reorder_blocks) { reorder_basic_blocks (); @@ -3502,10 +3547,6 @@ rest_of_compilation (decl) 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 (); - /* Show no temporary slots allocated. */ init_temp_slots (); @@ -3555,12 +3596,13 @@ display_help () printf (_(" -finline-limit= Limits the size of inlined functions to \n")); printf (_(" -fmessage-length= Limits diagnostics messages lengths to 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")); + printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n")); for (i = ARRAY_SIZE (f_options); i--;) { const char *description = f_options[i].description; - if (description != NULL && * description != 0) + if (description != NULL && *description != 0) printf (" -f%-21s %s\n", f_options[i].string, _(description)); } @@ -3570,9 +3612,9 @@ display_help () for (i = LAST_PARAM; i--;) { const char *description = compiler_params[i].help; - const int length = 21-strlen(compiler_params[i].option); + const int length = 21 - strlen (compiler_params[i].option); - if (description != NULL && * description != 0) + if (description != NULL && *description != 0) printf (" --param %s=%.*s%s\n", compiler_params[i].option, length > 0 ? length : 1, " ", @@ -3587,7 +3629,7 @@ display_help () { const char *description = W_options[i].description; - if (description != NULL && * description != 0) + if (description != NULL && *description != 0) printf (" -W%-21s %s\n", W_options[i].string, _(description)); } @@ -3595,12 +3637,6 @@ display_help () printf (_(" -Wunused Enable unused warnings\n")); printf (_(" -Wlarger-than- Warn if an object is larger than bytes\n")); printf (_(" -p Enable function profiling\n")); -#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) - 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 Place output into \n")); printf (_("\ -G Put global and static data smaller than \n\ @@ -3679,7 +3715,7 @@ display_help () static void display_target_options () { - int undoc,i; + int undoc, i; static bool displayed = false; /* Avoid double printing for --help --target-help. */ @@ -3713,7 +3749,7 @@ display_target_options () if (extra_warnings) printf (_(" -m%-23.23s [undocumented]\n"), option); } - else if (* description != 0) + else if (*description != 0) doc += printf (" -m%-23.23s %s\n", option, _(description)); } @@ -3732,7 +3768,7 @@ display_target_options () if (extra_warnings) printf (_(" -m%-23.23s [undocumented]\n"), option); } - else if (* description != 0) + else if (*description != 0) doc += printf (" -m%-23.23s %s\n", option, _(description)); } #endif @@ -3768,9 +3804,9 @@ decode_d_option (arg) flag_print_asm_name = 1; break; case 'P': - flag_dump_rtl_in_asm = 1; - flag_print_asm_name = 1; - break; + flag_dump_rtl_in_asm = 1; + flag_print_asm_name = 1; + break; case 'v': graph_dump_format = vcg; break; @@ -3778,7 +3814,7 @@ decode_d_option (arg) rtl_dump_and_exit = 1; break; case 'y': - (*lang_hooks.set_yydebug) (1); + set_yydebug = 1; break; case 'D': /* These are handled by the preprocessor. */ case 'I': @@ -3828,9 +3864,9 @@ decode_f_option (arg) } if (!strcmp (arg, "fast-math")) - set_fast_math_flags(); + set_fast_math_flags (1); else if (!strcmp (arg, "no-fast-math")) - set_no_fast_math_flags(); + set_fast_math_flags (0); else if ((option_value = skip_leading_substring (arg, "inline-limit-")) || (option_value = skip_leading_substring (arg, "inline-limit="))) { @@ -3839,6 +3875,19 @@ decode_f_option (arg) MAX_INLINE_INSNS); set_param_value ("max-inline-insns", val); } + else if ((option_value = skip_leading_substring (arg, "tls-model="))) + { + if (strcmp (option_value, "global-dynamic") == 0) + flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; + else if (strcmp (option_value, "local-dynamic") == 0) + flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC; + else if (strcmp (option_value, "initial-exec") == 0) + flag_tls_default = TLS_MODEL_INITIAL_EXEC; + else if (strcmp (option_value, "local-exec") == 0) + flag_tls_default = TLS_MODEL_LOCAL_EXEC; + else + warning ("`%s': unknown tls-model option", arg - 2); + } #ifdef INSN_SCHEDULING else if ((option_value = skip_leading_substring (arg, "sched-verbose="))) fix_sched_param ("verbose", option_value); @@ -3876,7 +3925,7 @@ decode_f_option (arg) stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm); } else if ((option_value - = skip_leading_substring (arg, "message-length="))) + = 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))); @@ -3884,10 +3933,10 @@ decode_f_option (arg) = skip_leading_substring (arg, "diagnostics-show-location="))) { if (!strcmp (option_value, "once")) - diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_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; + diagnostic_prefixing_rule (global_dc) + = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; else error ("unrecognized option `%s'", arg - 2); } @@ -3962,7 +4011,7 @@ static int decode_g_option (arg) const char *arg; { - static unsigned level=0; + 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 @@ -4030,7 +4079,7 @@ ignoring option `%s' due to invalid debug level specification", if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0) { -#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2) +#ifdef DWARF2_DEBUGGING_INFO type = DWARF2_DEBUG; #else #ifdef DBX_DEBUGGING_INFO @@ -4486,25 +4535,25 @@ init_asm_output (name) 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; - } + { + 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; + asm_out_file = stdout; else - asm_out_file = fopen (asm_file_name, "w"); + asm_out_file = fopen (asm_file_name, "w"); if (asm_out_file == 0) fatal_io_error ("can't open %s for writing", asm_file_name); } #ifdef IO_BUFFER_SIZE setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE), - _IOFBF, IO_BUFFER_SIZE); + _IOFBF, IO_BUFFER_SIZE); #endif if (!flag_syntax_only) @@ -4546,10 +4595,6 @@ general_init (argv0) 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); @@ -4566,6 +4611,9 @@ general_init (argv0) #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT) signal (SIGIOT, crash_signal); #endif +#ifdef SIGFPE + signal (SIGFPE, crash_signal); +#endif /* Initialize the diagnostics reporting machinery, so option parsing can give warnings and errors. */ @@ -4645,7 +4693,11 @@ parse_options_and_default_flags (argc, argv) flag_omit_frame_pointer = 1; #endif flag_guess_branch_prob = 1; - /* flag_cprop_registers = 1; */ + flag_cprop_registers = 1; + flag_loop_optimize = 1; + flag_crossjumping = 1; + flag_if_conversion = 1; + flag_if_conversion2 = 1; } if (optimize >= 2) @@ -4669,6 +4721,7 @@ parse_options_and_default_flags (argc, argv) flag_strict_aliasing = 1; flag_delete_null_pointer_checks = 1; flag_reorder_blocks = 1; + flag_reorder_functions = 1; } if (optimize >= 3) @@ -4773,6 +4826,11 @@ parse_options_and_default_flags (argc, argv) } } + if (flag_no_inline == 2) + flag_no_inline = 0; + else + flag_really_no_inline = flag_no_inline; + /* 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 @@ -4792,6 +4850,9 @@ parse_options_and_default_flags (argc, argv) warning ("-Wuninitialized is not supported without -O"); } + if (flag_really_no_inline == 2) + flag_really_no_inline = flag_no_inline; + /* All command line options have been parsed; allow the front end to perform consistency checks, etc. */ (*lang_hooks.post_options) (); @@ -4852,16 +4913,6 @@ process_options () 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) { @@ -4966,6 +5017,14 @@ process_options () } #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"); @@ -4977,19 +5036,8 @@ process_options () static void lang_independent_init () { - decl_printable_name = decl_name; - lang_expand_expr = (lang_expand_expr_t) do_abort; - - /* Set the language-dependent identifier size. */ - tree_code_length[(int) IDENTIFIER_NODE] - = ((lang_hooks.identifier_size - sizeof (struct tree_common)) - / sizeof (tree)); - /* Initialize the garbage-collector, and string pools. */ init_ggc (); - ggc_add_rtx_root (&stack_limit_rtx, 1); - ggc_add_tree_root (¤t_function_decl, 1); - ggc_add_tree_root (¤t_function_func_begin_label, 1); init_stringpool (); init_obstacks (); @@ -5004,19 +5052,15 @@ lang_independent_init () || 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 (); @@ -5047,6 +5091,7 @@ lang_dependent_init (name) front end is initialized. */ init_eh (); init_optabs (); + init_expr_once (); /* Put an entry on the input file stack for the main input file. */ push_srcloc (input_filename, 0); @@ -5168,14 +5213,14 @@ toplev_main (argc, argv) hex_init (); /* Initialization of GCC's environment, and diagnostics. */ - general_init (argv [0]); + 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) + if (!errorcount && !exit_after_options) do_compile (); if (errorcount || sorrycount)