#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
/* Carry information from ASM_DECLARE_OBJECT_NAME
to ASM_FINISH_DECLARE_OBJECT. */
extern int size_directive_output;
extern tree last_assemble_variable_decl;
+extern void reg_alloc PARAMS ((void));
+
static void general_init PARAMS ((char *));
static void parse_options_and_default_flags PARAMS ((int, char **));
static void do_compile PARAMS ((void));
static void process_options PARAMS ((void));
-static void lang_independent_init PARAMS ((void));
+static void backend_init PARAMS ((void));
static int lang_dependent_init PARAMS ((const char *));
static void init_asm_output PARAMS ((const char *));
static void finalize PARAMS ((void));
const char *dump_base_name;
+/* Name to use as a base for auxiliary output files. */
+
+const char *aux_base_name;
+
/* Format to use to print dumpfile index value */
#ifndef DUMPFILE_FORMAT
#define DUMPFILE_FORMAT ".%02d."
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. */
const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
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 },
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). */
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
{ NULL, 0, NULL }
};
-/* A default for same. */
-#ifndef USER_LABEL_PREFIX
-#define USER_LABEL_PREFIX ""
-#endif
-
/* Table of language-independent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
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_("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. */
enabled by default. */
{ "-ansi",
- N_("Compile just for ISO C89") },
+ N_("Compile just for ISO C90") },
{ "-std= ",
N_("Determine language standard") },
-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 calls abort and is used to avoid problems when abort if a macro.
+/* This calls abort and is used to avoid problems when abort is a macro.
It is used when we need to pass the address of abort. */
void
crash_signal (signo)
int signo;
{
- internal_error ("internal error: %s", strsignal (signo));
+ internal_error ("%s", strsignal (signo));
}
/* Strip off a legitimate source ending from the input string NAME of
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
free (dump_name);
if (decl)
- fprintf (rtl_dump_file, "\n;; Function %s\n\n",
- (*lang_hooks.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;
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++;
/* Initialize yet another pass. */
init_final (main_input_filename);
- init_branch_prob (dump_base_name);
+ init_branch_prob (aux_base_name);
timevar_push (TV_PARSE);
dw2_output_indirect_constants ();
- end_final (dump_base_name);
+ end_final (aux_base_name);
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
free_bb_for_insn ();
}
- current_function_nothrow = nothrow_function_p ();
+ set_nothrow_function_flags ();
if (current_function_nothrow)
/* Now we know that this can't throw; set the flag for the benefit
of other functions later in this translation unit. */
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. */
rtx insn;
optimize_sibling_and_tail_recursive_calls ();
+ /* 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))
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
delete_insn (insn);
}
- close_dump_file (DFI_sibling, print_rtl, get_insns ());
- timevar_pop (TV_JUMP);
+ 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);
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 ();
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 (flag_delete_null_pointer_checks || flag_if_conversion)
+ /* 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 (flag_if_conversion)
- 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 ());
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, LOOP_FIRST_PASS);
+ 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)
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)
{
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 ();
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 ();
shorten_branches (get_insns ());
timevar_pop (TV_SHORTEN_BRANCH);
- current_function_nothrow = nothrow_function_p ();
+ set_nothrow_function_flags ();
if (current_function_nothrow)
/* Now we know that this can't throw; set the flag for the benefit
of other functions later in this translation unit. */
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--;)
{
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 (!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)));
else if (!strcmp (arg, "no-stack-limit"))
stack_limit_rtx = NULL_RTX;
else if (!strcmp (arg, "preprocessed"))
- /* Recognise this switch but do nothing. This prevents warnings
+ /* Recognize this switch but do nothing. This prevents warnings
about an unrecognized switch if cpplib has not been linked in. */
;
else
if (argc == 1)
return 0;
- dump_base_name = argv[1];
+ if (argv[1][0])
+ dump_base_name = argv[1];
+
return 2;
}
else
else
return 0;
}
+ else if (!strcmp (arg, "auxbase"))
+ {
+ if (argc == 1)
+ return 0;
+
+ if (argv[1][0])
+ aux_base_name = argv[1];
+
+ return 2;
+ }
+ else if (!strcmp (arg, "auxbase-strip"))
+ {
+ if (argc == 1)
+ return 0;
+
+ if (argv[1][0])
+ {
+ strip_off_ending (argv[1], strlen (argv[1]));
+ if (argv[1][0])
+ aux_base_name = argv[1];
+ }
+
+ return 2;
+ }
else
return 0;
break;
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;
}
xmalloc_set_program_name (progname);
+ hex_init ();
+
gcc_init_libintl ();
/* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
/* Initialize the diagnostics reporting machinery, so option parsing
can give warnings and errors. */
diagnostic_initialize (global_dc);
+
+ /* Initialize the garbage-collector, string pools and tree type hash
+ table. */
+ init_ggc ();
+ init_stringpool ();
+ init_ttree ();
}
\f
/* Parse command line options and set default flag values, called
after language-independent option-independent initialization. Do
minimal options processing. Outputting diagnostics is OK, but GC
- and identifier hashtables etc. are not initialized yet. */
+ and identifier hashtables etc. are not initialized yet.
+
+ Return non-zero to suppress compiler back end initialization. */
static void
parse_options_and_default_flags (argc, argv)
int argc;
flag_strict_aliasing = 1;
flag_delete_null_pointer_checks = 1;
flag_reorder_blocks = 1;
+ flag_reorder_functions = 1;
}
if (optimize >= 3)
align_jumps = 1;
align_labels = 1;
align_functions = 1;
+
+ /* Don't reorder blocks when optimizing for size because extra
+ jump insns may be created; also barrier may create extra padding.
+
+ More correctly we should have a block reordering mode that tried
+ to minimize the combined size of all the jumps. This would more
+ or less automatically remove extra jumps, but would also try to
+ use more short jumps instead of long jumps. */
+ flag_reorder_blocks = 0;
}
/* Initialize whether `char' is signed. */
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) ();
}
\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. */
+/* Initialize the compiler back end. */
static void
-lang_independent_init ()
+backend_init ()
{
- /* Initialize the garbage-collector, and string pools. */
- init_ggc ();
- ggc_add_rtx_root (&stack_limit_rtx, 1);
- ggc_add_tree_root (¤t_function_decl, 1);
- ggc_add_tree_root (¤t_function_func_begin_label, 1);
-
- init_stringpool ();
- init_obstacks ();
-
+ /* init_emit_once uses reg_raw_mode and therefore must be called
+ after init_regs which initialized reg_raw_mode. */
+ init_regs ();
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
#ifdef VMS_DEBUGGING_INFO
#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 ();
{
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
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);
static void
do_compile ()
{
+ /* All command line options have been parsed; allow the front end to
+ perform consistency checks, etc. */
+ bool no_backend = (*lang_hooks.post_options) ();
+
/* The bulk of command line switch processing. */
process_options ();
+ /* If an error has already occurred, give up. */
+ if (errorcount)
+ return;
+
+ if (aux_base_name)
+ /*NOP*/;
+ else if (filename)
+ {
+ char *name = xstrdup (lbasename (filename));
+
+ aux_base_name = name;
+ strip_off_ending (name, strlen (name));
+ }
+ else
+ aux_base_name = "gccaux";
+
/* We cannot start timing until after options are processed since that
says if we run timers or not. */
init_timevar ();
timevar_start (TV_TOTAL);
- /* Language-independent initialization. Also sets up GC, identifier
- hashes etc. */
- lang_independent_init ();
+ /* Set up the back-end if requested. */
+ if (!no_backend)
+ backend_init ();
/* Language-dependent initialization. Returns true on success. */
if (lang_dependent_init (filename))
int argc;
char **argv;
{
- hex_init ();
-
/* Initialization of GCC's environment, and diagnostics. */
general_init (argv[0]);