aboutsummaryrefslogtreecommitdiff
path: root/gcc/opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/opts.c')
-rw-r--r--gcc/opts.c433
1 files changed, 358 insertions, 75 deletions
diff --git a/gcc/opts.c b/gcc/opts.c
index 8af263a8498..61f87e20d9f 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -38,6 +38,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h" /* For OPTIMIZATION_OPTIONS. */
#include "insn-attr.h" /* For INSN_SCHEDULING. */
#include "target.h"
+/* APPLE LOCAL optimization pragmas 3124235/3420242 */
+#include "hashtab.h"
/* Value of the -G xx switch, and whether it was passed or not. */
unsigned HOST_WIDE_INT g_switch_value;
@@ -373,6 +375,21 @@ handle_option (const char **argv, unsigned int lang_mask)
*option->flag_var = value;
}
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+ else if (option->access_flag)
+ {
+ if (option->has_set_value)
+ {
+ if (value)
+ (option->access_flag) (option->set_value, 1);
+ else
+ (option->access_flag) (!option->set_value, 1);
+ }
+ else
+ (option->access_flag) (value, 1);
+ }
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
+
if (option->flags & lang_mask)
if (lang_hooks.handle_option (opt_index, arg, value) == 0)
result = 0;
@@ -428,54 +445,28 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
}
}
-/* Parse command line options and set default flag values. Do minimal
- options processing. */
-void
-decode_options (unsigned int argc, const char **argv)
-{
- unsigned int i, lang_mask;
-
- /* Perform language-specific options initialization. */
- lang_mask = lang_hooks.init_options (argc, argv);
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* Use OPTIMIZE and OPTIMIZE_SIZE to set default values of more
+ detailed flags that they control. CMDLINE tells whether this
+ is the first call, from the command line, or a later call due
+ to user pragmas. Those flags which are not safe to change on
+ a per-function basis are not reset when !CMDLINE. (FIXME:
+ There should be some better way to identify these than handcoding.) */
- lang_hooks.initialize_diagnostics (global_dc);
-
- /* Scan to see what optimization level has been specified. That will
- determine the default value of many flags. */
- for (i = 1; i < argc; i++)
- {
- if (!strcmp (argv[i], "-O"))
- {
- optimize = 1;
- optimize_size = 0;
- }
- else if (argv[i][0] == '-' && argv[i][1] == 'O')
- {
- /* Handle -Os, -O2, -O3, -O69, ... */
- const char *p = &argv[i][2];
-
- if ((p[0] == 's') && (p[1] == 0))
- {
- optimize_size = 1;
-
- /* Optimizing for size forces optimize to be 2. */
- optimize = 2;
- }
- else
- {
- const int optimize_val = read_integral_parameter (p, p - 2, -1);
- if (optimize_val != -1)
- {
- optimize = optimize_val;
- optimize_size = 0;
- }
- }
- }
- }
+void set_flags_from_O (unsigned int cmdline)
+{
+ /* Reset flags to the "raw" state before command line processing,
+ except for optimize and optimize_size. */
+ int save_optimize_size = optimize_size;
+ int save_optimize = optimize;
+ cl_pf_opts = cl_pf_opts_raw;
+ optimize = save_optimize;
+ optimize_size = save_optimize_size;
if (!optimize)
{
- flag_merge_constants = 0;
+ if (cmdline)
+ flag_merge_constants = 0;
}
if (optimize >= 1)
@@ -496,6 +487,13 @@ decode_options (unsigned int argc, const char **argv)
flag_tree_dce = 1;
flag_tree_dom = 1;
flag_tree_dse = 1;
+ /* APPLE LOCAL begin lno */
+ flag_tree_loop_im = 1;
+ flag_ivopts = 1;
+ flag_tree_vectorize = 0;
+ flag_tree_loop_linear = 0;
+ flag_tree_pre = 1;
+ /* APPLE LOCAL end lno */
flag_tree_ter = 1;
flag_tree_live_range_split = 1;
flag_tree_sra = 1;
@@ -525,18 +523,25 @@ decode_options (unsigned int argc, const char **argv)
flag_rerun_cse_after_loop = 1;
flag_rerun_loop_opt = 1;
flag_caller_saves = 1;
+/* APPLE LOCAL begin radar 4153339 */
+/** Removed - Note! Mainline will removed the entire -fforce-mem functionality.
flag_force_mem = 1;
+*/
+/* APPLE LOCAL end radar 4153339 */
flag_peephole2 = 1;
#ifdef INSN_SCHEDULING
flag_schedule_insns = 1;
flag_schedule_insns_after_reload = 1;
#endif
flag_regmove = 1;
- flag_strict_aliasing = 1;
flag_delete_null_pointer_checks = 1;
flag_reorder_blocks = 1;
- flag_reorder_functions = 1;
- flag_unit_at_a_time = 1;
+ if (cmdline)
+ {
+ flag_strict_aliasing = 1;
+ flag_reorder_functions = 1;
+ flag_unit_at_a_time = 1;
+ }
if (!optimize_size)
{
@@ -547,7 +552,8 @@ decode_options (unsigned int argc, const char **argv)
if (optimize >= 3)
{
- flag_inline_functions = 1;
+ if (cmdline)
+ flag_inline_functions = 1;
flag_unswitch_loops = 1;
flag_gcse_after_reload = 1;
}
@@ -557,7 +563,8 @@ decode_options (unsigned int argc, const char **argv)
align_loops = 1;
align_jumps = 1;
align_labels = 1;
- align_functions = 1;
+ if (cmdline)
+ align_functions = 1;
/* Don't reorder blocks when optimizing for size because extra
jump insns may be created; also barrier may create extra padding.
@@ -572,15 +579,93 @@ decode_options (unsigned int argc, const char **argv)
if (optimize_size)
{
- /* Inlining of very small functions usually reduces total size. */
- set_param_value ("max-inline-insns-single", 5);
- set_param_value ("max-inline-insns-auto", 5);
- flag_inline_functions = 1;
+ if (cmdline)
+ {
+ /* Inlining of very small functions usually reduces total size. */
+ set_param_value ("max-inline-insns-single", 5);
+ set_param_value ("max-inline-insns-auto", 5);
+ flag_inline_functions = 1;
+
+ /* We want to crossjump as much as possible. */
+ set_param_value ("min-crossjump-insns", 1);
+ }
+ }
+}
+
+/* Parse command line options and set default flag values. Do minimal
+ options processing. */
+void
+decode_options (unsigned int argc, const char **argv)
+{
+ unsigned int i, lang_mask;
+
+ /* Perform language-specific options initialization. */
+ lang_mask = lang_hooks.init_options (argc, argv);
+
+ lang_hooks.initialize_diagnostics (global_dc);
+
+ /* Make a backup copy of the default, pre-command line options.
+ Note this includes "optimize" and "optimize_size". */
+ cl_pf_opts_raw = cl_pf_opts;
+
+ /* Scan to see what optimization level has been specified. That will
+ determine the default value of many flags. */
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp (argv[i], "-O"))
+ {
+ optimize = 1;
+ optimize_size = 0;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'O')
+ {
+ /* Handle -Os, -O2, -O3, -O69, ... */
+ const char *p = &argv[i][2];
- /* We want to crossjump as much as possible. */
- set_param_value ("min-crossjump-insns", 1);
+ if ((p[0] == 's') && (p[1] == 0))
+ {
+ optimize_size = 1;
+
+ /* Optimizing for size forces optimize to be 2. */
+ optimize = 2;
+ }
+ else
+ {
+ const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ if (optimize_val != -1)
+ {
+ optimize = optimize_val;
+ optimize_size = 0;
+ }
+ }
+ }
+ /* APPLE LOCAL begin -fast or -fastf or -fastcp */
+ else if (argv[i][0] == '-' && argv[i][1] == 'f')
+ {
+ const char *p = &argv[i][2];
+ if (!strcmp(p, "ast"))
+ flag_fast = 1;
+ else if (!strcmp(p, "astf"))
+ flag_fastf = 1;
+ else if (!strcmp(p, "astcp"))
+ flag_fastcp = 1;
+ }
}
+ if (flag_fast || flag_fastf || flag_fastcp )
+ {
+ optimize = 3;
+ optimize_size = 0;
+ /* This goes here, rather than in rs6000.c, so that
+ later -fcommon can override it. */
+ if (flag_fast || flag_fastcp)
+ flag_no_common = 1;
+ }
+ /* APPLE LOCAL end -fast or -fastf or -fastcp */
+
+ set_flags_from_O (true);
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
+
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;
/* Set this to a special "uninitialized" value. The actual default is set
@@ -662,6 +747,13 @@ decode_options (unsigned int argc, const char **argv)
flag_reorder_blocks_and_partition = 0;
flag_reorder_blocks = 1;
}
+
+ /* APPLE LOCAL begin AV 3846092 */
+ /* We have apple local patch to disable -fstrict-aliasing when -O2 is used.
+ Do not disable it when -ftree-vectorize is used. */
+ if (optimize >= 2 && flag_tree_vectorize)
+ flag_strict_aliasing = 1;
+ /* APPLE LOCAL end AV 3846092 */
}
/* Handle target- and language-independent options. Return zero to
@@ -676,6 +768,12 @@ common_handle_option (size_t scode, const char *arg, int value)
switch (code)
{
+ /* APPLE LOCAL begin fat builds */
+ case OPT_arch:
+ /* Ignore for now. */
+ break;
+ /* APPLE LOCAL end fat builds */
+
case OPT__help:
print_help ();
exit_after_options = true;
@@ -755,21 +853,39 @@ common_handle_option (size_t scode, const char *arg, int value)
dump_base_name = arg;
break;
- case OPT_falign_functions_:
- align_functions = value;
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
+ /* APPLE LOCAL begin falign-jumps-max-skip */
+ case OPT_falign_jumps_max_skip_:
+ align_jumps_max_skip = value;
break;
- case OPT_falign_jumps_:
- align_jumps = value;
+ case OPT_falign_loops_max_skip_:
+ align_loops_max_skip = value;
break;
+ /* APPLE LOCAL end falign-jumps-max-skip */
- case OPT_falign_labels_:
- align_labels = value;
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
+ /* APPLE LOCAL begin predictive compilation */
+ case OPT_fpredictive_compilation:
+ predictive_compilation = 0;
break;
- case OPT_falign_loops_:
- align_loops = value;
- break;
+ case OPT_fpredictive_compilation_:
+ {
+ char* buf = xmalloc (strlen(arg) + 1);
+ sprintf (buf, "%d", value);
+ if (strcmp(buf, arg))
+ {
+ error ("argument to \"-fpredictive-compilation=\" should be a valid non-negative integer instead of \"%s\"", arg);
+ value = 0;
+ }
+ free(buf);
+ predictive_compilation = value;
+ break;
+ }
+ /* APPLE LOCAL end predictive compilation */
case OPT_fbranch_probabilities:
flag_branch_probabilities_set = true;
@@ -834,6 +950,9 @@ common_handle_option (size_t scode, const char *arg, int value)
profile_arc_flag_set = true;
break;
+ /* APPLE LOCAL begin add fuse-profile */
+ case OPT_fuse_profile:
+ /* APPLE LOCAL end add fuse-profile */
case OPT_fprofile_use:
if (!flag_branch_probabilities_set)
flag_branch_probabilities = value;
@@ -853,6 +972,9 @@ common_handle_option (size_t scode, const char *arg, int value)
#endif
break;
+ /* APPLE LOCAL begin add fcreate-profile */
+ case OPT_fcreate_profile:
+ /* APPLE LOCAL end add fcreate-profile */
case OPT_fprofile_generate:
if (!profile_arc_flag_set)
profile_arc_flag = value;
@@ -906,13 +1028,8 @@ common_handle_option (size_t scode, const char *arg, int value)
flag_random_seed = arg;
break;
- case OPT_fsched_verbose_:
-#ifdef INSN_SCHEDULING
- fix_sched_param ("verbose", arg);
- break;
-#else
- return 0;
-#endif
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
case OPT_fsched_stalled_insns_:
flag_sched_stalled_insns = value;
@@ -920,9 +1037,8 @@ common_handle_option (size_t scode, const char *arg, int value)
flag_sched_stalled_insns = -1;
break;
- case OPT_fsched_stalled_insns_dep_:
- flag_sched_stalled_insns_dep = value;
- break;
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */
case OPT_fstack_limit:
/* The real switch is -fno-stack-limit. */
@@ -970,6 +1086,12 @@ common_handle_option (size_t scode, const char *arg, int value)
flag_unroll_loops_set = true;
break;
+ /* APPLE LOCAL begin fwritable strings */
+ case OPT_fwritable_strings:
+ flag_writable_strings = value;
+ break;
+ /* APPLE LOCAL end fwritable strings */
+
case OPT_g:
set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
break;
@@ -1015,7 +1137,8 @@ common_handle_option (size_t scode, const char *arg, int value)
default:
/* If the flag was handled in a standard way, assume the lack of
processing here is intentional. */
- if (cl_options[scode].flag_var)
+ /* APPLE LOCAL optimization pragmas 3124235/3420242 */
+ if (cl_options[scode].flag_var || cl_options[scode].access_flag)
break;
abort ();
@@ -1097,6 +1220,7 @@ set_fast_math_flags (int set)
{
flag_signaling_nans = 0;
flag_rounding_math = 0;
+ flag_cx_limited_range = 1;
}
}
@@ -1132,6 +1256,12 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg)
#elif defined DBX_DEBUGGING_INFO
write_symbols = DBX_DEBUG;
#endif
+/* APPLE LOCAL begin dwarf */
+/* Even though DWARF2_DEBUGGING_INFO is defined, use stabs for
+ debugging symbols with -ggdb. Remove this local patch when we
+ switch to dwarf. */
+ write_symbols = DBX_DEBUG;
+/* APPLE LOCAL end dwarf */
}
if (write_symbols == NO_DEBUG)
@@ -1375,3 +1505,156 @@ wrap_help (const char *help, const char *item, unsigned int item_width)
}
while (remaining);
}
+
+/* APPLE LOCAL begin optimization pragmas 3124235/3420242 */
+/* Find or allocate a cl_perfunc_opts to represent the current
+ state of the per-function options, found in the global cl_pf_opts.
+ There are logically not many of these, usually only 1, so we use
+ a small hash table to avoid unnecessary copies. */
+
+static htab_t cl_perfunc_opts_hash_table;
+
+static hashval_t
+hash_cl_perfunc_opts (const void *p)
+{
+ const unsigned int *uip = p;
+ unsigned int i;
+ hashval_t h = 0;
+ for (i = 0; i < sizeof (struct cl_perfunc_opts) / sizeof (int); i++)
+ h += *uip++;
+ return h;
+}
+
+static int
+cmp_cl_perfunc_opts (const void *p, const void *q)
+{
+ return !memcmp(p, q, sizeof(struct cl_perfunc_opts));
+}
+
+static struct cl_perfunc_opts *
+make_perfunc_opts (void)
+{
+ PTR *slot;
+
+ if (!cl_perfunc_opts_hash_table)
+ cl_perfunc_opts_hash_table = htab_create (11, hash_cl_perfunc_opts,
+ cmp_cl_perfunc_opts, NULL);
+ slot = htab_find_slot (cl_perfunc_opts_hash_table, &cl_pf_opts,
+ INSERT);
+ if (*slot == NULL)
+ {
+ *slot = xmalloc (sizeof (struct cl_perfunc_opts));
+ memcpy (*slot, &cl_pf_opts, sizeof (struct cl_perfunc_opts));
+ }
+ return *slot;
+}
+
+/* Record the per-function opts in effect, and associate them with
+ a FUNCTION_DECL. The more natural way to do this is to put a field
+ in the struct function, but we want to record this info at a time
+ when the struct function has not been allocated yet. A hash table
+ isn't a great way to do this; maybe I'll think of something better. */
+
+static htab_t func_cl_pf_opts_mapping_hash_table;
+
+struct func_cl_pf_opts_mapping
+{
+ tree func;
+ /* The following pointer might or might not point to malloc'd storage.
+ Don't free it. */
+ struct cl_perfunc_opts *cl_pf_opts;
+};
+
+static hashval_t
+func_cl_pf_opts_mapping_hash (const void* entry)
+{
+ const struct func_cl_pf_opts_mapping *e = entry;
+ return htab_hash_pointer (e->func);
+}
+
+static int
+func_cl_pf_opts_mapping_eq (const void *p, const void *q)
+{
+ const struct func_cl_pf_opts_mapping *pp = p;
+ const struct func_cl_pf_opts_mapping *qq = q;
+ return pp->func == qq->func;
+}
+
+void
+record_func_cl_pf_opts_mapping (tree func)
+{
+ PTR *slot;
+ struct func_cl_pf_opts_mapping map, *entry;
+ if (!func_cl_pf_opts_mapping_hash_table)
+ func_cl_pf_opts_mapping_hash_table = htab_create (101,
+ func_cl_pf_opts_mapping_hash, func_cl_pf_opts_mapping_eq, 0);
+ map.func = func;
+ slot = htab_find_slot (func_cl_pf_opts_mapping_hash_table, &map, INSERT);
+ if (*slot)
+ entry = *slot;
+ else
+ {
+ entry = xmalloc (sizeof (struct func_cl_pf_opts_mapping));
+ entry->func = func;
+ *slot = entry;
+ }
+ entry->cl_pf_opts = make_perfunc_opts ();
+}
+
+void
+restore_func_cl_pf_opts_mapping (tree func)
+{
+ PTR *slot;
+ struct func_cl_pf_opts_mapping map, *entry;
+ /* This will be the case for languages whose FEs don't call
+ record_func_cl_pf_opts_mapping. */
+ if (!func_cl_pf_opts_mapping_hash_table)
+ return;
+ map.func = func;
+ slot = htab_find_slot (func_cl_pf_opts_mapping_hash_table, &map, INSERT);
+ if (*slot)
+ entry = *slot;
+ else
+ {
+ /* This means we did not call record_func_cl_opts_pf_mapping earlier.
+ Currently this happens for functions defined inside a C++ class;
+ we just record a token stream for those, which doesn't include
+ pragmas in a usable fashion. For now just use the command line
+ options for these. */
+ entry = xmalloc (sizeof (struct func_cl_pf_opts_mapping));
+ entry->func = func;
+ entry->cl_pf_opts = &cl_pf_opts_cooked;
+ *slot = entry;
+ }
+ cl_pf_opts = *(entry->cl_pf_opts);
+}
+
+void
+copy_func_cl_pf_opts_mapping (tree funcold, tree funcnew)
+{
+ PTR *slot;
+ struct func_cl_pf_opts_mapping map, *entry;
+ struct cl_perfunc_opts *oldcl_pf_opts;
+ /* This will be the case for languages whose FEs don't call
+ record_func_cl_pf_opts_mapping. */
+ if (!func_cl_pf_opts_mapping_hash_table)
+ return;
+ map.func = funcold;
+ slot = htab_find_slot (func_cl_pf_opts_mapping_hash_table, &map, NO_INSERT);
+ gcc_assert (*slot);
+ entry = *slot;
+ oldcl_pf_opts = entry->cl_pf_opts;
+
+ map.func = funcnew;
+ slot = htab_find_slot (func_cl_pf_opts_mapping_hash_table, &map, INSERT);
+ if (*slot)
+ entry = *slot;
+ else
+ {
+ entry = xmalloc (sizeof (struct func_cl_pf_opts_mapping));
+ entry->func = funcnew;
+ *slot = entry;
+ }
+ entry->cl_pf_opts = oldcl_pf_opts;
+}
+/* APPLE LOCAL end optimization pragmas 3124235/3420242 */