/* Top level of GCC compilers (cc1, cc1plus, etc.)
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "line-map.h"
-#include "input.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
+#include "fold-const.h"
#include "varasm.h"
#include "tree-inline.h"
#include "realmpfr.h" /* For GMP/MPFR/MPC versions, in print_version. */
#include "except.h"
#include "function.h"
#include "toplev.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
#include "expr.h"
#include "intl.h"
#include "regs.h"
#include "params.h"
#include "reload.h"
#include "ira.h"
+#include "lra.h"
#include "dwarf2asm.h"
#include "debug.h"
#include "target.h"
#include "langhooks.h"
#include "cfgloop.h" /* for init_set_costs */
#include "hosthooks.h"
+#include "predict.h"
+#include "basic-block.h"
#include "cgraph.h"
#include "opts.h"
#include "opts-diagnostic.h"
#include "gimple-expr.h"
#include "gimple.h"
#include "plugin.h"
-#include "diagnostic-color.h"
#include "context.h"
#include "pass_manager.h"
+#include "auto-profile.h"
+#include "dwarf2out.h"
+#include "bitmap.h"
+#include "ipa-reference.h"
+#include "symbol-summary.h"
+#include "ipa-prop.h"
+#include "gcse.h"
+#include "insn-codes.h"
+#include "optabs.h"
+#include "tree-chkp.h"
+#include "omp-low.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
declarations for e.g. AIX 4.x. */
#endif
-static void general_init (const char *);
-static void do_compile (void);
+#ifndef HAVE_prologue
+#define HAVE_prologue 0
+#endif
+
+#include <new>
+
+static void general_init (const char *, bool);
+static void do_compile ();
static void process_options (void);
static void backend_init (void);
static int lang_dependent_init (const char *);
int fd = open ("/dev/urandom", O_RDONLY);
if (fd >= 0)
{
- read (fd, &random_seed, sizeof (random_seed));
+ if (read (fd, &random_seed, sizeof (random_seed))
+ != sizeof (random_seed))
+ random_seed = 0;
close (fd);
}
struct timeval tv;
gettimeofday (&tv, NULL);
- local_tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ local_tick = (unsigned) tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
#else
{
static void
init_random_seed (void)
{
- if (flag_random_seed)
- {
- char *endp;
-
- /* When the driver passed in a hex number don't crc it again */
- random_seed = strtoul (flag_random_seed, &endp, 0);
- if (!(endp > flag_random_seed && *endp == 0))
- random_seed = crc32_string (0, flag_random_seed);
- }
- else if (!random_seed)
+ if (!random_seed)
random_seed = local_tick ^ getpid (); /* Old racey fallback method */
}
{
const char *old = flag_random_seed;
flag_random_seed = val;
+ if (flag_random_seed)
+ {
+ char *endp;
+
+ /* When the driver passed in a hex number don't crc it again */
+ random_seed = strtoul (flag_random_seed, &endp, 0);
+ if (!(endp > flag_random_seed && *endp == 0))
+ random_seed = crc32_string (0, flag_random_seed);
+ }
return old;
}
{
varpool_node *node;
bool needed = true;
- node = varpool_get_node (decl);
+ node = varpool_node::get (decl);
if (!node && flag_ltrans)
needed = false;
needed = false;
else if (node && node->alias)
needed = false;
- else if (!cgraph_global_info_ready
+ else if (!symtab->global_info_ready
&& (TREE_USED (decl)
|| TREE_USED (DECL_ASSEMBLER_NAME (decl))))
/* needed */;
return output_something;
}
-/* A subroutine of check_global_declarations. Issue appropriate warnings
- for the global declaration DECL. */
+/* Issue appropriate warnings for the global declaration DECL. */
void
-check_global_declaration_1 (tree decl)
+check_global_declaration (tree decl)
{
/* Warn about any function declared static but not defined. We don't
warn about variables, because many programs have static variables
that exist only to get some text into the object file. */
+ symtab_node *snode = symtab_node::get (decl);
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl) == 0
&& DECL_EXTERNAL (decl)
&& ! TREE_NO_WARNING (decl)
&& ! TREE_PUBLIC (decl)
&& (warn_unused_function
- || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+ || snode->referred_to_p (/*include_self=*/false)))
{
- if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ if (snode->referred_to_p (/*include_self=*/false))
pedwarn (input_location, 0, "%q+F used but never defined", decl);
else
warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl);
|| (warn_unused_variable
&& TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl)))
&& ! DECL_IN_SYSTEM_HEADER (decl)
+ && ! snode->referred_to_p (/*include_self=*/false)
+ /* This TREE_USED check is needed in addition to referred_to_p
+ above, because the `__unused__' attribute is not being
+ considered for referred_to_p. */
&& ! TREE_USED (decl)
/* The TREE_USED bit for file-scope decls is kept in the identifier,
to handle multiple external decls in different scopes. */
&& ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl)))
&& ! DECL_EXTERNAL (decl)
+ && ! DECL_ARTIFICIAL (decl)
+ && ! DECL_ABSTRACT_ORIGIN (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))
+ /* Global ctors and dtors are called by the runtime. */
+ && (TREE_CODE (decl) != FUNCTION_DECL
+ || (!DECL_STATIC_CONSTRUCTOR (decl)
+ && !DECL_STATIC_DESTRUCTOR (decl)))
/* Otherwise, ask the language. */
&& lang_hooks.decls.warn_unused_global (decl))
warning ((TREE_CODE (decl) == FUNCTION_DECL)
"%q+D defined but not used", decl);
}
-/* Issue appropriate warnings for the global declarations in V (of
- which there are LEN). */
-
-void
-check_global_declarations (tree *v, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- check_global_declaration_1 (v[i]);
-}
-
-/* Emit debugging information for all global declarations in VEC. */
-
-void
-emit_debug_global_declarations (tree *vec, int len)
-{
- int i;
-
- /* Avoid confusing the debug information machinery when there are errors. */
- if (seen_error ())
- return;
-
- timevar_push (TV_SYMOUT);
- for (i = 0; i < len; i++)
- debug_hooks->global_decl (vec[i]);
- timevar_pop (TV_SYMOUT);
-}
-
/* Compile an entire translation unit. Write a file of assembly
output and various debugging dumps. */
timevar_start (TV_PHASE_PARSING);
timevar_push (TV_PARSE_GLOBAL);
- /* Call the parser, which parses the entire file (calling
- rest_of_compilation for each function). */
+ /* Parse entire file and generate initial debug information. */
lang_hooks.parse_file ();
timevar_pop (TV_PARSE_GLOBAL);
timevar_stop (TV_PHASE_PARSING);
+ if (flag_dump_locations)
+ dump_location_info (stderr);
+
/* Compilation is now finished except for writing
what's left of the symbol table output. */
ggc_protect_identifiers = false;
- /* This must also call finalize_compilation_unit. */
- lang_hooks.decls.final_write_globals ();
+ /* Run the actual compilation process. */
+ if (!in_lto_p)
+ {
+ timevar_start (TV_PHASE_OPT_GEN);
+ symtab->finalize_compilation_unit ();
+ timevar_stop (TV_PHASE_OPT_GEN);
+ }
+
+ /* Perform any post compilation-proper parser cleanups and
+ processing. This is currently only needed for the C++ parser,
+ which can be hopefully cleaned up so this hook is no longer
+ necessary. */
+ if (lang_hooks.decls.post_compilation_parsing_cleanups)
+ lang_hooks.decls.post_compilation_parsing_cleanups ();
if (seen_error ())
return;
+ /* After the parser has generated debugging information, augment
+ this information with any new location/etc information that may
+ have become available after the compilation proper. */
+ timevar_start (TV_PHASE_DBGINFO);
+ symtab_node *node;
+ FOR_EACH_DEFINED_SYMBOL (node)
+ debug_hooks->late_global_decl (node->decl);
+ timevar_stop (TV_PHASE_DBGINFO);
+
timevar_start (TV_PHASE_LATE_ASM);
/* Compilation unit is finalized. When producing non-fat LTO object, we are
if (flag_sanitize & SANITIZE_THREAD)
tsan_finish_file ();
+ if (flag_check_pointer_bounds)
+ chkp_finish_file ();
+
+ omp_finish_file ();
+
output_shared_constant_pool ();
output_object_blocks ();
finish_tm_clone_pairs ();
We used to emit an undefined reference here, but this produces
link errors if an object file with IL is stored into a shared
library without invoking lto1. */
- if (flag_generate_lto)
+ if (flag_generate_lto || flag_generate_offload)
{
#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE,
(unsigned HOST_WIDE_INT) 1,
(unsigned HOST_WIDE_INT) 1);
#endif
- /* Let linker plugin know that this is a slim object and must be LTOed
- even when user did not ask for it. */
- if (!flag_fat_lto_objects)
- {
+ }
+
+ /* Let linker plugin know that this is a slim object and must be LTOed
+ even when user did not ask for it. */
+ if (flag_generate_lto && !flag_fat_lto_objects)
+ {
#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
- ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE,
- "__gnu_lto_slim",
- (unsigned HOST_WIDE_INT) 1, 8);
+ ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim",
+ (unsigned HOST_WIDE_INT) 1, 8);
#elif defined ASM_OUTPUT_ALIGNED_COMMON
- ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
- (unsigned HOST_WIDE_INT) 1, 8);
+ ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim",
+ (unsigned HOST_WIDE_INT) 1, 8);
#else
- ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
- (unsigned HOST_WIDE_INT) 1,
- (unsigned HOST_WIDE_INT) 1);
+ ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim",
+ (unsigned HOST_WIDE_INT) 1,
+ (unsigned HOST_WIDE_INT) 1);
#endif
- }
}
/* Attach a special .ident directive to the end of the file to identify
targetm.asm_out.output_ident (ident_str);
}
+ /* Auto profile finalization. */
+ if (flag_auto_profile)
+ end_auto_profile ();
+
/* Invoke registered plugin callbacks. */
invoke_plugin_callbacks (PLUGIN_FINISH_UNIT, NULL);
/* Print version information to FILE.
Each line begins with INDENT (for the case where FILE is the
- assembler output file). */
+ assembler output file).
+
+ If SHOW_GLOBAL_STATE is true (for cc1 etc), we are within the compiler
+ proper and can print pertinent state (e.g. params and plugins).
+
+ If SHOW_GLOBAL_STATE is false (for use by libgccjit), we are outside the
+ compiler, and we don't hold the mutex on the compiler's global state:
+ we can't print params and plugins, since they might not be initialized,
+ or might be being manipulated by a compile running in another
+ thread. */
void
-print_version (FILE *file, const char *indent)
+print_version (FILE *file, const char *indent, bool show_global_state)
{
static const char fmt1[] =
#ifdef __GNUC__
file == stderr ? _(fmt3) : fmt3,
indent, *indent != 0 ? " " : "",
"MPC", MPC_VERSION_STRING, mpc_get_version ());
- fprintf (file,
- file == stderr ? _(fmt4) : fmt4,
- indent, *indent != 0 ? " " : "",
- PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
- print_plugins_versions (file, indent);
+ if (show_global_state)
+ {
+ fprintf (file,
+ file == stderr ? _(fmt4) : fmt4,
+ indent, *indent != 0 ? " " : "",
+ PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
+
+ print_plugins_versions (file, indent);
+ }
}
static int
}
if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout;
- else
+ else if (!canonical_filename_eq (asm_file_name, name)
+ || !strcmp (asm_file_name, HOST_BIT_BUCKET))
asm_out_file = fopen (asm_file_name, "w");
+ else
+ /* Use UNKOWN_LOCATION to prevent gcc from printing the first
+ line in the current file. */
+ fatal_error (UNKNOWN_LOCATION,
+ "input file %qs is the same as output file",
+ asm_file_name);
if (asm_out_file == 0)
- fatal_error ("can%'t open %s for writing: %m", asm_file_name);
+ fatal_error (UNKNOWN_LOCATION,
+ "can%'t open %qs for writing: %m", asm_file_name);
}
if (!flag_syntax_only)
{
/* Print the list of switches in effect
into the assembler file as comments. */
- print_version (asm_out_file, ASM_COMMENT_START);
+ print_version (asm_out_file, ASM_COMMENT_START, true);
print_switch_values (print_to_asm_out_file);
putc ('\n', asm_out_file);
}
static void *
realloc_for_line_map (void *ptr, size_t len)
{
- return GGC_RESIZEVAR (void, ptr, len);
+ return ggc_realloc (ptr, len);
}
/* A helper function: used as the allocator function for
}
fprintf (stack_usage_file,
- "%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
+ "%s:%d:%d:%s\t" HOST_WIDE_INT_PRINT_DEC"\t%s\n",
lbasename (loc.file),
loc.line,
loc.column,
if (warn_stack_usage >= 0)
{
+ const location_t loc = DECL_SOURCE_LOCATION (current_function_decl);
+
if (stack_usage_kind == DYNAMIC)
- warning (OPT_Wstack_usage_, "stack usage might be unbounded");
+ warning_at (loc, OPT_Wstack_usage_, "stack usage might be unbounded");
else if (stack_usage > warn_stack_usage)
{
if (stack_usage_kind == DYNAMIC_BOUNDED)
- warning (OPT_Wstack_usage_, "stack usage might be %wd bytes",
- stack_usage);
+ warning_at (loc,
+ OPT_Wstack_usage_, "stack usage might be %wd bytes",
+ stack_usage);
else
- warning (OPT_Wstack_usage_, "stack usage is %wd bytes",
- stack_usage);
+ warning_at (loc, OPT_Wstack_usage_, "stack usage is %wd bytes",
+ stack_usage);
}
}
}
filename = concat (aux_base_name, ".", ext, NULL);
file = fopen (filename, "w");
if (!file)
- fatal_error ("can%'t open %s for writing: %m", filename);
+ fatal_error (input_location, "can%'t open %s for writing: %m", filename);
free (filename);
return file;
}
options are parsed. Signal handlers, internationalization etc.
ARGV0 is main's argv[0]. */
static void
-general_init (const char *argv0)
+general_init (const char *argv0, bool init_signals)
{
const char *p;
/* Set a default printer. Language specific initializations will
override it later. */
tree_diagnostics_defaults (global_dc);
- /* FIXME: This should probably be moved to C-family
- language-specific initializations. */
- /* By default print macro expansion contexts in the diagnostic
- finalizer -- for tokens resulting from macro expansion. */
- diagnostic_finalizer (global_dc) = virt_loc_aware_diagnostic_finalizer;
global_dc->show_caret
= global_options_init.x_flag_diagnostics_show_caret;
global_dc->option_state = &global_options;
global_dc->option_name = option_name;
- /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
+ if (init_signals)
+ {
+ /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
#ifdef SIGSEGV
- signal (SIGSEGV, crash_signal);
+ signal (SIGSEGV, crash_signal);
#endif
#ifdef SIGILL
- signal (SIGILL, crash_signal);
+ signal (SIGILL, crash_signal);
#endif
#ifdef SIGBUS
- signal (SIGBUS, crash_signal);
+ signal (SIGBUS, crash_signal);
#endif
#ifdef SIGABRT
- signal (SIGABRT, crash_signal);
+ signal (SIGABRT, crash_signal);
#endif
#if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
- signal (SIGIOT, crash_signal);
+ signal (SIGIOT, crash_signal);
#endif
#ifdef SIGFPE
- signal (SIGFPE, crash_signal);
+ signal (SIGFPE, crash_signal);
#endif
- /* Other host-specific signal setup. */
- (*host_hooks.extra_signals)();
+ /* Other host-specific signal setup. */
+ (*host_hooks.extra_signals)();
+ }
/* Initialize the garbage-collector, string pools and tree type hash
table. */
init_ggc ();
init_stringpool ();
- line_table = ggc_alloc_line_maps ();
- linemap_init (line_table);
+ input_location = UNKNOWN_LOCATION;
+ line_table = ggc_alloc<line_maps> ();
+ linemap_init (line_table, BUILTINS_LOCATION);
line_table->reallocator = realloc_for_line_map;
line_table->round_alloc_size = ggc_round_alloc_size;
init_ttree ();
/* Create the singleton holder for global state.
Doing so also creates the pass manager and with it the passes. */
g = new gcc::context ();
+ symtab = new (ggc_cleared_alloc <symbol_table> ()) symbol_table ();
statistics_early_init ();
finish_params ();
maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT;
- /* Default to -fdiagnostics-color=auto if GCC_COLORS is in the environment,
- otherwise default to -fdiagnostics-color=never. */
- if (!global_options_set.x_flag_diagnostics_show_color
- && getenv ("GCC_COLORS"))
- pp_show_color (global_dc->printer)
- = colorize_init (DIAGNOSTICS_COLOR_AUTO);
-
/* 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 (&main_input_filename);
+ /* Set default values for parameters relation to the Scalar Reduction
+ of Aggregates passes (SRA and IP-SRA). We must do this here, rather
+ than in opts.c:default_options_optimization as historically these
+ tuning heuristics have been based on MOVE_RATIO, which on some
+ targets requires other symbols from the backend. */
+ maybe_set_param_value
+ (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED,
+ get_move_ratio (true) * UNITS_PER_WORD,
+ global_options.x_param_values, global_options_set.x_param_values);
+ maybe_set_param_value
+ (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE,
+ get_move_ratio (false) * UNITS_PER_WORD,
+ global_options.x_param_values, global_options_set.x_param_values);
+
/* Some machines may reject certain combinations of options. */
targetm.target_option.override ();
else
aux_base_name = "gccaux";
-#ifndef HAVE_cloog
+#ifndef HAVE_isl
if (flag_graphite
|| flag_graphite_identity
|| flag_loop_block
|| flag_loop_interchange
|| flag_loop_strip_mine
- || flag_loop_parallelize_all)
- sorry ("Graphite loop optimizations cannot be used (-fgraphite, "
- "-fgraphite-identity, -floop-block, "
+ || flag_loop_parallelize_all
+ || flag_loop_unroll_jam)
+ sorry ("Graphite loop optimizations cannot be used (ISL is not available)"
+ "(-fgraphite, -fgraphite-identity, -floop-block, "
"-floop-interchange, -floop-strip-mine, -floop-parallelize-all, "
- "and -ftree-loop-linear)");
+ "-floop-unroll-and-jam, and -ftree-loop-linear)");
#endif
+ if (flag_check_pointer_bounds)
+ {
+ if (targetm.chkp_bound_mode () == VOIDmode)
+ {
+ error ("-fcheck-pointer-bounds is not supported for this target");
+ flag_check_pointer_bounds = 0;
+ }
+
+ if (flag_sanitize & SANITIZE_ADDRESS)
+ {
+ error ("-fcheck-pointer-bounds is not supported with "
+ "Address Sanitizer");
+ flag_check_pointer_bounds = 0;
+ }
+ }
+
/* One region RA really helps to decrease the code size. */
if (flag_ira_region == IRA_REGION_AUTODETECT)
flag_ira_region
= optimize_size || !optimize ? IRA_REGION_ONE : IRA_REGION_MIXED;
- if (flag_strict_volatile_bitfields > 0 && !abi_version_at_least (2))
+ if (!abi_version_at_least (2))
{
- warning (0, "-fstrict-volatile-bitfields disabled; "
- "it is incompatible with ABI versions < 2");
- flag_strict_volatile_bitfields = 0;
+ /* -fabi-version=1 support was removed after GCC 4.9. */
+ error ("%<-fabi-version=1%> is no longer supported");
+ flag_abi_version = 2;
}
/* Unrolling all loops implies that standard loop unrolling must also
option flags in use. */
if (version_flag)
{
- print_version (stderr, "");
+ print_version (stderr, "", true);
if (! quiet_flag)
print_switch_values (print_to_stderr);
}
debug_hooks = &vmsdbg_debug_hooks;
#endif
else
- error ("target system does not support the \"%s\" debug format",
+ error ("target system does not support the %qs debug format",
debug_type_names[write_symbols]);
/* We know which debug output will be used so we can set flag_var_tracking
warning (0, "var-tracking-assignments changes selective scheduling");
if (flag_tree_cselim == AUTODETECT_VALUE)
-#ifdef HAVE_conditional_move
- flag_tree_cselim = 1;
-#else
- flag_tree_cselim = 0;
-#endif
+ {
+ if (HAVE_conditional_move)
+ flag_tree_cselim = 1;
+ else
+ flag_tree_cselim = 0;
+ }
/* If auxiliary info generation is desired, open the output file.
This goes in the same directory as the source file--unlike
{
aux_info_file = fopen (aux_info_file_name, "w");
if (aux_info_file == 0)
- fatal_error ("can%'t open %s: %m", aux_info_file_name);
+ fatal_error (input_location, "can%'t open %s: %m", aux_info_file_name);
}
if (!targetm_common.have_named_sections)
warn_stack_protect = 0;
/* Address Sanitizer needs porting to each target architecture. */
+
if ((flag_sanitize & SANITIZE_ADDRESS)
- && (targetm.asan_shadow_offset == NULL
- || !FRAME_GROWS_DOWNWARD))
+ && !FRAME_GROWS_DOWNWARD)
+ {
+ warning (0,
+ "-fsanitize=address and -fsanitize=kernel-address "
+ "are not supported for this target");
+ flag_sanitize &= ~SANITIZE_ADDRESS;
+ }
+
+ if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+ && targetm.asan_shadow_offset == NULL)
{
warning (0, "-fsanitize=address not supported for this target");
flag_sanitize &= ~SANITIZE_ADDRESS;
}
+ /* Do not use IPA optimizations for register allocation if profiler is active
+ or port does not emit prologue and epilogue as RTL. */
+ if (profile_flag || !HAVE_prologue || !HAVE_epilogue)
+ flag_ipa_ra = 0;
+
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
have not been set. */
if (!global_options_set.x_warnings_are_errors
/* Save the current optimization options. */
optimization_default_node = build_optimization_node (&global_options);
optimization_current_node = optimization_default_node;
+
+ /* Please don't change global_options after this point, those changes won't
+ be reflected in optimization_{default,current}_node. */
}
/* This function can be called multiple times to reinitialize the compiler
/* Initialize alignment variables. */
init_alignments ();
- /* This reinitializes hard_frame_pointer, and calls init_reg_modes_target()
- to initialize reg_raw_mode[]. */
- init_emit_regs ();
-
- /* This invokes target hooks to set fixed_reg[] etc, which is
- mode-dependent. */
- init_regs ();
-
/* This depends on stack_pointer_rtx. */
init_fake_stack_mems ();
/* Depends on HARD_FRAME_POINTER_REGNUM. */
init_reload ();
+ /* Depends on the enabled attribute. */
+ recog_init ();
+
/* The following initialization functions need to generate rtl, so
provide a dummy function context for them. */
init_dummy_function_start ();
on a mode change. */
init_expmed ();
init_lower_subreg ();
+ init_set_costs ();
+
+ init_expr_target ();
+ ira_init ();
/* We may need to recompute regno_save_code[] and regno_restore_code[]
after a mode change as well. */
init_varasm_once ();
save_register_info ();
- /* Initialize the target-specific back end pieces. */
- ira_init_once ();
- backend_init_target ();
+ /* Middle end needs this initialization for default mem attributes
+ used by early calls to make_decl_rtl. */
+ init_emit_regs ();
+
+ /* Middle end needs this initialization for mode tables used to assign
+ modes to vector variables. */
+ init_regs ();
}
/* Initialize excess precision settings. */
generated from the target machine description. */
init_optabs ();
- /* The following initialization functions need to generate rtl, so
- provide a dummy function context for them. */
- init_dummy_function_start ();
+ gcc_assert (!this_target_rtl->target_specific_initialized);
+}
- /* Do the target-specific parts of expr initialization. */
- init_expr_target ();
+/* Perform initializations that are lang-dependent or target-dependent.
+ but matters only for late optimizations and RTL generation. */
- /* Although the actions of these functions are language-independent,
- they use optabs, so we cannot call them from backend_init. */
- init_set_costs ();
- ira_init ();
+static int rtl_initialized;
- expand_dummy_function_end ();
+void
+initialize_rtl (void)
+{
+ auto_timevar tv (TV_INITIALIZE_RTL);
+
+ /* Initialization done just once per compilation, but delayed
+ till code generation. */
+ if (!rtl_initialized)
+ ira_init_once ();
+ rtl_initialized = true;
+
+ /* Target specific RTL backend initialization. */
+ if (!this_target_rtl->target_specific_initialized)
+ {
+ backend_init_target ();
+ this_target_rtl->target_specific_initialized = true;
+ }
}
/* Language-dependent initialization. Returns nonzero on success. */
{
struct rtl_data saved_x_rtl;
rtx *saved_regno_reg_rtx;
+ tree saved_optimization_current_node;
+ struct target_optabs *saved_this_fn_optabs;
+
+ /* Temporarily switch to the default optimization node, so that
+ *this_target_optabs is set to the default, not reflecting
+ whatever a previous function used for the optimize
+ attribute. */
+ saved_optimization_current_node = optimization_current_node;
+ saved_this_fn_optabs = this_fn_optabs;
+ if (saved_optimization_current_node != optimization_default_node)
+ {
+ optimization_current_node = optimization_default_node;
+ cl_optimization_restore
+ (&global_options,
+ TREE_OPTIMIZATION (optimization_default_node));
+ }
+ this_fn_optabs = this_target_optabs;
/* Save *crtl and regno_reg_rtx around the reinitialization
to allow target_reinit being called even after prepare_function_start. */
regno_reg_rtx = NULL;
}
- /* Reinitialize RTL backend. */
- backend_init_target ();
+ this_target_rtl->target_specific_initialized = false;
+
+ /* This initializes hard_frame_pointer, and calls init_reg_modes_target()
+ to initialize reg_raw_mode[]. */
+ init_emit_regs ();
+
+ /* This invokes target hooks to set fixed_reg[] etc, which is
+ mode-dependent. */
+ init_regs ();
/* Reinitialize lang-dependent parts. */
lang_dependent_init_target ();
- /* And restore it at the end, as free_after_compilation from
+ /* Restore the original optimization node. */
+ if (saved_optimization_current_node != optimization_default_node)
+ {
+ optimization_current_node = saved_optimization_current_node;
+ cl_optimization_restore (&global_options,
+ TREE_OPTIMIZATION (optimization_current_node));
+ }
+ this_fn_optabs = saved_this_fn_optabs;
+
+ /* Restore regno_reg_rtx at the end, as free_after_compilation from
expand_dummy_function_end clears it. */
if (saved_regno_reg_rtx)
{
dump_rtx_statistics ();
dump_alloc_pool_statistics ();
dump_bitmap_statistics ();
+ dump_hash_table_loc_statistics ();
dump_vec_loc_statistics ();
dump_ggc_loc_statistics (final);
dump_alias_stats (stderr);
if (asm_out_file)
{
if (ferror (asm_out_file) != 0)
- fatal_error ("error writing to %s: %m", asm_file_name);
+ fatal_error (input_location, "error writing to %s: %m", asm_file_name);
if (fclose (asm_out_file) != 0)
- fatal_error ("error closing %s: %m", asm_file_name);
+ fatal_error (input_location, "error closing %s: %m", asm_file_name);
}
if (stack_usage_file)
g->get_passes ()->finish_optimization_passes ();
- ira_finish_once ();
+ lra_finish_once ();
}
if (mem_report)
lang_hooks.finish ();
}
+static bool
+standard_type_bitsize (int bitsize)
+{
+ /* As a special exception, we always want __int128 enabled if possible. */
+ if (bitsize == 128)
+ return false;
+ if (bitsize == CHAR_TYPE_SIZE
+ || bitsize == SHORT_TYPE_SIZE
+ || bitsize == INT_TYPE_SIZE
+ || bitsize == LONG_TYPE_SIZE
+ || bitsize == LONG_LONG_TYPE_SIZE)
+ return true;
+ return false;
+}
+
/* Initialize the compiler, and compile the input file. */
static void
-do_compile (void)
+do_compile ()
{
- /* 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);
-
process_options ();
/* Don't do any more if an error has already occurred. */
if (!seen_error ())
{
+ int i;
+
timevar_start (TV_PHASE_SETUP);
/* This must be run always, because it is needed to compute the FP
predefined macros, such as __LDBL_MAX__, for targets using non
default FP formats. */
init_adjust_machine_modes ();
+ init_derived_machine_modes ();
+
+ /* This must happen after the backend has a chance to process
+ command line options, but before the parsers are
+ initialized. */
+ for (i = 0; i < NUM_INT_N_ENTS; i ++)
+ if (targetm.scalar_mode_supported_p (int_n_data[i].m)
+ && ! standard_type_bitsize (int_n_data[i].bitsize))
+ int_n_enabled_p[i] = true;
+ else
+ int_n_enabled_p[i] = false;
/* Set up the back-end if requested. */
if (!no_backend)
ggc_protect_identifiers = true;
- init_cgraph ();
+ symtab->initialize ();
init_final (main_input_filename);
coverage_init (aux_base_name);
statistics_init ();
timevar_stop (TV_PHASE_FINALIZE);
}
+}
+
+toplev::toplev (bool use_TV_TOTAL, bool init_signals)
+ : m_use_TV_TOTAL (use_TV_TOTAL),
+ m_init_signals (init_signals)
+{
+ if (!m_use_TV_TOTAL)
+ start_timevars ();
+}
+
+toplev::~toplev ()
+{
+ if (g_timer)
+ {
+ g_timer->stop (TV_TOTAL);
+ g_timer->print (stderr);
+ }
+}
- /* Stop timing and print the times. */
- timevar_stop (TV_TOTAL);
- timevar_print (stderr);
+void
+toplev::start_timevars ()
+{
+ if (time_report || !quiet_flag || flag_detailed_statistics)
+ timevar_init ();
+
+ timevar_start (TV_TOTAL);
}
/* Entry point of cc1, cc1plus, jc1, f771, etc.
It is not safe to call this function more than once. */
int
-toplev_main (int argc, char **argv)
+toplev::main (int argc, char **argv)
{
/* Parsing and gimplification sometimes need quite large stack.
Increase stack size limits if possible. */
expandargv (&argc, &argv);
/* Initialization of GCC's environment, and diagnostics. */
- general_init (argv[0]);
+ general_init (argv[0], m_init_signals);
/* One-off initialization of options that does not need to be
repeated when options are added for particular functions. */
initialize_plugins ();
if (version_flag)
- print_version (stderr, "");
+ print_version (stderr, "", true);
if (help_flag)
print_plugins_help (stderr, "");
/* Exit early if we can (e.g. -help). */
if (!exit_after_options)
- do_compile ();
+ {
+ if (m_use_TV_TOTAL)
+ start_timevars ();
+ do_compile ();
+ }
if (warningcount || errorcount || werrorcount)
print_ignored_options ();
return (SUCCESS_EXIT_CODE);
}
+
+/* For those that want to, this function aims to clean up enough state that
+ you can call toplev::main again. */
+void
+toplev::finalize (void)
+{
+ rtl_initialized = false;
+ this_target_rtl->target_specific_initialized = false;
+
+ /* Needs to be called before cgraph_c_finalize since it uses symtab. */
+ ipa_reference_c_finalize ();
+
+ cgraph_c_finalize ();
+ cgraphunit_c_finalize ();
+ dwarf2out_c_finalize ();
+ gcse_c_finalize ();
+ ipa_cp_c_finalize ();
+ ira_costs_c_finalize ();
+ params_c_finalize ();
+
+ finalize_options_struct (&global_options);
+ finalize_options_struct (&global_options_set);
+
+ XDELETEVEC (save_decoded_options);
+
+ /* Clean up the context (and pass_manager etc). */
+ delete g;
+ g = NULL;
+
+ obstack_free (&opts_obstack, NULL);
+}