#undef FFS /* Some systems define this in param.h. */
#include "system.h"
#include <signal.h>
-#include <setjmp.h>
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#include "debug.h"
#include "target.h"
#include "langhooks.h"
+#include "cfglayout.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
#include "xcoffout.h" /* Needed for external data
declarations for e.g. AIX 4.x. */
#endif
-
-#ifdef HALF_PIC_DEBUG
-#include "halfpic.h"
-#endif
\f
-#ifdef VMS
-/* The extra parameters substantially improve the I/O performance. */
-
-static FILE *
-vms_fopen (fname, type)
- char *fname;
- char *type;
-{
- /* The <stdio.h> in the gcc-vms-1.42 distribution prototypes fopen with two
- fixed arguments, which matches ANSI's specification but not VAXCRTL's
- 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 bool parse_options_and_default_flags PARAMS ((int, char **));
+static void do_compile PARAMS ((int));
static void process_options PARAMS ((void));
-static void lang_independent_init PARAMS ((void));
+static void lang_independent_init PARAMS ((int));
static int lang_dependent_init PARAMS ((const char *));
static void init_asm_output PARAMS ((const char *));
static void finalize PARAMS ((void));
static void set_target_switch PARAMS ((const char *));
-static const char *decl_name PARAMS ((tree, int));
-static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
-static void set_float_handler PARAMS ((jmp_buf));
static void compile_file PARAMS ((void));
static void display_help PARAMS ((void));
static void display_target_options PARAMS ((void));
static void 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
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. */
DFI_loop,
DFI_cfg,
DFI_bp,
+ DFI_tracer,
DFI_cse2,
DFI_life,
DFI_combine,
{ "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 },
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;
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;
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;
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). */
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. */
/* 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. */
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. */
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
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,
N_("Perform enhanced load motion during global subexpression elimination") },
{"gcse-sm", &flag_gcse_sm, 1,
N_("Perform store motion after global subexpression elimination") },
+ {"loop-optimize", &flag_loop_optimize, 1,
+ N_("Perform the loop optimizations") },
+ {"crossjumping", &flag_crossjumping, 1,
+ N_("Perform cross-jumping optimization") },
+ {"if-conversion", &flag_if_conversion, 1,
+ N_("Perform conversion of conditional jumps to branchless equivalents") },
+ {"if-conversion2", &flag_if_conversion2, 1,
+ N_("Perform conversion of conditional jumps to conditional execution") },
{"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
N_("Run CSE pass after loop optimizations") },
{"rerun-loop-opt", &flag_rerun_loop_opt, 1,
N_("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,
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,
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,
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. */
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", "" },
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") },
{ "-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", "" },
{ "-Wdiv-by-zero", "" },
- { "-Wno-div-by-zero",
+ { "-Wno-div-by-zero",
N_("Do not warn about compile-time integer division by zero") },
- { "-Wfloat-equal",
+ { "-Wfloat-equal",
N_("Warn about testing equality of floating point numbers") },
{ "-Wno-float-equal", "" },
- { "-Wformat",
+ { "-Wformat",
N_("Warn about printf/scanf/strftime/strfmon format anomalies") },
{ "-Wno-format", "" },
{ "-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 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",
{ "-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", "" },
- { "-Wpointer-arith",
+ { "-Wpointer-arith",
N_("Warn about function pointer arithmetic") },
{ "-Wno-pointer-arith", "" },
{ "-Wredundant-decls",
{ "-Wsequence-point",
N_("Warn about possible violations of sequence point rules") },
{ "-Wno-sequence-point", "" },
- { "-Wsign-compare",
+ { "-Wsign-compare",
N_("Warn about signed/unsigned comparisons") },
{ "-Wno-sign-compare", "" },
- { "-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", "" },
- { "-Wunknown-pragmas",
+ { "-Wunknown-pragmas",
N_("Warn about unrecognized pragmas") },
{ "-Wno-unknown-pragmas", "" },
- { "-Wwrite-strings",
+ { "-Wwrite-strings",
N_("Mark strings as 'const char *'") },
{ "-Wno-write-strings", "" },
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. */
const char **const variable;
const char *const description;
}
-target_options [] = TARGET_OPTIONS;
+target_options[] = TARGET_OPTIONS;
#endif
\f
/* Options controlling warnings. */
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. */
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;
{"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,
-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);
}
\f
return atoi (p);
}
-
-\f
-/* 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));
-}
\f
-
/* 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. */
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. */
int len;
{
int i;
- for (i = 2; i < 6 && len > i; i++)
+ for (i = 2; i < 6 && len > i; i++)
{
if (name[len - i] == '.')
{
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
while (na > input_name)
{
if (IS_DIR_SEPARATOR (na[-1]))
- break;
+ break;
na--;
}
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;
/* 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
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
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);
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++;
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. */
/* 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
{
alias = TREE_VALUE (TREE_VALUE (alias));
alias = get_identifier (TREE_STRING_POINTER (alias));
- assemble_alias (decl, alias);
+ assemble_alias (decl, alias);
}
}
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. */
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.
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;
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);
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.
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
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);
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 ();
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);
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);
- /* 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);
}
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);
if (tem || optimize > 1)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
/* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks || flag_thread_jumps)
+ if (flag_delete_null_pointer_checks)
{
timevar_push (TV_JUMP);
- 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);
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 ());
/* 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);
/* 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
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 ());
close_dump_file (DFI_loop, print_rtl, insns);
timevar_pop (TV_LOOP);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
ggc_collect ();
}
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)
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)
{
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. */
#endif
life_analysis (insns, rtl_dump_file, PROP_FINAL);
if (optimize)
- cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
timevar_pop (TV_FLOW);
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 ();
/* 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);
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 ();
timevar_push (TV_JUMP);
rebuild_jump_labels (insns);
+ purge_all_dead_edges (0);
timevar_pop (TV_JUMP);
}
if (optimize)
{
life_analysis (insns, rtl_dump_file, PROP_FINAL);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP | CLEANUP_UPDATE_LIFE);
+ 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
}
#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);
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. */
+ /* 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 ();
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 ();
printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
+ 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));
}
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=<value>%.*s%s\n",
compiler_params[i].option,
length > 0 ? length : 1, " ",
{
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));
}
printf (_(" -Wunused Enable unused warnings\n"));
printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"));
printf (_(" -p Enable function profiling\n"));
-#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
- printf (_(" -a Enable block profiling \n"));
-#endif
-#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
- printf (_(" -ax Enable jump profiling \n"));
-#endif
printf (_(" -o <file> Place output into <file> \n"));
printf (_("\
-G <number> Put global and static data smaller than <number>\n\
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));
}
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
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;
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':
}
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=")))
{
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);
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)));
= 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);
}
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
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
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;
}
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)
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
#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. */
/* Parse command line options and set default flag values, called
after language-independent option-independent initialization. Do
minimal options processing. Outputting diagnostics is OK, but GC
- and identifier hashtables etc. are not initialized yet. */
-static void
+ and identifier hashtables etc. are not initialized yet.
+
+ Return non-zero to suppress compiler back end initialization. */
+static bool
parse_options_and_default_flags (argc, argv)
int argc;
char **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)
flag_strict_aliasing = 1;
flag_delete_null_pointer_checks = 1;
flag_reorder_blocks = 1;
+ flag_reorder_functions = 1;
}
if (optimize >= 3)
}
}
+ 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
warning ("-Wuninitialized is not supported without -O");
}
+ if (flag_really_no_inline == 2)
+ flag_really_no_inline = flag_no_inline;
+
/* All command line options have been parsed; allow the front end to
perform consistency checks, etc. */
- (*lang_hooks.post_options) ();
+ return (*lang_hooks.post_options) ();
}
\f
/* Process the options that have been parsed. */
warning ("this target machine does not have delayed branches");
#endif
- /* Some operating systems do not allow profiling without a frame
- pointer. */
- if (!TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER
- && profile_flag
- && flag_omit_frame_pointer)
- {
- error ("profiling does not work without a frame pointer");
- flag_omit_frame_pointer = 0;
- }
-
user_label_prefix = USER_LABEL_PREFIX;
if (flag_leading_underscore != -1)
{
if (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;
}
\f
/* Language-independent initialization, before language-dependent
initialization. */
static void
-lang_independent_init ()
+lang_independent_init (no_backend)
+ int no_backend;
{
- 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 ();
+ if (no_backend)
+ return;
+
+ /* 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
#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 ();
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);
\f
/* Initialize the compiler, and compile the input file. */
static void
-do_compile ()
+do_compile (no_backend)
+ int no_backend;
{
/* The bulk of command line switch processing. */
process_options ();
timevar_start (TV_TOTAL);
/* Language-independent initialization. Also sets up GC, identifier
- hashes etc. */
- lang_independent_init ();
+ hashes etc., and the back-end if requested. */
+ lang_independent_init (no_backend);
/* Language-dependent initialization. Returns true on success. */
if (lang_dependent_init (filename))
int argc;
char **argv;
{
- hex_init ();
+ bool no_backend;
/* Initialization of GCC's environment, and diagnostics. */
- general_init (argv [0]);
+ general_init (argv[0]);
/* Parse the options and do minimal processing; basically just
enough to default flags appropriately. */
- parse_options_and_default_flags (argc, argv);
+ no_backend = parse_options_and_default_flags (argc, argv);
/* Exit early if we can (e.g. -help). */
- if (!exit_after_options)
- do_compile ();
+ if (!errorcount && !exit_after_options)
+ do_compile (no_backend);
if (errorcount || sorrycount)
return (FATAL_EXIT_CODE);