/* Top level of GNU C compiler
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
#undef FLOAT /* This is for hpux. They should change hpux. */
#undef FFS /* Some systems define this in param.h. */
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
#include "target.h"
#include "langhooks.h"
#include "cfglayout.h"
+#include "cfgloop.h"
+#include "hosthooks.h"
+#include "cgraph.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
static void set_target_switch PARAMS ((const char *));
static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void setup_core_dumping PARAMS ((void));
static void compile_file PARAMS ((void));
static void display_help PARAMS ((void));
static void display_target_options PARAMS ((void));
static int decode_W_option PARAMS ((const char *));
static int decode_g_option PARAMS ((const char *));
static unsigned int independent_decode_option PARAMS ((int, char **));
+static void set_Wextra PARAMS ((int));
static void print_version PARAMS ((FILE *, const char *));
static int print_single_switch PARAMS ((FILE *, int, int, const char *,
/* 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
int save_argc;
char **save_argv;
\f
-/* Name of current original source file (what was input to cpp).
- This comes from each #-command in the actual input. */
-
-const char *input_filename;
-
/* Name of top-level original source file (what was input to cpp).
This comes from the #-command at the beginning of the actual input.
If there isn't any there, then this is the cc1 input file name. */
const char *main_input_filename;
-/* Current line number in real source file. */
+/* Current position in real source file. */
-int lineno;
+location_t input_location;
/* Nonzero if it is unsafe to create any new pseudo registers. */
int no_new_pseudos;
/* Name to use as a base for auxiliary output files. */
-const char *aux_base_name;
+static const char *aux_base_name;
/* Format to use to print dumpfile index value */
#ifndef DUMPFILE_FORMAT
DFI_addressof,
DFI_gcse,
DFI_loop,
+ DFI_bypass,
DFI_cfg,
DFI_bp,
+ DFI_ce1,
DFI_tracer,
+ DFI_loop2,
DFI_cse2,
DFI_life,
DFI_combine,
- DFI_ce,
+ DFI_ce2,
DFI_regmove,
DFI_sched,
DFI_lreg,
DFI_flow2,
DFI_peephole2,
DFI_rnreg,
- DFI_ce2,
+ DFI_bbro,
+ DFI_ce3,
DFI_sched2,
DFI_stack,
- DFI_bbro,
DFI_mach,
DFI_dbr,
DFI_MAX
{ "addressof", 'F', 0, 0, 0 },
{ "gcse", 'G', 1, 0, 0 },
{ "loop", 'L', 1, 0, 0 },
+ { "bypass", 'G', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "cfg", 'f', 1, 0, 0 },
{ "bp", 'b', 1, 0, 0 },
+ { "ce1", 'C', 1, 0, 0 },
{ "tracer", 'T', 1, 0, 0 },
+ { "loop2", 'L', 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 },
+ { "ce2", 'C', 1, 0, 0 },
{ "regmove", 'N', 1, 0, 0 },
{ "sched", 'S', 1, 0, 0 },
{ "lreg", 'l', 1, 0, 0 },
{ "flow2", 'w', 1, 0, 0 },
{ "peephole2", 'z', 1, 0, 0 },
{ "rnreg", 'n', 1, 0, 0 },
- { "ce2", 'E', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
+ { "ce3", 'E', 1, 0, 0 },
{ "sched2", 'R', 1, 0, 0 },
{ "stack", 'k', 1, 0, 0 },
- { "bbro", 'B', 1, 0, 0 },
{ "mach", 'M', 1, 0, 0 },
{ "dbr", 'd', 0, 0, 0 },
};
int rtl_dump_and_exit;
int flag_print_asm_name;
static int version_flag;
-static char *filename;
+static const char *filename;
enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
char *asm_file_name;
/* Value of the -G xx switch, and whether it was passed or not. */
-int g_switch_value;
+unsigned HOST_WIDE_INT g_switch_value;
int g_switch_set;
/* Type(s) of debugging information we are producing (if any).
int flag_eliminate_dwarf2_dups = 0;
+/* Nonzero if doing unused type elimination. */
+
+int flag_eliminate_unused_debug_types = 1;
+
/* Nonzero if generating code to do profiling. */
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;
/* Print times taken by the various passes. -ftime-report. */
-int time_report = 0;
+static int time_report = 0;
/* Print memory still in use at end of compilation (which may have little
to do with peak memory consumption). -fmem-report. */
int mem_report = 0;
-/* Non-zero means to collect statistics which might be expensive
+/* Nonzero means to collect statistics which might be expensive
and to print them when we are done. */
int flag_detailed_statistics = 0;
UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
unrolled. */
-int flag_unroll_loops;
+int flag_old_unroll_loops;
/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled.
This is generally not a win. */
+int flag_old_unroll_all_loops;
+
+/* Enables unrolling of simple loops in loop-unroll.c. */
+int flag_unroll_loops;
+
+/* Enables unrolling of all loops in loop-unroll.c. */
int flag_unroll_all_loops;
+/* Nonzero enables loop peeling. */
+int flag_peel_loops;
+
+/* Nonzero enables loop unswitching. */
+int flag_unswitch_loops;
+
/* Nonzero enables prefetch optimizations for arrays in loops. */
int flag_prefetch_loop_arrays;
/* Zero means that floating-point math operations cannot generate a
(user-visible) trap. This is the case, for example, in nonstop
IEEE 754 arithmetic. Trapping conditions include division by zero,
- overflow, underflow, invalid and inexact, but does not include
+ overflow, underflow, invalid and inexact, but does not include
operations on signaling NaNs (see below). */
int flag_trapping_math = 1;
int flag_complex_divide_method = 0;
-/* Nonzero means all references through pointers are volatile. */
-
-int flag_volatile;
-
-/* Nonzero means treat all global and extern variables as volatile. */
-
-int flag_volatile_global;
-
-/* Nonzero means treat all static variables as volatile. */
-
-int flag_volatile_static;
-
/* Nonzero means just do syntax checking; don't output anything. */
int flag_syntax_only = 0;
-/* Nonzero means perform global cse. */
-
-static int flag_gcse;
-
/* Nonzero means perform loop optimizer. */
static int flag_loop_optimize;
static int flag_delete_null_pointer_checks;
+/* Nonzero means perform global CSE. */
+
+int flag_gcse = 0;
+
/* Nonzero means to do the enhanced load motion during gcse, which trys
to hoist loads by not killing them when a store to the same location
is seen. */
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
+/* When flag_schedule_insns_after_reload is set, use EBB scheduler. */
+int flag_sched2_use_superblocks = 0;
+
+/* When flag_schedule_insns_after_reload is set, construct traces and EBB
+ scheduler. */
+int flag_sched2_use_traces = 0;
+
/* The following flags have effect only for scheduling before register
allocation:
- flag_schedule_interblock means schedule insns accross basic blocks.
+ flag_schedule_interblock means schedule insns across basic blocks.
flag_schedule_speculative means allow speculative motion of non-load insns.
flag_schedule_speculative_load means allow speculative motion of some
load insns.
/* This will try to guess branch probabilities. */
int flag_guess_branch_prob = 0;
-/* -fbounded-pointers causes gcc to compile pointers as composite
- objects occupying three words: the pointer value, the base address
- of the referent object, and the address immediately beyond the end
- of the referent object. The base and extent allow us to perform
- runtime bounds checking. -fbounded-pointers implies -fcheck-bounds. */
-int flag_bounded_pointers = 0;
-
/* -fcheck-bounds causes gcc to generate array bounds checks.
- For C, C++: defaults to value of flag_bounded_pointers.
- For ObjC: defaults to off.
+ For C, C++, ObjC: defaults to off.
For Java: defaults to on.
- For Fortran: defaults to off.
- For CHILL: defaults to off. */
+ For Fortran: defaults to off. */
int flag_bounds_check = 0;
/* This will attempt to merge constant section constants, if 1 only
int flag_tracer = 0;
+/* Nonzero if we perform whole unit at a time compilation. */
+
+int flag_unit_at_a_time = 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
{
{"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
N_("Perform DWARF2 duplicate elimination") },
+ {"eliminate-unused-debug-types", &flag_eliminate_unused_debug_types, 1,
+ N_("Perform unused type elimination in debug info") },
{"float-store", &flag_float_store, 1,
N_("Do not store floats in registers") },
- {"volatile", &flag_volatile, 1,
- N_("Consider all mem refs through pointers as volatile") },
- {"volatile-global", &flag_volatile_global, 1,
- N_("Consider all mem refs to global data to be volatile") },
- {"volatile-static", &flag_volatile_static, 1,
- N_("Consider all mem refs to static data to be volatile") },
{"defer-pop", &flag_defer_pop, 1,
N_("Defer popping functions args from stack until later") },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
N_("Optimize sibling and tail recursive calls") },
{"tracer", &flag_tracer, 1,
N_("Perform superblock formation via tail duplication") },
+ {"unit-at-a-time", &flag_unit_at_a_time, 1,
+ N_("Compile whole compilation unit at a time") },
{"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,
N_("Perform loop unrolling when iteration count is known") },
{"unroll-all-loops", &flag_unroll_all_loops, 1,
N_("Perform loop unrolling for all loops") },
+ {"old-unroll-loops", &flag_old_unroll_loops, 1,
+ N_("Perform loop unrolling when iteration count is known") },
+ {"old-unroll-all-loops", &flag_old_unroll_all_loops, 1,
+ N_("Perform loop unrolling for all loops") },
+ {"peel-loops", &flag_peel_loops, 1,
+ N_("Perform loop peeling") },
+ {"unswitch-loops", &flag_unswitch_loops, 1,
+ N_("Perform loop unswitching") },
{"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
N_("Generate prefetch instructions, if available, for arrays in loops") },
{"move-all-movables", &flag_move_all_movables, 1,
N_("Allow speculative motion of some loads") },
{"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
N_("Allow speculative motion of more loads") },
+ {"sched2-use-superblocks", &flag_sched2_use_superblocks, 1,
+ N_("If scheduling post reload, do superblock scheduling") },
+ {"sched2-use-traces", &flag_sched2_use_traces, 1,
+ N_("If scheduling post reload, do trace scheduling") },
{"branch-count-reg",&flag_branch_on_count_reg, 1,
N_("Replace add,compare,branch with branch on count reg") },
{"pic", &flag_pic, 1,
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,
{"data-sections", &flag_data_sections, 1,
N_("place data items into their own section") },
{"verbose-asm", &flag_verbose_asm, 1,
- N_("Add extra commentry to assembler output") },
+ N_("Add extra commentary to assembler output") },
{"gnu-linker", &flag_gnu_linker, 1,
N_("Output GNU ld formatted global initializers") },
{"regmove", &flag_regmove, 1,
{"align-functions", &align_functions, 0,
N_("Align the start of functions") },
{"merge-constants", &flag_merge_constants, 1,
- N_("Attempt to merge identical constants accross compilation units") },
+ N_("Attempt to merge identical constants across compilation units") },
{"merge-all-constants", &flag_merge_constants, 2,
N_("Attempt to merge identical constants and constant variables") },
{"dump-unnumbered", &flag_dump_unnumbered, 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,
- N_("Generate code to check bounds before dereferencing pointers and arrays") },
+ N_("Generate code to check bounds before indexing arrays") },
{"single-precision-constant", &flag_single_precision_constant, 1,
N_("Convert floating point constant to single precision constant") },
{"time-report", &time_report, 1,
{ "-Wimport",
N_("Warn about the use of the #import directive") },
{ "-Wno-import", "" },
+ { "-Winvalid-pch",
+ N_("Warn about PCH files that are found but not used") },
{ "-Wlong-long","" },
{ "-Wno-long-long",
N_("Do not warn about using 'long long' when -pedantic") },
const char *const prefix;
const char **const variable;
const char *const description;
+ const char *const value;
}
target_options[] = TARGET_OPTIONS;
#endif
int warn_system_headers = 0;
-/* Print various extra warnings. -W. */
+/* Print various extra warnings. -W/-Wextra. */
int extra_warnings = 0;
int warn_unused_variable;
int warn_unused_value;
+/* Used for cooperation between set_Wunused and set_Wextra. */
+static int maybe_warn_unused_parameter;
+
/* Nonzero to warn about code which is never reached. */
int warn_notreached;
int warn_deprecated_decl = 1;
-/* Likewise for -W. */
+/* Nonzero means warn about constructs which might not be
+ strict-aliasing safe. */
+
+int warn_strict_aliasing;
+
+/* Like f_options, but for -W. */
static const lang_independent_options W_options[] =
{
{"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") }
+ N_("Warn about functions which might be candidates for attribute noreturn") },
+ {"strict-aliasing", &warn_strict_aliasing, 1,
+ N_ ("Warn about code which might break the strict aliasing rules") }
};
void
{
warn_unused_function = setting;
warn_unused_label = setting;
- /* Unused function parameter warnings are reported when either ``-W
- -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate
- -Wunused by setting WARN_UNUSED_PARAMETER to -1. */
- if (!setting)
- warn_unused_parameter = 0;
- else if (!warn_unused_parameter)
- warn_unused_parameter = -1;
+ /* Unused function parameter warnings are reported when either
+ ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
+ Thus, if -Wextra has already been seen, set warn_unused_parameter;
+ otherwise set maybe_warn_extra_parameter, which will be picked up
+ by set_Wextra. */
+ maybe_warn_unused_parameter = setting;
+ warn_unused_parameter = (setting && extra_warnings);
warn_unused_variable = setting;
warn_unused_value = setting;
}
+static void
+set_Wextra (setting)
+ int setting;
+{
+ extra_warnings = setting;
+ warn_unused_value = setting;
+ warn_unused_parameter = (setting && maybe_warn_unused_parameter);
+
+ /* We save the value of warn_uninitialized, since if they put
+ -Wuninitialized on the command line, we need to generate a
+ warning about not using it without also specifying -O. */
+ if (setting == 0)
+ warn_uninitialized = 0;
+ else if (warn_uninitialized != 1)
+ warn_uninitialized = 2;
+}
+
/* The following routines are useful in setting all the flags that
-ffast-math and -fno-fast-math imply. */
if (*endp != 0)
{
if (pname != 0)
- error ("invalid option `%s'", pname);
+ error ("invalid option argument `%s'", pname);
return defval;
}
internal_error ("%s", strsignal (signo));
}
+/* Arrange to dump core on error. (The regular error message is still
+ printed first, except in the case of abort().) */
+
+static void
+setup_core_dumping ()
+{
+#ifdef SIGABRT
+ signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(HAVE_SETRLIMIT)
+ {
+ struct rlimit rlim;
+ if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+ fatal_error ("getting core file size maximum limit: %m");
+ rlim.rlim_cur = rlim.rlim_max;
+ if (setrlimit (RLIMIT_CORE, &rlim) != 0)
+ fatal_error ("setting core file size limit to maximum: %m");
+ }
+#endif
+ diagnostic_abort_on_error (global_dc);
+}
+
+
/* Strip off a legitimate source ending from the input string NAME of
length LEN. Rather than having to know the names used by all of
our front ends, we strip off an ending of a period followed by
rtl_dump_file = fopen (dump_name, open_arg);
if (rtl_dump_file == NULL)
- fatal_io_error ("can't open %s", dump_name);
+ fatal_error ("can't open %s: %m", dump_name);
free (dump_name);
{
decl = vec[i];
- /* We're not deferring this any longer. */
- DECL_DEFER_OUTPUT (decl) = 0;
+ /* We're not deferring this any longer. Assignment is
+ conditional to avoid needlessly dirtying PCH pages. */
+ if (DECL_DEFER_OUTPUT (decl) != 0)
+ DECL_DEFER_OUTPUT (decl) = 0;
if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
(*lang_hooks.finish_incomplete_decl) (decl);
&& ! TREE_USED (DECL_NAME (decl))
&& ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
+ /* A volatile variable might be used in some non-obvious way. */
+ && ! TREE_THIS_VOLATILE (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);
- (*debug_hooks->global_decl) (decl);
- timevar_pop (TV_SYMOUT);
+ /* Avoid confusing the debug information machinery when there are
+ errors. */
+ if (errorcount == 0 && sorrycount == 0)
+ {
+ timevar_push (TV_SYMOUT);
+ (*debug_hooks->global_decl) (decl);
+ timevar_pop (TV_SYMOUT);
+ }
}
}
-/* Save the current INPUT_FILENAME and LINENO on the top entry in the
+/* Save the current INPUT_LOCATION on the top entry in the
INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the
- INPUT_FILENAME and LINENO accordingly. */
+ INPUT_LOCATION accordingly. */
void
push_srcloc (file, line)
struct file_stack *fs;
if (input_file_stack)
- {
- input_file_stack->name = input_filename;
- input_file_stack->line = lineno;
- }
+ input_file_stack->location = input_location;
fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
- fs->name = input_filename = file;
- fs->line = lineno = line;
+ input_filename = file;
+ input_line = line;
+ fs->location = input_location;
fs->next = input_file_stack;
input_file_stack = fs;
input_file_stack_tick++;
}
/* Pop the top entry off the stack of presently open source files.
- Restore the INPUT_FILENAME and LINENO from the new topmost entry on
- the stack. */
+ Restore the INPUT_LOCATION from the new topmost entry on the
+ stack. */
void
pop_srcloc ()
input_file_stack = fs->next;
free (fs);
input_file_stack_tick++;
- /* The initial source file is never popped. */
- if (!input_file_stack)
- abort ();
- input_filename = input_file_stack->name;
- lineno = input_file_stack->line;
+
+ if (input_file_stack)
+ input_location = input_file_stack->location;
+ else
+ {
+ input_filename = NULL;
+ input_line = 0;
+ }
}
/* Compile an entire translation unit. Write a file of assembly
static void
compile_file ()
{
- tree globals;
-
/* Initialize yet another pass. */
init_final (main_input_filename);
- init_branch_prob (aux_base_name);
+ coverage_init (aux_base_name);
timevar_push (TV_PARSE);
if (flag_syntax_only)
return;
- globals = (*lang_hooks.decls.getdecls) ();
-
- /* Really define vars that have had only a tentative definition.
- Really output inline functions that must actually be callable
- and have not been output so far. */
-
- {
- int len = list_length (globals);
- tree *vec = (tree *) xmalloc (sizeof (tree) * len);
- int i;
- tree decl;
-
- /* Process the decls in reverse order--earliest first.
- Put them into VEC from back to front, then take out from front. */
-
- for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
- vec[len - i - 1] = decl;
+ (*lang_hooks.decls.final_write_globals)();
- wrapup_global_declarations (vec, len);
-
- /* This must occur after the loop to output deferred functions. Else
- the profiler initializer would not be emitted if all the functions
- in this compilation unit were deferred.
-
- output_func_start_profiler can not cause any additional functions or
- data to need to be output, so it need not be in the deferred function
- loop above. */
- output_func_start_profiler ();
-
- check_global_declarations (vec, len);
-
- /* Clean up. */
- free (vec);
- }
+ /* This must occur after the loop to output deferred functions.
+ Else the coverage initializer would not be emitted if all the
+ functions in this compilation unit were deferred. */
+ coverage_finish ();
/* Write out any pending weak symbol declarations. */
dw2_output_indirect_constants ();
- end_final (aux_base_name);
-
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
timevar_push (TV_DUMP);
int top_level;
int at_end;
{
- /* Declarations of variables, and of functions defined elsewhere. */
-
-/* The most obvious approach, to put an #ifndef around where
- this macro is used, doesn't work since it's inside a macro call. */
-#ifndef ASM_FINISH_DECLARE_OBJECT
-#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. */
{
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);
+
+#ifdef ASM_FINISH_DECLARE_OBJECT
if (decl == last_assemble_variable_decl)
{
ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
top_level, at_end);
}
+#endif
timevar_pop (TV_VARCONST);
}
timevar_pop (TV_SYMOUT);
}
#endif
+#ifdef DWARF2_DEBUGGING_INFO
+ else if ((write_symbols == DWARF2_DEBUG
+ || write_symbols == VMS_AND_DWARF2_DEBUG)
+ && top_level
+ && TREE_CODE (decl) == TYPE_DECL)
+ {
+ timevar_push (TV_SYMOUT);
+ dwarf2out_decl (decl);
+ timevar_pop (TV_SYMOUT);
+ }
+#endif
}
/* Called after finishing a record, union or enumeral type. */
void
rest_of_type_compilation (type, toplev)
-#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) \
+ || defined (SDB_DEBUGGING_INFO) || defined (DWARF2_DEBUGGING_INFO)
tree type;
int toplev;
#else
int toplev ATTRIBUTE_UNUSED;
#endif
{
+ /* Avoid confusing the debug information machinery when there are
+ errors. */
+ if (errorcount != 0 || sorrycount != 0)
+ return;
+
timevar_push (TV_SYMOUT);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
int tem;
int failure = 0;
int rebuild_label_notes_after_reload;
- int register_life_up_to_date;
timevar_push (TV_REST_OF_COMPILATION);
DECL_INITIAL (decl) = 0;
goto exit_rest_of_compilation;
}
+ else if (TYPE_P (parent))
+ /* A function in a local class should be treated normally. */
+ break;
/* If requested, consider whether to make this function inline. */
if ((DECL_INLINE (decl) && !flag_no_inline)
goto exit_rest_of_compilation;
}
}
- else
- /* ??? Note that this has the effect of making it look
- like "inline" was specified for a function if we choose
- to inline it. This isn't quite right, but it's
- probably not worth the trouble to fix. */
+ else {
+ /* ??? Note that we used to just make it look like if
+ the "inline" keyword was specified when we decide
+ to inline it (because of -finline-functions).
+ garloff@suse.de, 2002-04-24: Add another flag to
+ actually record this piece of information. */
+ if (!DECL_INLINE (decl))
+ DID_INLINE_FUNC (decl) = 1;
inlinable = DECL_INLINE (decl) = 1;
+ }
}
insns = get_insns ();
convert_from_eh_region_ranges ();
/* If function is inline, and we don't yet know whether to
- compile it by itself, defer decision till end of compilation.
- finish_compilation will call rest_of_compilation again
- for those functions that need to be output. Also defer those
- functions that we are supposed to defer. */
+ compile it by itself, defer decision till end of compilation.
+ wrapup_global_declarations will (indirectly) call
+ rest_of_compilation again for those functions that need to
+ be output. Also defer those functions that we are supposed
+ to defer. */
if (inlinable
|| (DECL_INLINE (decl)
+ && flag_inline_functions
&& ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
&& ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& ! flag_keep_inline_functions)
delete_unreachable_blocks ();
+ /* We have to issue these warnings now already, because CFG cleanups
+ further down may destroy the required information. */
+ check_function_return_warnings ();
+
/* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
- note_prediction_to_br_prob ();
+ if (flag_guess_branch_prob)
+ {
+ timevar_push (TV_BRANCH_PROB);
+ note_prediction_to_br_prob ();
+ timevar_pop (TV_BRANCH_PROB);
+ }
/* We may have potential sibling or tail recursion sites. Select one
(of possibly multiple) methods of performing the call. */
timevar_push (TV_JUMP);
/* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
before jump optimization switches branch directions. */
- expected_value_to_br_prob ();
+ if (flag_guess_branch_prob)
+ expected_value_to_br_prob ();
reg_scan (insns, max_reg_num (), 0);
rebuild_jump_labels (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ delete_trivially_dead_insns (insns, max_reg_num ());
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 ();
- if (!optimize_size)
- copy_loop_headers (insns);
+ if (optimize)
+ {
+ free_bb_for_insn ();
+ copy_loop_headers (insns);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ }
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);
}
timevar_push (TV_JUMP);
- cleanup_cfg (optimize ? CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP: 0);
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
save_cfj = flag_cse_follow_jumps;
flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
+ /* Instantiate any remaining CONSTANT_P_RTX nodes. */
+ if (current_function_calls_constant_p)
+ purge_builtin_constant_p ();
+
/* If -fexpensive-optimizations, re-run CSE to clean up things done
by gcse. */
if (flag_expensive_optimizations)
/* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
- do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
+ if (flag_unroll_loops)
+ do_unroll = 0; /* Having two unrollers is useless. */
+ else
+ do_unroll = flag_old_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
if (flag_rerun_loop_opt)
{
ggc_collect ();
}
+ /* Perform jump bypassing and control flow optimizations. */
+ if (optimize > 0 && flag_gcse)
+ {
+ timevar_push (TV_BYPASS);
+ open_dump_file (DFI_bypass, decl);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ tem = bypass_jumps (rtl_dump_file);
+
+ if (tem)
+ {
+ rebuild_jump_labels (insns);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ }
+
+ close_dump_file (DFI_bypass, print_rtl_with_bb, insns);
+ timevar_pop (TV_BYPASS);
+
+ ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+ }
+
/* Do control and data flow analysis; wrote some of the results to
the dump file. */
open_dump_file (DFI_cfg, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
- cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
- | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE
+ | (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
+ eliminated by life_analysis, 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.
+ life_analysis 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)
+ if (optimize > 0
+ || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
struct loops loops;
timevar_push (TV_BRANCH_PROB);
open_dump_file (DFI_bp, decl);
- if (cfun->arc_profile || flag_branch_probabilities)
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
branch_prob ();
/* Discover and record the loop depth at the head of each basic
close_dump_file (DFI_bp, print_rtl_with_bb, insns);
timevar_pop (TV_BRANCH_PROB);
}
+ if (optimize > 0)
+ {
+ open_dump_file (DFI_ce1, decl);
+ if (flag_if_conversion)
+ {
+ timevar_push (TV_IFCVT);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 0);
+ if_convert (0);
+ timevar_pop (TV_IFCVT);
+ }
+ timevar_push (TV_JUMP);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 0);
+ timevar_pop (TV_JUMP);
+ close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
+ }
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);
+ reg_scan (insns, max_reg_num (), 0);
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)
+ /* Perform loop optimalizations. It might be better to do them a bit
+ sooner, but we want the profile feedback to work more efficiently. */
+ if (optimize > 0
+ && (flag_unswitch_loops
+ || flag_peel_loops
+ || flag_unroll_loops))
+ {
+ struct loops *loops;
+ timevar_push (TV_LOOP);
+ open_dump_file (DFI_loop2, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+
+ loops = loop_optimizer_init (rtl_dump_file);
+
+ if (loops)
+ {
+ /* The optimalizations: */
+ if (flag_unswitch_loops)
+ unswitch_loops (loops);
+
+ if (flag_peel_loops || flag_unroll_loops)
+ unroll_and_peel_loops (loops,
+ (flag_peel_loops ? UAP_PEEL : 0) |
+ (flag_unroll_loops ? UAP_UNROLL : 0) |
+ (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
+
+ loop_optimizer_finalize (loops, rtl_dump_file);
+ }
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ reg_scan (insns, max_reg_num (), 0);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_LOOP);
+ ggc_collect ();
+ }
+
+ if (flag_rerun_cse_after_loop)
{
timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
+ /* CFG is no longer maintained up-to-date. */
+ 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 (flag_rerun_cse_after_loop)
+ if (tem)
{
timevar_push (TV_JUMP);
-
- reg_scan (insns, max_reg_num (), 0);
-
- timevar_push (TV_IFCVT);
+ rebuild_jump_labels (insns);
cleanup_cfg (CLEANUP_EXPENSIVE);
- 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)
- {
- timevar_push (TV_JUMP);
- rebuild_jump_labels (insns);
- cleanup_cfg (CLEANUP_EXPENSIVE);
- timevar_pop (TV_JUMP);
- }
}
-
+ reg_scan (insns, max_reg_num (), 0);
close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
- timevar_pop (TV_CSE2);
-
ggc_collect ();
+ timevar_pop (TV_CSE2);
}
cse_not_expected = 1;
open_dump_file (DFI_life, decl);
regclass_init ();
- check_function_return_warnings ();
-
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
timevar_pop (TV_FLOW);
- no_new_pseudos = 1;
-
- if (warn_uninitialized || extra_warnings)
+ if (warn_uninitialized)
{
uninitialized_vars_warning (DECL_INITIAL (decl));
if (extra_warnings)
if (optimize)
{
- clear_bb_flags ();
if (!flag_new_regalloc && initialize_uninitialized_subregs ())
{
- /* Insns were inserted, so things might look a bit different. */
+ /* Insns were inserted, and possibly pseudos created, so
+ things might look a bit different. */
insns = get_insns ();
- update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
- PROP_LOG_LINKS | PROP_REG_INFO
- | PROP_DEATH_NOTES);
+ allocate_reg_life_data ();
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
}
}
+ no_new_pseudos = 1;
+
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();
= combine_instructions (insns, max_reg_num ());
/* Combining insns may have turned an indirect jump into a
- direct jump. Rebuid the JUMP_LABEL fields of jumping
+ direct jump. Rebuild the JUMP_LABEL fields of jumping
instructions. */
if (rebuild_jump_labels_after_combine)
{
if (flag_if_conversion)
{
timevar_push (TV_IFCVT);
- open_dump_file (DFI_ce, decl);
+ open_dump_file (DFI_ce2, decl);
no_new_pseudos = 0;
if_convert (1);
no_new_pseudos = 1;
- close_dump_file (DFI_ce, print_rtl_with_bb, insns);
+ close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
timevar_pop (TV_IFCVT);
}
description to add extra information not needed previously. */
split_all_insns (1);
- /* Any of the several passes since flow1 will have munged register
- lifetime data a bit. */
- register_life_up_to_date = 0;
-
#ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_MODE_SWITCH);
timevar_pop (TV_MODE_SWITCH);
#endif
+ /* Any of the several passes since flow1 will have munged register
+ lifetime data a bit. We need it to be up to date for scheduling
+ (see handling of reg_known_equiv in init_alias_analysis). */
+ recompute_reg_usage (insns, !optimize_size);
+
timevar_push (TV_SCHED);
#ifdef INSN_SCHEDULING
schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched, print_rtl_with_bb, insns);
-
- /* Register lifetime information was updated as part of verifying
- the schedule. */
- register_life_up_to_date = 1;
}
#endif
timevar_pop (TV_SCHED);
RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
jump optimizer after register allocation and reloading are finished. */
- if (! register_life_up_to_date)
- recompute_reg_usage (insns, ! optimize_size);
-
if (flag_new_regalloc)
{
delete_trivially_dead_insns (insns, max_reg_num ());
#endif
/* If optimizing, then go ahead and split insns now. */
+#ifndef STACK_REGS
if (optimize > 0)
+#endif
split_all_insns (0);
- cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE);
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
timevar_pop (TV_RENAME_REGISTERS);
}
+ if (optimize > 0)
+ {
+ timevar_push (TV_REORDER_BLOCKS);
+ open_dump_file (DFI_bbro, decl);
+
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
+
+ if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
+ tracer ();
+ if (flag_reorder_blocks)
+ reorder_basic_blocks ();
+ if (flag_reorder_blocks
+ || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+
+ close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+ timevar_pop (TV_REORDER_BLOCKS);
+ }
+
if (flag_if_conversion2)
{
timevar_push (TV_IFCVT2);
- open_dump_file (DFI_ce2, decl);
+ open_dump_file (DFI_ce3, decl);
if_convert (1);
- close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+ close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
timevar_pop (TV_IFCVT2);
}
-#ifdef STACK_REGS
- if (optimize)
- split_all_insns (1);
-#endif
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
split_all_insns (1);
- schedule_insns (rtl_dump_file);
+ if (flag_sched2_use_superblocks || flag_sched2_use_traces)
+ {
+ schedule_ebbs (rtl_dump_file);
+ /* No liveness updating code yet, but it should be easy to do.
+ reg-stack recompute the liveness when needed for now. */
+ count_or_remove_death_notes (NULL, 1);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ }
+ else
+ schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
timevar_pop (TV_SCHED2);
timevar_push (TV_REG_STACK);
open_dump_file (DFI_stack, decl);
- reg_to_stack (insns, rtl_dump_file);
-
- close_dump_file (DFI_stack, print_rtl_with_bb, insns);
- timevar_pop (TV_REG_STACK);
-
- ggc_collect ();
-#endif
- if (optimize > 0)
+ if (reg_to_stack (insns, rtl_dump_file) && optimize)
{
- timevar_push (TV_REORDER_BLOCKS);
- open_dump_file (DFI_bbro, decl);
-
- /* 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
- | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
- if (flag_reorder_blocks)
+ if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
+ && flag_reorder_blocks)
{
reorder_basic_blocks ();
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
}
-
- close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
- timevar_pop (TV_REORDER_BLOCKS);
}
+
+ close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+ timevar_pop (TV_REG_STACK);
+
+ ggc_collect ();
+#endif
compute_alignments ();
/* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
/* If a machine dependent reorganization is needed, call it. */
-#ifdef MACHINE_DEPENDENT_REORG
- timevar_push (TV_MACH_DEP);
- open_dump_file (DFI_mach, decl);
+ if (targetm.machine_dependent_reorg != 0)
+ {
+ timevar_push (TV_MACH_DEP);
+ open_dump_file (DFI_mach, decl);
- MACHINE_DEPENDENT_REORG (insns);
+ (*targetm.machine_dependent_reorg) ();
- close_dump_file (DFI_mach, print_rtl, insns);
- timevar_pop (TV_MACH_DEP);
+ close_dump_file (DFI_mach, print_rtl, insns);
+ timevar_pop (TV_MACH_DEP);
- ggc_collect ();
-#endif
+ ggc_collect ();
+ }
purge_line_number_notes (insns);
cleanup_barriers ();
know for certain that we will be generating an out-of-line copy,
the first invocation of this routine (rest_of_compilation) will
skip over this code by doing a `goto exit_rest_of_compilation;'.
- Later on, finish_compilation will call rest_of_compilation again
- for those inline functions that need to have out-of-line copies
- generated. During that call, we *will* be routed past here. */
+ Later on, wrapup_global_declarations will (indirectly) call
+ rest_of_compilation again for those inline functions that need
+ to have out-of-line copies generated. During that call, we
+ *will* be routed past here. */
timevar_push (TV_SYMOUT);
(*debug_hooks->function_decl) (decl);
exit_rest_of_compilation:
+ coverage_end_function ();
+
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */
timevar_pop (TV_FINAL);
+ if ((*targetm.binds_local_p) (current_function_decl))
+ {
+ int pref = cfun->preferred_stack_boundary;
+ if (cfun->recursive_call_emit
+ && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+ pref = cfun->stack_alignment_needed;
+ cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
+ = pref;
+ }
+
/* Make sure volatile mem refs aren't considered valid operands for
arithmetic insns. We must call this here if this is a nested inline
function, since the above code leaves us in the init_recog state
printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
+ printf (_(" -fstack-limit-register=<register> Trap if the stack goes past <register>\n"));
+ printf (_(" -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>\n"));
+ printf (_(" -frandom-seed=<string> Make compile reproducible using <string>\n"));
+
for (i = ARRAY_SIZE (f_options); i--;)
{
printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n"));
printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n"));
printf (_(" -w Suppress warnings\n"));
- printf (_(" -W Enable extra warnings\n"));
for (i = ARRAY_SIZE (W_options); i--;)
{
W_options[i].string, _(description));
}
+ printf (_(" -Wextra Print extra (possibly unwanted) warnings\n"));
printf (_(" -Wunused Enable unused warnings\n"));
printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"));
printf (_(" -p Enable function profiling\n"));
case 'D': /* These are handled by the preprocessor. */
case 'I':
break;
+ case 'H':
+ setup_core_dumping();
+ break;
default:
matched = 0;
read_integral_parameter (option_value, arg - 2,
MAX_INLINE_INSNS);
set_param_value ("max-inline-insns", val);
+ set_param_value ("max-inline-insns-single", val/2);
+ set_param_value ("max-inline-insns-auto", val/2);
+ set_param_value ("max-inline-insns-rtl", val);
+ if (val/4 < MIN_INLINE_INSNS)
+ {
+ if (val/4 > 10)
+ set_param_value ("min-inline-insns", val/4);
+ else
+ set_param_value ("min-inline-insns", 10);
+ }
}
else if ((option_value = skip_leading_substring (arg, "tls-model=")))
{
}
else if (!strcmp (arg, "no-stack-limit"))
stack_limit_rtx = NULL_RTX;
+ else if ((option_value = skip_leading_substring (arg, "random-seed=")))
+ flag_random_seed = option_value;
+ else if (!strcmp (arg, "no-random-seed"))
+ flag_random_seed = NULL;
else if (!strcmp (arg, "preprocessed"))
/* Recognize this switch but do nothing. This prevents warnings
about an unrecognized switch if cpplib has not been linked in. */
{
set_Wunused (0);
}
+ else if (!strcmp (arg, "extra"))
+ {
+ set_Wextra (1);
+ }
+ else if (!strcmp (arg, "no-extra"))
+ {
+ set_Wextra (0);
+ }
else
return 0;
return 1;
}
+/* Indexed by enum debug_info_type. */
+const char *const debug_type_names[] =
+{
+ "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
+};
+
/* Parse a -g... command line switch. ARG is the value after the -g.
It is safe to access 'ARG - 2' to generate the full switch name.
Return the number of strings consumed. */
selected type. It is an error to specify more than one
debugging type. */
static enum debug_info_type selected_debug_type = NO_DEBUG;
- /* Non-zero if debugging format has been explicitly set.
+ /* Nonzero if debugging format has been explicitly set.
-g and -ggdb don't explicitly set the debugging format so
-gdwarf -g3 is equivalent to -gdwarf3. */
static int type_explicitly_set_p = 0;
- /* Indexed by enum debug_info_type. */
- static const char *const debug_type_names[] =
- {
- "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
- };
/* The maximum admissible debug level value. */
static const unsigned max_debug_level = 3;
{
display_help ();
exit_after_options = 1;
+ return 1;
}
if (!strcmp (arg, "-target-help"))
{
display_target_options ();
exit_after_options = 1;
+ return 1;
}
if (!strcmp (arg, "-version"))
{
print_version (stderr, "");
exit_after_options = 1;
+ return 1;
}
/* Handle '--param <name>=<value>'. */
return 2;
}
- if (*arg == 'Y')
- arg++;
-
switch (*arg)
{
default:
if (argv[1][0])
dump_base_name = argv[1];
-
+
return 2;
}
else
break;
case 'W':
+ /* For backward compatibility, -W is the same as -Wextra. */
if (arg[1] == 0)
- {
- extra_warnings = 1;
- /* We save the value of warn_uninitialized, since if they put
- -Wuninitialized on the command line, we need to generate a
- warning about not using it without also specifying -O. */
- if (warn_uninitialized != 1)
- warn_uninitialized = 2;
- }
+ set_Wextra (1);
else
return decode_W_option (arg + 1);
break;
if (argv[1][0])
aux_base_name = argv[1];
-
+
return 2;
}
else if (!strcmp (arg, "auxbase-strip"))
if (argv[1][0])
aux_base_name = argv[1];
}
-
+
return 2;
}
else
for (j = 0; j < ARRAY_SIZE (target_options); j++)
{
int len = strlen (target_options[j].prefix);
- if (!strncmp (target_options[j].prefix, name, len))
+ if (target_options[j].value)
{
- *target_options[j].variable = name + len;
- valid_target_option = 1;
+ if (!strcmp (target_options[j].prefix, name))
+ {
+ *target_options[j].variable = target_options[j].value;
+ valid_target_option = 1;
+ }
+ }
+ else
+ {
+ if (!strncmp (target_options[j].prefix, name, len))
+ {
+ *target_options[j].variable = name + len;
+ valid_target_option = 1;
+ }
}
}
#endif
, indent, *indent != 0 ? " " : "",
lang_hooks.name, version_string, TARGET_NAME,
indent, __VERSION__);
+ fnotice (file, "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n",
+ indent, *indent != 0 ? " " : "",
+ PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
}
/* Print an option value and return the adjusted position in the line.
size_t j;
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. Of
+ course, the string may never be used, but we can't tell that at
+ this point in the compile. */
+ default_flag_random_seed ();
+
/* Print the options as passed. */
pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
if (!strcmp (asm_file_name, "-"))
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);
+ fatal_error ("can't open %s for writing: %m", asm_file_name);
}
#ifdef IO_BUFFER_SIZE
signal (SIGFPE, crash_signal);
#endif
+ /* Other host-specific signal setup. */
+ (*host_hooks.extra_signals)();
+
/* Initialize the diagnostics reporting machinery, so option parsing
can give warnings and errors. */
diagnostic_initialize (global_dc);
/* Register the language-independent parameters. */
add_params (lang_independent_params, LAST_PARAM);
+ /* This must be done after add_params but before argument processing. */
+ init_ggc_heuristics();
+
/* Perform language-specific options initialization. */
(*lang_hooks.init_options) ();
{
flag_inline_functions = 1;
flag_rename_registers = 1;
+ flag_unswitch_loops = 1;
+ flag_unit_at_a_time = 1;
}
if (optimize < 2 || optimize_size)
static void
process_options ()
{
+ /* Allow the front end to perform consistency checks and do further
+ initialization based on the command line options. This hook also
+ sets the original filename if appropriate (e.g. foo.i -> foo.c)
+ so we can correctly initialize debug output. */
+ no_backend = (*lang_hooks.post_options) (&filename);
+ main_input_filename = input_filename = filename;
+
#ifdef OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of options. */
OVERRIDE_OPTIONS;
#endif
+ /* Set aux_base_name if not already set. */
+ if (aux_base_name)
+ ;
+ else if (filename)
+ {
+ char *name = xstrdup (lbasename (filename));
+
+ strip_off_ending (name, strlen (name));
+ aux_base_name = name;
+ }
+ else
+ aux_base_name = "gccaux";
+
/* Set up the align_*_log variables, defaulting them to 1 if they
were still unset. */
if (align_loops <= 0) align_loops = 1;
be done. */
if (flag_unroll_all_loops)
flag_unroll_loops = 1;
- /* Loop unrolling requires that strength_reduction be on also. Silently
+
+ if (flag_unroll_loops)
+ {
+ flag_old_unroll_loops = 0;
+ flag_old_unroll_all_loops = 0;
+ }
+
+ if (flag_old_unroll_all_loops)
+ flag_old_unroll_loops = 1;
+
+ /* Old loop unrolling requires that strength_reduction be on also. Silently
turn on strength reduction here if it isn't already on. Also, the loop
unrolling code assumes that cse will be run after loop, so that must
be turned on also. */
- if (flag_unroll_loops)
+ if (flag_old_unroll_loops)
{
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
}
+ if (flag_unroll_loops || flag_peel_loops)
+ flag_rerun_cse_after_loop = 1;
if (flag_non_call_exceptions)
flag_asynchronous_unwind_tables = 1;
if (flag_asynchronous_unwind_tables)
flag_unwind_tables = 1;
+ /* Disable unit-at-a-time mode for frontends not supporting callgraph
+ interface. */
+ if (flag_unit_at_a_time && ! lang_hooks.callgraph.expand_function)
+ flag_unit_at_a_time = 0;
+
/* Warn about options that are not supported on this machine. */
#ifndef INSN_SCHEDULING
if (flag_schedule_insns || flag_schedule_insns_after_reload)
print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
}
- if (! quiet_flag)
- time_report = 1;
-
if (flag_syntax_only)
{
write_symbols = NO_DEBUG;
{
aux_info_file = fopen (aux_info_file_name, "w");
if (aux_info_file == 0)
- fatal_io_error ("can't open %s", aux_info_file_name);
+ fatal_error ("can't open %s: %m", aux_info_file_name);
}
if (! targetm.have_named_sections)
{
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
-
- /* Front-end initialization. This hook can assume that GC,
- identifier hashes etc. are set up, but debug initialization is
- not done yet. This routine must return the original filename
- (e.g. foo.i -> foo.c) so can correctly initialize debug output. */
- name = (*lang_hooks.init) (name);
- if (name == NULL)
+
+ /* Other front-end initialization. */
+ if ((*lang_hooks.init) () == 0)
return 0;
- /* Is this duplication necessary? */
- name = ggc_strdup (name);
- main_input_filename = input_filename = name;
init_asm_output (name);
/* These create various _DECL nodes, so need to be called after the
if (asm_out_file)
{
if (ferror (asm_out_file) != 0)
- fatal_io_error ("error writing to %s", asm_file_name);
+ fatal_error ("error writing to %s: %m", asm_file_name);
if (fclose (asm_out_file) != 0)
- fatal_io_error ("error closing %s", asm_file_name);
+ fatal_error ("error closing %s: %m", asm_file_name);
}
/* Do whatever is necessary to finish printing the graphs. */
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) ();
+ /* Initialize timing first. The C front ends read the main file in
+ the post_options hook, and C++ does file timings. */
+ if (time_report || !quiet_flag || flag_detailed_statistics)
+ timevar_init ();
+ timevar_start (TV_TOTAL);
- /* 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)
+ /* Don't do any more if an error has already occurred. */
+ if (!errorcount)
{
- 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);
+ /* Set up the back-end if requested. */
+ if (!no_backend)
+ backend_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))
+ compile_file ();
- /* Language-dependent initialization. Returns true on success. */
- if (lang_dependent_init (filename))
- compile_file ();
-
- finalize ();
+ finalize ();
+ }
/* Stop timing and print the times. */
timevar_stop (TV_TOTAL);