X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftoplev.c;h=6ce6ecdbd04e624b841162b964f91f8d5d95dc40;hp=5a8c0dd09143411d54152b2b0c5b6fa4e9718081;hb=6ff922f90a7927d17c494884947931ddc0d49564;hpb=7bc16a7d656758c9c071bf456e4f9a1017b0b95c diff --git a/gcc/toplev.c b/gcc/toplev.c index 5a8c0dd0914..6ce6ecdbd04 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -29,7 +29,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 +69,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,55 +87,27 @@ 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 */ - /* Carry information from ASM_DECLARE_OBJECT_NAME to ASM_FINISH_DECLARE_OBJECT. */ extern int size_directive_output; extern tree last_assemble_variable_decl; +extern void reg_alloc PARAMS ((void)); + static void general_init PARAMS ((char *)); static void parse_options_and_default_flags PARAMS ((int, char **)); static void do_compile PARAMS ((void)); static void process_options PARAMS ((void)); -static void lang_independent_init PARAMS ((void)); +static void backend_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)); @@ -153,6 +125,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 @@ -193,6 +168,10 @@ int input_file_stack_tick; const char *dump_base_name; +/* Name to use as a base for auxiliary output files. */ + +const char *aux_base_name; + /* Format to use to print dumpfile index value */ #ifndef DUMPFILE_FORMAT #define DUMPFILE_FORMAT ".%02d." @@ -204,9 +183,14 @@ const char *dump_base_name; extern int target_flags; +/* A mask of target_flags that includes bit X if X was set or cleared + on the command line. */ + +int target_flags_explicit; + /* Debug hooks - dependent upon command line options. */ -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. */ @@ -247,6 +231,7 @@ enum dump_file_index DFI_loop, DFI_cfg, DFI_bp, + DFI_tracer, DFI_cse2, DFI_life, DFI_combine, @@ -294,6 +279,7 @@ static struct dump_file_info dump_file[DFI_MAX] = { "loop", 'L', 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 }, @@ -376,29 +362,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; @@ -411,6 +374,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; @@ -423,6 +391,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; @@ -607,12 +579,24 @@ int flag_errno_math = 1; int flag_unsafe_math_optimizations = 0; +/* Nonzero means that no NaNs or +-Infs are expected. */ + +int flag_finite_math_only = 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. */ + IEEE 754 arithmetic. Trapping conditions include division by zero, + overflow, underflow, invalid and inexact, but does not include + operations on signaling NaNs (see below). */ int flag_trapping_math = 1; +/* Nonzero means disable transformations observable by signaling NaNs. + This option implies that any operation on a IEEE signaling NaN can + generate a (user-visible) trap. */ + +int flag_signaling_nans = 0; + /* 0 means straightforward implementation of complex divide acceptable. 1 means wide ranges of inputs must work for complex divide. 2 means C99-like requirements for complex divide (not yet implemented). */ @@ -639,6 +623,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. */ @@ -678,7 +678,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. */ @@ -702,12 +707,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. */ @@ -879,6 +887,13 @@ int flag_merge_constants = 1; one, unconditionally renumber instruction UIDs. */ int flag_renumber_insns = 1; +/* If nonzero, use the graph coloring register allocator. */ +int flag_new_regalloc = 0; + +/* Nonzero if we perform superblock formation. */ + +int flag_tracer = 0; + /* 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 @@ -930,6 +945,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 } }; @@ -987,6 +1005,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, @@ -1043,6 +1063,14 @@ 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, @@ -1076,12 +1104,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, @@ -1144,6 +1178,8 @@ static const lang_independent_options f_options[] = N_("Process #ident directives") }, { "peephole2", &flag_peephole2, 1, N_("Enables an rtl peephole pass run before sched2") }, + {"finite-math-only", &flag_finite_math_only, 1, + N_("Assume no NaNs or +-Infs are generated") }, { "guess-branch-probability", &flag_guess_branch_prob, 1, N_("Enables guessing of branch probabilities") }, {"math-errno", &flag_errno_math, 1, @@ -1152,6 +1188,8 @@ static const lang_independent_options f_options[] = 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") }, + {"signaling-nans", &flag_signaling_nans, 1, + N_("Disable optimizations observable by IEEE signaling NaNs") }, {"bounded-pointers", &flag_bounded_pointers, 1, N_("Compile pointers as triples: value, base & end") }, {"bounds-check", &flag_bounds_check, 1, @@ -1164,6 +1202,8 @@ static const lang_independent_options f_options[] = N_("Report on permanent memory allocation at end of run") }, { "trapv", &flag_trapv, 1, N_("Trap for signed overflow in addition / subtraction / multiplication") }, + { "new-ra", &flag_new_regalloc, 1, + N_("Use graph coloring register allocation.") }, }; /* Table of language-specific options. */ @@ -1179,9 +1219,9 @@ documented_lang_options[] = used here is to only describe those options which are not enabled by default. */ - { "-ansi", - N_("Compile just for ISO C89") }, - { "-std= ", + { "-ansi", + N_("Compile just for ISO C90") }, + { "-std= ", N_("Determine language standard") }, { "-fsigned-bitfields", "" }, @@ -1189,98 +1229,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", "" }, { "-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", @@ -1289,48 +1334,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", + { "-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", "" }, @@ -1352,7 +1397,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. */ @@ -1363,7 +1408,7 @@ static const struct const char **const variable; const char *const description; } -target_options [] = TARGET_OPTIONS; +target_options[] = TARGET_OPTIONS; #endif /* Options controlling warnings. */ @@ -1404,10 +1449,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. */ @@ -1451,7 +1506,7 @@ int warn_disabled_optimization; int warn_missing_noreturn; -/* Nonzero means warn about uses of __attribute__((deprecated)) +/* Nonzero means warn about uses of __attribute__((deprecated)) declarations. */ int warn_deprecated_decl = 1; @@ -1477,7 +1532,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, @@ -1521,19 +1580,25 @@ set_Wunused (setting) -ffast-math and -fno-fast-math imply. */ void -set_fast_math_flags () +set_fast_math_flags (set) + 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_finite_math_only = set; + flag_errno_math = !set; + if (set) + flag_signaling_nans = 0; } -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_finite_math_only + && !flag_errno_math); } @@ -1574,19 +1639,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. */ @@ -1640,73 +1693,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. */ @@ -1714,7 +1700,7 @@ static void crash_signal (signo) int signo; { - internal_error ("internal error: %s", strsignal (signo)); + internal_error ("%s", strsignal (signo)); } /* Strip off a legitimate source ending from the input string NAME of @@ -1728,7 +1714,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] == '.') { @@ -1760,12 +1746,30 @@ output_quoted_string (asm_file, string) putc (c, asm_file); } else - fprintf (asm_file, "\\%03o", c); + 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 @@ -1780,7 +1784,7 @@ output_file_directive (asm_file, input_name) while (na > input_name) { if (IS_DIR_SEPARATOR (na[-1])) - break; + break; na--; } @@ -1843,8 +1847,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; @@ -1907,9 +1916,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 @@ -1950,16 +1958,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 @@ -2028,22 +2044,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); @@ -2072,7 +2085,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++; @@ -2109,13 +2121,13 @@ compile_file () /* Initialize yet another pass. */ init_final (main_input_filename); - init_branch_prob (dump_base_name); + init_branch_prob (aux_base_name); 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. */ @@ -2123,13 +2135,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 @@ -2183,7 +2194,7 @@ compile_file () dw2_output_indirect_constants (); - end_final (dump_base_name); + end_final (aux_base_name); if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) { @@ -2255,7 +2266,7 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) { alias = TREE_VALUE (TREE_VALUE (alias)); alias = get_identifier (TREE_STRING_POINTER (alias)); - assemble_alias (decl, alias); + assemble_alias (decl, alias); } } @@ -2267,7 +2278,7 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end) timevar_push (TV_VARCONST); if (asmspec) - make_decl_rtl (decl, 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. */ @@ -2346,7 +2357,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. @@ -2461,6 +2472,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; @@ -2494,7 +2506,7 @@ rest_of_compilation (decl) free_bb_for_insn (); } - current_function_nothrow = nothrow_function_p (); + set_nothrow_function_flags (); 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. */ @@ -2549,31 +2561,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); @@ -2585,6 +2625,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. @@ -2600,7 +2644,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 @@ -2624,12 +2671,14 @@ rest_of_compilation (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) | CLEANUP_PRE_LOOP); + 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 (); copy_loop_headers (insns); purge_line_number_notes (insns); + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); timevar_pop (TV_JUMP); close_dump_file (DFI_jump, print_rtl, insns); @@ -2650,7 +2699,6 @@ rest_of_compilation (decl) 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 (); @@ -2686,7 +2734,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); @@ -2705,29 +2753,21 @@ rest_of_compilation (decl) timevar_pop (TV_FROM_SSA); ggc_collect (); - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); } timevar_push (TV_JUMP); + cleanup_cfg (optimize ? CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP: 0); - if (optimize > 0) + /* Try to identify useless null pointer tests and delete them. */ + if (flag_delete_null_pointer_checks) { open_dump_file (DFI_null, decl); - find_basic_blocks (insns, max_reg_num (), rtl_dump_file); if (rtl_dump_file) dump_flow_info (rtl_dump_file); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - /* Try to identify useless null pointer tests and delete them. */ - if (flag_delete_null_pointer_checks) - delete_null_pointer_checks (insns); + if (delete_null_pointer_checks (insns)) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - timevar_push (TV_IFCVT); - if_convert (0); - timevar_pop (TV_IFCVT); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); close_dump_file (DFI_null, print_rtl_with_bb, insns); } @@ -2737,8 +2777,6 @@ 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 (get_max_uid ()); timevar_pop (TV_JUMP); close_dump_file (DFI_jump, print_rtl_with_bb, insns); @@ -2764,35 +2802,27 @@ rest_of_compilation (decl) 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) cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - - /* Run this after jump optmizations remove all the unreachable code - so that unreachable code will not keep values live. */ - delete_trivially_dead_insns (insns, max_reg_num (), 1); - /* Try to identify useless null pointer tests and delete them. */ - if (flag_delete_null_pointer_checks || flag_thread_jumps) + if (flag_delete_null_pointer_checks) { timevar_push (TV_JUMP); - 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. */ + if (delete_null_pointer_checks (insns)) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); timevar_pop (TV_JUMP); } /* The second pass of jump optimization is likely to have removed a bunch more instructions. */ renumber_insns (rtl_dump_file); - compute_bb_for_insn (get_max_uid ()); timevar_pop (TV_CSE); close_dump_file (DFI_cse, print_rtl_with_bb, insns); @@ -2819,9 +2849,9 @@ rest_of_compilation (decl) timevar_push (TV_GCSE); open_dump_file (DFI_gcse, decl); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); tem = gcse_main (insns, rtl_dump_file); rebuild_jump_labels (insns); + delete_trivially_dead_insns (insns, max_reg_num ()); save_csb = flag_cse_skip_blocks; save_cfj = flag_cse_follow_jumps; @@ -2835,6 +2865,7 @@ rest_of_compilation (decl) 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; } @@ -2846,7 +2877,6 @@ rest_of_compilation (decl) tem = tem2 = 0; timevar_push (TV_JUMP); rebuild_jump_labels (insns); - delete_trivially_dead_insns (insns, max_reg_num (), 1); cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); timevar_pop (TV_JUMP); @@ -2856,6 +2886,7 @@ rest_of_compilation (decl) 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); } } @@ -2873,41 +2904,45 @@ rest_of_compilation (decl) /* Move constant computations out of loops. */ - if (optimize > 0) + if (optimize > 0 && flag_loop_optimize) { + int do_unroll, do_prefetch; + timevar_push (TV_LOOP); delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); open_dump_file (DFI_loop, decl); /* CFG is no longer maintained up-to-date. */ free_bb_for_insn (); + do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL; + do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0; if (flag_rerun_loop_opt) { cleanup_barriers (); /* We only want to perform unrolling once. */ - - loop_optimize (insns, rtl_dump_file, 0); + loop_optimize (insns, rtl_dump_file, do_unroll); + do_unroll = 0; /* The first call to loop_optimize makes some instructions trivially dead. We delete those instructions now in the 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. */ reg_scan (insns, max_reg_num (), 1); } cleanup_barriers (); - loop_optimize (insns, rtl_dump_file, - (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT - | (flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0)); + loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch); /* Loop can create trivially dead instructions. */ - delete_trivially_dead_insns (insns, max_reg_num (), 0); + delete_trivially_dead_insns (insns, max_reg_num ()); close_dump_file (DFI_loop, print_rtl, insns); timevar_pop (TV_LOOP); + find_basic_blocks (insns, max_reg_num (), rtl_dump_file); ggc_collect (); } @@ -2917,8 +2952,6 @@ rest_of_compilation (decl) 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) @@ -2931,36 +2964,49 @@ rest_of_compilation (decl) life_analyzis rarely eliminates modification of external memory. */ - mark_constant_function (); + 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 || profile_arc_flag || flag_test_coverage - || flag_branch_probabilities) + if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities) { struct loops loops; timevar_push (TV_BRANCH_PROB); open_dump_file (DFI_bp, decl); - if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) + 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); + if (rtl_dump_file) + flow_loops_dump (&loops, rtl_dump_file, NULL, 0); + /* Estimate using heuristics if no profiling info is available. */ if (flag_guess_branch_prob) estimate_probability (&loops); - if (rtl_dump_file) - flow_loops_dump (&loops, rtl_dump_file, NULL, 0); - flow_loops_free (&loops); close_dump_file (DFI_bp, print_rtl_with_bb, insns); timevar_pop (TV_BRANCH_PROB); } + if (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) { @@ -2977,14 +3023,16 @@ rest_of_compilation (decl) timevar_push (TV_IFCVT); 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. */ 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) { @@ -3003,7 +3051,7 @@ rest_of_compilation (decl) cse_not_expected = 1; - close_dump_file (DFI_life, print_rtl_with_bb, insns); + open_dump_file (DFI_life, decl); regclass_init (); check_function_return_warnings (); @@ -3013,7 +3061,8 @@ rest_of_compilation (decl) #endif life_analysis (insns, rtl_dump_file, PROP_FINAL); if (optimize) - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); timevar_pop (TV_FLOW); no_new_pseudos = 1; @@ -3028,7 +3077,7 @@ rest_of_compilation (decl) if (optimize) { clear_bb_flags (); - if (initialize_uninitialized_subregs ()) + if (!flag_new_regalloc && initialize_uninitialized_subregs ()) { /* Insns were inserted, so things might look a bit different. */ insns = get_insns (); @@ -3054,10 +3103,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. */ @@ -3078,7 +3123,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); @@ -3167,60 +3212,101 @@ rest_of_compilation (decl) if (! register_life_up_to_date) recompute_reg_usage (insns, ! optimize_size); - /* Allocate the reg_renumber array. */ - allocate_reg_info (max_regno, FALSE, TRUE); + if (flag_new_regalloc) + { + delete_trivially_dead_insns (insns, max_reg_num ()); + reg_alloc (); - /* And the reg_equiv_memory_loc array. */ - reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx)); + timevar_pop (TV_LOCAL_ALLOC); + if (dump_file[DFI_lreg].enabled) + { + timevar_push (TV_DUMP); - allocate_initial_values (reg_equiv_memory_loc); + close_dump_file (DFI_lreg, NULL, NULL); + timevar_pop (TV_DUMP); + } - regclass (insns, max_reg_num (), rtl_dump_file); - rebuild_label_notes_after_reload = local_alloc (); + /* XXX clean up the whole mess to bring live info in shape again. */ + timevar_push (TV_GLOBAL_ALLOC); + open_dump_file (DFI_greg, decl); - timevar_pop (TV_LOCAL_ALLOC); + build_insn_chain (insns); + failure = reload (insns, 0); - if (dump_file[DFI_lreg].enabled) - { - timevar_push (TV_DUMP); + timevar_pop (TV_GLOBAL_ALLOC); - dump_flow_info (rtl_dump_file); - dump_local_alloc (rtl_dump_file); + if (dump_file[DFI_greg].enabled) + { + timevar_push (TV_DUMP); - close_dump_file (DFI_lreg, print_rtl_with_bb, insns); - timevar_pop (TV_DUMP); + dump_global_regs (rtl_dump_file); + + close_dump_file (DFI_greg, print_rtl_with_bb, insns); + timevar_pop (TV_DUMP); + } + + if (failure) + goto exit_rest_of_compilation; + reload_completed = 1; + rebuild_label_notes_after_reload = 0; } + else + { + /* Allocate the reg_renumber array. */ + allocate_reg_info (max_regno, FALSE, TRUE); - ggc_collect (); + /* And the reg_equiv_memory_loc array. */ + reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx)); - timevar_push (TV_GLOBAL_ALLOC); - open_dump_file (DFI_greg, decl); + allocate_initial_values (reg_equiv_memory_loc); - /* If optimizing, allocate remaining pseudo-regs. Do the reload - pass fixing up any insns that are invalid. */ + regclass (insns, max_reg_num (), rtl_dump_file); + rebuild_label_notes_after_reload = local_alloc (); - if (optimize) - failure = global_alloc (rtl_dump_file); - else - { - build_insn_chain (insns); - failure = reload (insns, 0); - } + timevar_pop (TV_LOCAL_ALLOC); - timevar_pop (TV_GLOBAL_ALLOC); + if (dump_file[DFI_lreg].enabled) + { + timevar_push (TV_DUMP); - if (dump_file[DFI_greg].enabled) - { - timevar_push (TV_DUMP); + dump_flow_info (rtl_dump_file); + dump_local_alloc (rtl_dump_file); - dump_global_regs (rtl_dump_file); + close_dump_file (DFI_lreg, print_rtl_with_bb, insns); + timevar_pop (TV_DUMP); + } - close_dump_file (DFI_greg, print_rtl_with_bb, insns); - timevar_pop (TV_DUMP); - } + ggc_collect (); - if (failure) - goto exit_rest_of_compilation; + timevar_push (TV_GLOBAL_ALLOC); + open_dump_file (DFI_greg, decl); + + /* If optimizing, allocate remaining pseudo-regs. Do the reload + pass fixing up any insns that are invalid. */ + + if (optimize) + failure = global_alloc (rtl_dump_file); + else + { + build_insn_chain (insns); + failure = reload (insns, 0); + } + + timevar_pop (TV_GLOBAL_ALLOC); + + if (dump_file[DFI_greg].enabled) + { + timevar_push (TV_DUMP); + + dump_global_regs (rtl_dump_file); + + close_dump_file (DFI_greg, print_rtl_with_bb, insns); + timevar_pop (TV_DUMP); + } + + if (failure) + goto exit_rest_of_compilation; + } ggc_collect (); @@ -3242,6 +3328,7 @@ rest_of_compilation (decl) timevar_push (TV_JUMP); rebuild_jump_labels (insns); + purge_all_dead_edges (0); timevar_pop (TV_JUMP); } @@ -3270,8 +3357,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 @@ -3303,21 +3391,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); @@ -3373,10 +3461,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 (); @@ -3438,7 +3528,7 @@ rest_of_compilation (decl) shorten_branches (get_insns ()); timevar_pop (TV_SHORTEN_BRANCH); - current_function_nothrow = nothrow_function_p (); + set_nothrow_function_flags (); 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. */ @@ -3527,10 +3617,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 (); @@ -3580,12 +3666,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)); } @@ -3595,9 +3682,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, " ", @@ -3612,7 +3699,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)); } @@ -3620,12 +3707,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\ @@ -3738,7 +3819,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)); } @@ -3757,7 +3838,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 @@ -3793,9 +3874,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; @@ -3803,7 +3884,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': @@ -3853,9 +3934,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="))) { @@ -3864,6 +3945,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); @@ -3901,7 +3995,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))); @@ -3909,10 +4003,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); } @@ -3987,7 +4081,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 @@ -4055,7 +4149,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 @@ -4207,7 +4301,9 @@ independent_decode_option (argc, argv) if (argc == 1) return 0; - dump_base_name = argv[1]; + if (argv[1][0]) + dump_base_name = argv[1]; + return 2; } else @@ -4280,6 +4376,30 @@ independent_decode_option (argc, argv) else return 0; } + else if (!strcmp (arg, "auxbase")) + { + if (argc == 1) + return 0; + + if (argv[1][0]) + aux_base_name = argv[1]; + + return 2; + } + else if (!strcmp (arg, "auxbase-strip")) + { + if (argc == 1) + return 0; + + if (argv[1][0]) + { + strip_off_ending (argv[1], strlen (argv[1])); + if (argv[1][0]) + aux_base_name = argv[1]; + } + + return 2; + } else return 0; break; @@ -4346,6 +4466,13 @@ set_target_switch (name) target_flags &= ~-target_switches[j].value; else target_flags |= target_switches[j].value; + if (name[0] != 0) + { + if (target_switches[j].value < 0) + target_flags_explicit |= -target_switches[j].value; + else + target_flags_explicit |= target_switches[j].value; + } valid_target_option = 1; } @@ -4511,25 +4638,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) @@ -4569,11 +4696,9 @@ general_init (argv0) xmalloc_set_program_name (progname); - gcc_init_libintl (); + hex_init (); - /* Install handler for SIGFPE, which may be received while we do - compile-time floating point arithmetic. */ - signal (SIGFPE, float_signal); + gcc_init_libintl (); /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ #ifdef SIGSEGV @@ -4591,16 +4716,27 @@ 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. */ diagnostic_initialize (global_dc); + + /* Initialize the garbage-collector, string pools and tree type hash + table. */ + init_ggc (); + init_stringpool (); + init_ttree (); } /* 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. */ + and identifier hashtables etc. are not initialized yet. + + Return non-zero to suppress compiler back end initialization. */ static void parse_options_and_default_flags (argc, argv) int argc; @@ -4671,6 +4807,10 @@ parse_options_and_default_flags (argc, argv) #endif flag_guess_branch_prob = 1; flag_cprop_registers = 1; + flag_loop_optimize = 1; + flag_crossjumping = 1; + flag_if_conversion = 1; + flag_if_conversion2 = 1; } if (optimize >= 2) @@ -4694,6 +4834,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) @@ -4708,6 +4849,15 @@ parse_options_and_default_flags (argc, argv) align_jumps = 1; align_labels = 1; align_functions = 1; + + /* Don't reorder blocks when optimizing for size because extra + jump insns may be created; also barrier may create extra padding. + + More correctly we should have a block reordering mode that tried + to minimize the combined size of all the jumps. This would more + or less automatically remove extra jumps, but would also try to + use more short jumps instead of long jumps. */ + flag_reorder_blocks = 0; } /* Initialize whether `char' is signed. */ @@ -4798,6 +4948,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 @@ -4817,9 +4972,8 @@ parse_options_and_default_flags (argc, argv) 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) (); + if (flag_really_no_inline == 2) + flag_really_no_inline = flag_no_inline; } /* Process the options that have been parsed. */ @@ -4877,16 +5031,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) { @@ -5003,30 +5147,19 @@ process_options () if (flag_function_sections && write_symbols != NO_DEBUG) warning ("-ffunction-sections may affect debugging on some targets"); #endif + + /* The presence of IEEE signaling NaNs, implies all math can trap. */ + if (flag_signaling_nans) + flag_trapping_math = 1; } -/* Language-independent initialization, before language-dependent - initialization. */ +/* Initialize the compiler back end. */ static void -lang_independent_init () +backend_init () { - decl_printable_name = decl_name; - lang_expand_expr = (lang_expand_expr_t) do_abort; - - /* Set the language-dependent identifier size. */ - tree_code_length[(int) IDENTIFIER_NODE] - = ((lang_hooks.identifier_size - sizeof (struct tree_common) - + sizeof (tree) - 1) / sizeof (tree)); - - /* Initialize the garbage-collector, and string pools. */ - init_ggc (); - ggc_add_rtx_root (&stack_limit_rtx, 1); - ggc_add_tree_root (¤t_function_decl, 1); - ggc_add_tree_root (¤t_function_func_begin_label, 1); - - init_stringpool (); - init_obstacks (); - + /* init_emit_once uses reg_raw_mode and therefore must be called + after init_regs which initialized reg_raw_mode. */ + init_regs (); init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE #ifdef VMS_DEBUGGING_INFO @@ -5035,21 +5168,17 @@ lang_independent_init () #endif || flag_test_coverage || warn_notreached); - init_regs (); + init_fake_stack_mems (); 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 (); @@ -5062,7 +5191,7 @@ lang_dependent_init (name) { 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 @@ -5081,6 +5210,12 @@ lang_dependent_init (name) init_eh (); init_optabs (); + /* The following initialization functions need to generate rtl, so + provide a dummy function context for them. */ + init_dummy_function_start (); + init_expr_once (); + expand_dummy_function_end (); + /* Put an entry on the input file stack for the main input file. */ push_srcloc (input_filename, 0); @@ -5163,17 +5298,37 @@ finalize () static void do_compile () { + /* All command line options have been parsed; allow the front end to + perform consistency checks, etc. */ + bool no_backend = (*lang_hooks.post_options) (); + /* The bulk of command line switch processing. */ process_options (); + /* If an error has already occurred, give up. */ + if (errorcount) + return; + + if (aux_base_name) + /*NOP*/; + else if (filename) + { + char *name = xstrdup (lbasename (filename)); + + aux_base_name = name; + strip_off_ending (name, strlen (name)); + } + else + aux_base_name = "gccaux"; + /* 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 (); + /* Set up the back-end if requested. */ + if (!no_backend) + backend_init (); /* Language-dependent initialization. Returns true on success. */ if (lang_dependent_init (filename)) @@ -5198,10 +5353,8 @@ toplev_main (argc, argv) int argc; char **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. */