/* Top level of GCC compilers (cc1, cc1plus, etc.)
- Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011 Free Software Foundation, Inc.
+ Copyright (C) 1987-2014 Free Software Foundation, Inc.
This file is part of GCC.
#include "line-map.h"
#include "input.h"
#include "tree.h"
+#include "varasm.h"
+#include "tree-inline.h"
#include "realmpfr.h" /* For GMP/MPFR/MPC versions, in print_version. */
#include "version.h"
#include "rtl.h"
#include "recog.h"
#include "output.h"
#include "except.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "machmode.h"
#include "function.h"
#include "toplev.h"
#include "expr.h"
-#include "basic-block.h"
#include "intl.h"
-#include "ggc.h"
#include "regs.h"
#include "timevar.h"
#include "diagnostic.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 "hash-map.h"
+#include "is-a.h"
+#include "plugin-api.h"
+#include "ipa-ref.h"
#include "cgraph.h"
#include "opts.h"
#include "opts-diagnostic.h"
#include "coverage.h"
#include "value-prof.h"
#include "alloc-pool.h"
-#include "tree-mudflap.h"
#include "asan.h"
#include "tsan.h"
-#include "gimple.h"
#include "tree-ssa-alias.h"
+#include "internal-fn.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 "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
+#include <new>
+
static void general_init (const char *);
-static void do_compile (void);
+static void do_compile ();
static void process_options (void);
static void backend_init (void);
static int lang_dependent_init (const char *);
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;
}
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
{
- struct varpool_node *node;
+ varpool_node *node;
bool needed = true;
- node = varpool_get_node (decl);
+ node = varpool_node::get (decl);
if (!node && flag_ltrans)
needed = false;
- else if (node && node->finalized)
+ else if (node && node->definition)
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 */;
basically finished. */
if (in_lto_p || !flag_lto || flag_fat_lto_objects)
{
- /* Likewise for mudflap static object registrations. */
- if (flag_mudflap)
- mudflap_finish_file ();
-
/* File-scope initialization for AddressSanitizer. */
- if (flag_asan)
+ if (flag_sanitize & SANITIZE_ADDRESS)
asan_finish_file ();
- if (flag_tsan)
+ 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 ();
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);
two string formats, "i.j.k" and "i.j" when k is zero. As of
gmp-4.3.0, GMP always uses the 3 number format. */
#define GCC_GMP_STRINGIFY_VERSION3(X) #X
-#define GCC_GMP_STRINGIFY_VERSION2(X) GCC_GMP_STRINGIFY_VERSION3(X)
+#define GCC_GMP_STRINGIFY_VERSION2(X) GCC_GMP_STRINGIFY_VERSION3 (X)
#define GCC_GMP_VERSION_NUM(X,Y,Z) (((X) << 16L) | ((Y) << 8) | (Z))
#define GCC_GMP_VERSION \
GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL)
#if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,0) && __GNU_MP_VERSION_PATCHLEVEL == 0
-#define GCC_GMP_STRINGIFY_VERSION GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION) "." \
- GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_MINOR)
+#define GCC_GMP_STRINGIFY_VERSION \
+ GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION) "." \
+ GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_MINOR)
#else
-#define GCC_GMP_STRINGIFY_VERSION GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION) "." \
- GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_MINOR) "." \
- GCC_GMP_STRINGIFY_VERSION2(__GNU_MP_VERSION_PATCHLEVEL)
+#define GCC_GMP_STRINGIFY_VERSION \
+ GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION) "." \
+ GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_MINOR) "." \
+ GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_PATCHLEVEL)
#endif
fprintf (file,
file == stderr ? _(fmt2) : fmt2,
}
if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout;
- else
+ else if (!canonical_filename_eq (asm_file_name, name))
asm_out_file = fopen (asm_file_name, "w");
+ else
+ /* Use fatal_error (UNKOWN_LOCATION) instead of just fatal_error 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)
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
{
expanded_location loc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
- const char *raw_id, *id;
-
- /* Strip the scope prefix if any. */
- raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
- id = strrchr (raw_id, '.');
- if (id)
- id++;
+ /* We don't want to print the full qualified name because it can be long,
+ so we strip the scope prefix, but we may need to deal with the suffix
+ created by the compiler. */
+ const char *suffix
+ = strchr (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), '.');
+ const char *name
+ = lang_hooks.decl_printable_name (current_function_decl, 2);
+ if (suffix)
+ {
+ const char *dot = strchr (name, '.');
+ while (dot && strcasecmp (dot, suffix) != 0)
+ {
+ name = dot + 1;
+ dot = strchr (name, '.');
+ }
+ }
else
- id = raw_id;
+ {
+ const char *dot = strrchr (name, '.');
+ if (dot)
+ name = dot + 1;
+ }
fprintf (stack_usage_file,
"%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
lbasename (loc.file),
loc.line,
loc.column,
- id,
+ name,
stack_usage,
stack_usage_kind_str[stack_usage_kind]);
}
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);
}
}
}
/* 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;
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 ();
/* This must be done after global_init_params but before argument
processing. */
- init_ggc_heuristics();
- init_optimization_passes ();
+ init_ggc_heuristics ();
+
+ /* Create the singleton holder for global state.
+ Doing so also creates the pass manager and with it the passes. */
+ g = new gcc::context ();
+ symtab = ggc_cleared_alloc <symbol_table> ();
+
statistics_early_init ();
finish_params ();
}
maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT;
+ /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to -fdiagnostics-color=auto
+ if GCC_COLORS is in the environment, otherwise default to
+ -fdiagnostics-color=never, for other values default to that
+ -fdiagnostics-color={never,auto,always}. */
+ if (!global_options_set.x_flag_diagnostics_show_color)
+ switch ((int) DIAGNOSTICS_COLOR_DEFAULT)
+ {
+ case -1:
+ if (!getenv ("GCC_COLORS"))
+ break;
+ /* FALLTHRU */
+ case DIAGNOSTICS_COLOR_AUTO:
+ pp_show_color (global_dc->printer)
+ = colorize_init (DIAGNOSTICS_COLOR_AUTO);
+ break;
+ case DIAGNOSTICS_COLOR_YES:
+ pp_show_color (global_dc->printer)
+ = colorize_init (DIAGNOSTICS_COLOR_YES);
+ break;
+ default:
+ break;
+ }
+
/* 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_mudflap && flag_lto)
- sorry ("mudflap cannot be used together with link-time optimization");
+ if (flag_check_pointer_bounds)
+ {
+ if (targetm.chkp_bound_mode () == VOIDmode)
+ error ("-fcheck-pointer-bounds is not supported for this target");
+ }
/* 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
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
}
}
- if (flag_function_sections && profile_flag)
- {
- warning (0, "-ffunction-sections disabled; it makes profiling impossible");
- flag_function_sections = 0;
- }
-
#ifndef HAVE_prefetch
if (flag_prefetch_loop_arrays > 0)
{
if (!flag_stack_protect)
warn_stack_protect = 0;
- /* ??? Unwind info is not correct around the CFG unless either a frame
- pointer is present or A_O_A is set. Fixing this requires rewriting
- unwind info generation to be aware of the CFG and propagating states
- around edges. */
- if (flag_unwind_tables && !ACCUMULATE_OUTGOING_ARGS
- && flag_omit_frame_pointer)
+ /* Address Sanitizer needs porting to each target architecture. */
+
+ if ((flag_sanitize & SANITIZE_ADDRESS)
+ && !FRAME_GROWS_DOWNWARD)
{
- warning (0, "unwind tables currently require a frame pointer "
- "for correctness");
- flag_omit_frame_pointer = 0;
+ warning (0,
+ "-fsanitize=address and -fsanitize=kernel-address "
+ "are not supported for this target");
+ flag_sanitize &= ~SANITIZE_ADDRESS;
}
- /* Address Sanitizer needs porting to each target architecture. */
- if (flag_asan
- && (targetm.asan_shadow_offset == NULL
- || !FRAME_GROWS_DOWNWARD))
+ if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+ && targetm.asan_shadow_offset == NULL)
{
warning (0, "-fsanitize=address not supported for this target");
- flag_asan = 0;
+ flag_sanitize &= ~SANITIZE_ADDRESS;
}
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
DK_ERROR, UNKNOWN_LOCATION);
/* Save the current optimization options. */
- optimization_default_node = build_optimization_node ();
+ optimization_default_node = build_optimization_node (&global_options);
optimization_current_node = optimization_default_node;
}
/* 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)
+{
+ /* 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)
{
{
statistics_fini ();
- finish_optimization_passes ();
+ 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)
+ : m_use_TV_TOTAL (use_TV_TOTAL)
+{
+ if (!m_use_TV_TOTAL)
+ start_timevars ();
+}
- /* Stop timing and print the times. */
+toplev::~toplev ()
+{
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.
Exit code is FATAL_EXIT_CODE if can't open files or if there were
any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
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. */
/* 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)
+ if (warningcount || errorcount || werrorcount)
print_ignored_options ();
- diagnostic_finish (global_dc);
- /* Invoke registered plugin callbacks if any. */
+ /* Invoke registered plugin callbacks if any. Some plugins could
+ emit some diagnostics here. */
invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
+ diagnostic_finish (global_dc);
+
finalize_plugins ();
location_adhoc_data_fini (line_table);
- if (seen_error ())
+ if (seen_error () || werrorcount)
return (FATAL_EXIT_CODE);
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;
+
+ cgraph_c_finalize ();
+ cgraphunit_c_finalize ();
+ dwarf2out_c_finalize ();
+ gcse_c_finalize ();
+ ipa_cp_c_finalize ();
+ ipa_reference_c_finalize ();
+ params_c_finalize ();
+}