X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftoplev.c;h=78e3afd93afede59f275bc25ac9324892203632b;hb=23a44cd6b52e8d9476559605340b77c8eb0a6f0f;hp=ff4c85049070f1023f3cf47c0541bdeb68ed1f52;hpb=c087e689da9b45056cd6f2df2ddded28e318d0d4;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/toplev.c b/gcc/toplev.c index ff4c8504907..78e3afd93af 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -117,17 +117,15 @@ static void crash_signal (int) ATTRIBUTE_NORETURN; static void setup_core_dumping (void); static void compile_file (void); -/* Nonzero to dump debug info whilst parsing (-dy option). */ -static int set_yydebug; - /* True if we don't need a backend (e.g. preprocessing only). */ static bool no_backend; /* Length of line when printing switch values. */ #define MAX_LINE 75 -/* Copy of argument vector to toplev_main. */ -static const char **save_argv; +/* Decoded options, and number of such options. */ +struct cl_decoded_option *save_decoded_options; +unsigned int save_decoded_options_count; /* Name of top-level original source file (what was input to cpp). This comes from the #-command at the beginning of the actual input. @@ -135,30 +133,19 @@ static const char **save_argv; const char *main_input_filename; +/* Pointer to base name in main_input_filename, with directories and a + single final extension removed, and the length of this base + name. */ +const char *main_input_basename; +int main_input_baselength; + /* Used to enable -fvar-tracking, -fweb and -frename-registers according to optimize in process_options (). */ #define AUTODETECT_VALUE 2 -/* Name to use as base of names for dump output files. */ - -const char *dump_base_name; - -/* Directory used for dump output files. */ - -const char *dump_dir_name; - -/* Name to use as a base for auxiliary output files. */ - -const char *aux_base_name; - /* Prefix for profile data files */ const char *profile_data_prefix; -/* A mask of target_flags that includes bit X if X was set or cleared - on the command line. */ - -int target_flags_explicit; - /* Debug hooks - dependent upon command line options. */ const struct gcc_debug_hooks *debug_hooks; @@ -169,26 +156,6 @@ int rtl_dump_and_exit; int flag_print_asm_name; enum graph_dump_types graph_dump_format; -/* Name for output file of assembly code, specified with -o. */ - -const char *asm_file_name; - -/* Nonzero means do optimizations. -O. - Particular numeric values stand for particular amounts of optimization; - thus, -O2 stores 2 here. However, the optimizations beyond the basic - ones are not controlled directly by this variable. Instead, they are - controlled by individual `flag_...' variables that are defaulted - based on this variable. */ - -int optimize = 0; - -/* Nonzero means optimize for size. -Os. - The only valid values are zero and nonzero. When optimize_size is - nonzero, optimize defaults to 2, but certain individual code - bloating optimizations are disabled. */ - -int optimize_size = 0; - /* True if this is the lto front end. This is used to disable gimple generation and lowering passes that are normally run on the output of a front end. These passes must be bypassed for lto since @@ -196,10 +163,6 @@ int optimize_size = 0; bool in_lto_p = false; -/* Nonzero if we should write GIMPLE bytecode for link-time optimization. */ - -int flag_generate_lto; - /* The FUNCTION_DECL for the function currently being compiled, or 0 if between functions. */ tree current_function_decl; @@ -208,10 +171,6 @@ tree current_function_decl; if none. */ const char * current_function_func_begin_label; -/* Nonzero means to collect statistics which might be expensive - and to print them when we are done. */ -int flag_detailed_statistics = 0; - /* A random sequence of characters, unless overridden by user. */ static const char *flag_random_seed; @@ -222,47 +181,6 @@ unsigned local_tick; /* -f flags. */ -/* Nonzero means `char' should be signed. */ - -int flag_signed_char; - -/* Nonzero means give an enum type only as many bytes as it needs. A value - of 2 means it has not yet been initialized. */ - -int flag_short_enums; - -/* Nonzero if structures and unions should be returned in memory. - - This should only be defined if compatibility with another compiler or - with an ABI is needed, because it results in slower code. */ - -#ifndef DEFAULT_PCC_STRUCT_RETURN -#define DEFAULT_PCC_STRUCT_RETURN 1 -#endif - -/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ - -int flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN; - -/* 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 multiply and divide. */ - -int flag_complex_method = 1; - -/* Nonzero means we should be saving declaration info into a .X file. */ - -int flag_gen_aux_info = 0; - -/* Specified name of aux-info file. */ - -const char *aux_info_file_name; - -/* Nonzero if we are compiling code for a shared library, zero for - executable. */ - -int flag_shlib; - /* Generate code for GNU or NeXT Objective-C runtime environment. */ #ifdef NEXT_OBJC_RUNTIME @@ -271,30 +189,6 @@ int flag_next_runtime = 1; int flag_next_runtime = 0; #endif -/* Set to the default thread-local storage (tls) model to use. */ - -enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; - -/* Set the default region and algorithm for the integrated register - allocator. */ - -enum ira_algorithm flag_ira_algorithm = IRA_ALGORITHM_CB; -enum ira_region flag_ira_region = IRA_REGION_MIXED; - -/* Set the default value for -fira-verbose. */ - -unsigned int flag_ira_verbose = 5; - -/* Set the default for excess precision. */ - -enum excess_precision flag_excess_precision_cmdline = EXCESS_PRECISION_DEFAULT; -enum excess_precision flag_excess_precision = EXCESS_PRECISION_DEFAULT; - -/* Nonzero means change certain warnings into errors. - Usually these are warnings about failure to conform to some standard. */ - -int flag_pedantic_errors = 0; - /* Nonzero means make permerror produce warnings instead of errors. */ int flag_permissive = 0; @@ -321,23 +215,6 @@ int flag_dump_rtl_in_asm = 0; the support provided depends on the backend. */ rtx stack_limit_rtx; -/* Positive if we should track variables, negative if we should run - the var-tracking pass only to discard debug annotations, zero if - we're not to run it. When flag_var_tracking == AUTODETECT_VALUE it - will be set according to optimize, debug_info_level and debug_hooks - in process_options (). */ -int flag_var_tracking = AUTODETECT_VALUE; - -/* Positive if we should track variables at assignments, negative if - we should run the var-tracking pass only to discard debug - annotations. When flag_var_tracking_assignments == - AUTODETECT_VALUE it will be set according to flag_var_tracking. */ -int flag_var_tracking_assignments = AUTODETECT_VALUE; - -/* Nonzero if we should toggle flag_var_tracking_assignments after - processing options and computing its default. */ -int flag_var_tracking_assignments_toggle = 0; - /* Type of stack check. */ enum stack_check_type flag_stack_check = NO_STACK_CHECK; @@ -346,18 +223,12 @@ enum stack_check_type flag_stack_check = NO_STACK_CHECK; bool user_defined_section_attribute = false; -/* Values of the -falign-* flags: how much to align labels in code. - 0 means `use default', 1 means `don't align'. - For each variable, there is an _log variant which is the power - of two not less than the variable, for .align output. */ - -int align_loops_log; -int align_loops_max_skip; -int align_jumps_log; -int align_jumps_max_skip; -int align_labels_log; -int align_labels_max_skip; -int align_functions_log; +struct target_flag_state default_target_flag_state; +#if SWITCHABLE_TARGET +struct target_flag_state *this_target_flag_state = &default_target_flag_state; +#else +#define this_target_flag_state (&default_target_flag_state) +#endif typedef struct { @@ -367,18 +238,15 @@ typedef struct } lang_independent_options; -/* Nonzero if subexpressions must be evaluated from left-to-right. */ -int flag_evaluation_order = 0; - /* The user symbol prefix after having resolved same. */ const char *user_label_prefix; static const param_info lang_independent_params[] = { #define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \ - { OPTION, DEFAULT, false, MIN, MAX, HELP }, + { OPTION, DEFAULT, MIN, MAX, HELP }, #include "params.def" #undef DEFPARAM - { NULL, 0, false, 0, 0, NULL } + { NULL, 0, 0, 0, NULL } }; /* Output files for assembler code (real compiler output) @@ -386,6 +254,7 @@ static const param_info lang_independent_params[] = { FILE *asm_out_file; FILE *aux_info_file; +FILE *stack_usage_file = NULL; FILE *dump_file = NULL; const char *dump_file_name; @@ -518,39 +387,11 @@ set_random_seed (const char *val) return old; } -/* Decode the string P as an integral parameter. - If the string is indeed an integer return its numeric value else - issue an Invalid Option error for the option PNAME and return DEFVAL. - If PNAME is zero just return DEFVAL, do not call error. */ - -int -read_integral_parameter (const char *p, const char *pname, const int defval) -{ - const char *endp = p; - - while (*endp) - { - if (ISDIGIT (*endp)) - endp++; - else - break; - } - - if (*endp != 0) - { - if (pname != 0) - error ("invalid option argument %qs", pname); - return defval; - } - - return atoi (p); -} - #if GCC_VERSION < 3004 -/* The functions floor_log2 and exact_log2 are defined as inline - functions in toplev.h if GCC_VERSION >= 3004. The definitions here - are used for older versions of gcc. */ +/* The functions clz_hwi, ctz_hwi, ffs_hwi, floor_log2 and exact_log2 + are defined as inline functions in toplev.h if GCC_VERSION >= 3004. + The definitions here are used for older versions of gcc. */ /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. If X is 0, return -1. */ @@ -594,6 +435,32 @@ exact_log2 (unsigned HOST_WIDE_INT x) return floor_log2 (x); } +/* Given X, an unsigned number, return the number of least significant bits + that are zero. When X == 0, the result is the word size. */ + +int +ctz_hwi (unsigned HOST_WIDE_INT x) +{ + return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT; +} + +/* Similarly for most significant bits. */ + +int +clz_hwi (unsigned HOST_WIDE_INT x) +{ + return HOST_BITS_PER_WIDE_INT - 1 - floor_log2(x); +} + +/* Similar to ctz_hwi, except that the least significant bit is numbered + starting from 1, and X == 0 yields 0. */ + +int +ffs_hwi (unsigned HOST_WIDE_INT x) +{ + return 1 + floor_log2 (x & -x); +} + #endif /* GCC_VERSION < 3004 */ /* Handler for fatal signals, such as SIGSEGV. These are transformed @@ -684,39 +551,6 @@ output_quoted_string (FILE *asm_file, const char *string) #endif } -/* Output a file name in the form wanted by System V. */ - -void -output_file_directive (FILE *asm_file, const char *input_name) -{ - int len; - const char *na; - - if (input_name == NULL) - input_name = ""; - else - input_name = remap_debug_filename (input_name); - - len = strlen (input_name); - na = input_name + len; - - /* NA gets INPUT_NAME sans directory names. */ - while (na > input_name) - { - if (IS_DIR_SEPARATOR (na[-1])) - break; - na--; - } - -#ifdef ASM_OUTPUT_SOURCE_FILENAME - ASM_OUTPUT_SOURCE_FILENAME (asm_file, na); -#else - fprintf (asm_file, "\t.file\t"); - output_quoted_string (asm_file, na); - putc ('\n', asm_file); -#endif -} - /* A subroutine of wrapup_global_declarations. We've come to the end of the compilation unit. All deferred variables should be undeferred, and all incomplete decls should be finalized. */ @@ -1039,7 +873,7 @@ compile_file (void) /* Call the parser, which parses the entire file (calling rest_of_compilation for each function). */ - lang_hooks.parse_file (set_yydebug); + lang_hooks.parse_file (); /* Compilation is now finished except for writing what's left of the symbol table output. */ @@ -1056,11 +890,6 @@ compile_file (void) if (seen_error ()) return; - /* Ensure that emulated TLS control vars are finalized and build - a static constructor for them, when it is required. */ - if (!targetm.have_tls) - emutls_finish (); - varpool_assemble_pending_decls (); finish_aliases_2 (); @@ -1167,9 +996,6 @@ decode_d_option (const char *arg) case 'x': rtl_dump_and_exit = 1; break; - case 'y': - set_yydebug = 1; - break; case 'D': /* These are handled by the preprocessor. */ case 'I': case 'M': @@ -1368,7 +1194,6 @@ print_switch_values (print_switch_fn_type print_fn) { int pos = 0; size_t j; - const char **p; /* Fill in the -frandom-seed option, if the user didn't pass it, so that it can be printed below. This helps reproducibility. */ @@ -1379,30 +1204,23 @@ print_switch_values (print_switch_fn_type print_fn) pos = print_single_switch (print_fn, pos, SWITCH_TYPE_DESCRIPTIVE, _("options passed: ")); - for (p = &save_argv[1]; *p != NULL; p++) + for (j = 1; j < save_decoded_options_count; j++) { - if (**p == '-') + switch (save_decoded_options[j].opt_index) { + case OPT_o: + case OPT_d: + case OPT_dumpbase: + case OPT_dumpdir: + case OPT_auxbase: + case OPT_quiet: + case OPT_version: /* Ignore these. */ - if (strcmp (*p, "-o") == 0 - || strcmp (*p, "-dumpbase") == 0 - || strcmp (*p, "-dumpdir") == 0 - || strcmp (*p, "-auxbase") == 0) - { - if (p[1] != NULL) - p++; - continue; - } - - if (strcmp (*p, "-quiet") == 0 - || strcmp (*p, "-version") == 0) - continue; - - if ((*p)[1] == 'd') - continue; + continue; } - pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED, *p); + pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED, + save_decoded_options[j].orig_option_with_args_text); } if (pos > 0) @@ -1416,7 +1234,7 @@ print_switch_values (print_switch_fn_type print_fn) for (j = 0; j < cl_options_count; j++) if ((cl_options[j].flags & CL_REPORT) - && option_enabled (j) > 0) + && option_enabled (j, &global_options) > 0) pos = print_single_switch (print_fn, pos, SWITCH_TYPE_ENABLED, cl_options[j].opt_text); @@ -1495,10 +1313,10 @@ option_affects_pch_p (int option, struct cl_option_state *state) { if ((cl_options[option].flags & CL_TARGET) == 0) return false; - if (cl_options[option].flag_var == &target_flags) + if (option_flag_var (option, &global_options) == &target_flags) if (targetm.check_pch_target_flags) return false; - return get_option_state (option, state); + return get_option_state (&global_options, option, state); } /* Default version of get_pch_validity. @@ -1657,7 +1475,7 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec, static void * realloc_for_line_map (void *ptr, size_t len) { - return ggc_realloc (ptr, len); + return GGC_RESIZEVAR (void, ptr, len); } /* A helper function: used as the allocator function for @@ -1665,7 +1483,89 @@ realloc_for_line_map (void *ptr, size_t len) static void * alloc_for_identifier_to_locale (size_t len) { - return ggc_alloc (len); + return ggc_alloc_atomic (len); +} + +/* Output stack usage information. */ +void +output_stack_usage (void) +{ + static bool warning_issued = false; + enum stack_usage_kind_type { STATIC = 0, DYNAMIC, DYNAMIC_BOUNDED }; + const char *stack_usage_kind_str[] = { + "static", + "dynamic", + "dynamic,bounded" + }; + HOST_WIDE_INT stack_usage = current_function_static_stack_size; + enum stack_usage_kind_type stack_usage_kind; + expanded_location loc; + const char *raw_id, *id; + + if (stack_usage < 0) + { + if (!warning_issued) + { + warning (0, "-fstack-usage not supported for this target"); + warning_issued = true; + } + return; + } + + stack_usage_kind = STATIC; + + /* Add the maximum amount of space pushed onto the stack. */ + if (current_function_pushed_stack_size > 0) + { + stack_usage += current_function_pushed_stack_size; + stack_usage_kind = DYNAMIC_BOUNDED; + } + + /* Now on to the tricky part: dynamic stack allocation. */ + if (current_function_allocates_dynamic_stack_space) + { + if (current_function_has_unbounded_dynamic_stack_size) + stack_usage_kind = DYNAMIC; + else + stack_usage_kind = DYNAMIC_BOUNDED; + + /* Add the size even in the unbounded case, this can't hurt. */ + stack_usage += current_function_dynamic_stack_size; + } + + loc = expand_location (DECL_SOURCE_LOCATION (current_function_decl)); + + /* Strip the scope prefix if any. */ + raw_id = lang_hooks.decl_printable_name (current_function_decl, 2); + id = strrchr (raw_id, '.'); + if (id) + id++; + else + id = raw_id; + + fprintf (stack_usage_file, + "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n", + lbasename (loc.file), + loc.line, + loc.column, + id, + stack_usage, + stack_usage_kind_str[stack_usage_kind]); +} + +/* Open an auxiliary output file. */ +static FILE * +open_auxiliary_file (const char *ext) +{ + char *filename; + FILE *file; + + filename = concat (aux_base_name, ".", ext, NULL); + file = fopen (filename, "w"); + if (!file) + fatal_error ("can%'t open %s for writing: %m", filename); + free (filename); + return file; } /* Initialization of the front end environment, before command line @@ -1700,10 +1600,13 @@ general_init (const char *argv0) /* Set a default printer. Language specific initializations will override it later. */ pp_format_decoder (global_dc->printer) = &default_tree_printer; - global_dc->show_option_requested = flag_diagnostics_show_option; - global_dc->show_column = flag_show_column; + global_dc->show_option_requested + = global_options_init.x_flag_diagnostics_show_option; + global_dc->show_column + = global_options_init.x_flag_show_column; global_dc->internal_error = plugins_internal_error_function; global_dc->option_enabled = option_enabled; + global_dc->option_state = &global_options; global_dc->option_name = option_name; /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ @@ -1733,7 +1636,7 @@ general_init (const char *argv0) table. */ init_ggc (); init_stringpool (); - line_table = GGC_NEW (struct line_maps); + line_table = ggc_alloc_line_maps (); linemap_init (line_table); line_table->reallocator = realloc_for_line_map; init_ttree (); @@ -1743,11 +1646,13 @@ general_init (const char *argv0) /* Register the language-independent parameters. */ add_params (lang_independent_params, LAST_PARAM); + targetm.target_option.default_params (); /* This must be done after add_params but before argument processing. */ init_ggc_heuristics(); init_optimization_passes (); statistics_early_init (); + finish_params (); } /* Return true if the current target supports -fsection-anchors. */ @@ -1826,10 +1731,8 @@ process_options (void) so we can correctly initialize debug output. */ no_backend = lang_hooks.post_options (&main_input_filename); -#ifdef OVERRIDE_OPTIONS /* Some machines may reject certain combinations of options. */ - OVERRIDE_OPTIONS; -#endif + targetm.target_option.override (); /* Avoid any informative notes in the second run of -fcompare-debug. */ if (flag_compare_debug) @@ -1873,11 +1776,7 @@ process_options (void) if (flag_unroll_all_loops) flag_unroll_loops = 1; - /* The loop unrolling code assumes that cse will be run after loop. - web and rename-registers also help when run after loop unrolling. */ - if (flag_rerun_cse_after_loop == AUTODETECT_VALUE) - flag_rerun_cse_after_loop = flag_unroll_loops || flag_peel_loops; - + /* web and rename-registers help when run after loop unrolling. */ if (flag_web == AUTODETECT_VALUE) flag_web = flag_unroll_loops || flag_peel_loops; @@ -2017,6 +1916,12 @@ process_options (void) flag_var_tracking_uninit = 0; } + /* The debug hooks are used to implement -fdump-go-spec because it + gives a simple and stable API for all the information we need to + dump. */ + if (flag_dump_go_spec != NULL) + debug_hooks = dump_go_spec_init (flag_dump_go_spec, debug_hooks); + /* If the user specifically requested variable tracking with tagging uninitialized variables, we need to turn on variable tracking. (We already determined above that variable tracking is feasible.) */ @@ -2078,13 +1983,13 @@ process_options (void) } #ifndef HAVE_prefetch - if (flag_prefetch_loop_arrays) + if (flag_prefetch_loop_arrays > 0) { warning (0, "-fprefetch-loop-arrays not supported for this target"); flag_prefetch_loop_arrays = 0; } #else - if (flag_prefetch_loop_arrays && !HAVE_prefetch) + if (flag_prefetch_loop_arrays > 0 && !HAVE_prefetch) { warning (0, "-fprefetch-loop-arrays not supported for this target (try -march switches)"); flag_prefetch_loop_arrays = 0; @@ -2093,7 +1998,7 @@ process_options (void) /* 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) + if (flag_prefetch_loop_arrays > 0 && optimize_size) { warning (0, "-fprefetch-loop-arrays is not supported with -Os"); flag_prefetch_loop_arrays = 0; @@ -2285,6 +2190,10 @@ lang_dependent_init (const char *name) init_asm_output (name); + /* If stack usage information is desired, open the output file. */ + if (flag_stack_usage) + stack_usage_file = open_auxiliary_file ("su"); + /* This creates various _DECL nodes, so needs to be called after the front end is initialized. */ init_eh (); @@ -2366,6 +2275,9 @@ finalize (void) unlink_if_ordinary (asm_file_name); } + if (stack_usage_file) + fclose (stack_usage_file); + statistics_fini (); finish_optimization_passes (); @@ -2425,14 +2337,35 @@ toplev_main (int argc, char **argv) { expandargv (&argc, &argv); - save_argv = CONST_CAST2 (const char **, char **, argv); - /* Initialization of GCC's environment, and diagnostics. */ general_init (argv[0]); + /* One-off initialization of options that does not need to be + repeated when options are added for particular functions. */ + init_options_once (); + + /* Initialize global options structures; this must be repeated for + each structure used for parsing options. */ + init_options_struct (&global_options, &global_options_set); + lang_hooks.init_options_struct (&global_options); + + /* Convert the options to an array. */ + decode_cmdline_options_to_array_default_mask (argc, + CONST_CAST2 (const char **, + char **, argv), + &save_decoded_options, + &save_decoded_options_count); + + /* Perform language-specific options initialization. */ + lang_hooks.init_options (save_decoded_options_count, save_decoded_options); + /* Parse the options and do minimal processing; basically just enough to default flags appropriately. */ - decode_options (argc, CONST_CAST2 (const char **, char **, argv)); + decode_options (&global_options, &global_options_set, + save_decoded_options, save_decoded_options_count, + UNKNOWN_LOCATION, global_dc); + + handle_common_deferred_options (); init_local_tick ();