aboutsummaryrefslogtreecommitdiff
path: root/gcc/toplev.c
diff options
context:
space:
mode:
authorMartin Liska <marxin@gcc.gnu.org>2018-07-04 07:51:08 +0000
committerMartin Liska <marxin@gcc.gnu.org>2018-07-04 07:51:08 +0000
commitc518c1025b435e1c593a745036fc9b8ed04c5819 (patch)
tree75ee9f7156d26af39f332f3fab50c5012d340427 /gcc/toplev.c
parentdd047c67e45c244c147a8244671154c77a9bda47 (diff)
downloadgcc-c518c1025b435e1c593a745036fc9b8ed04c5819.zip
gcc-c518c1025b435e1c593a745036fc9b8ed04c5819.tar.gz
gcc-c518c1025b435e1c593a745036fc9b8ed04c5819.tar.bz2
[multiple changes]
2018-07-04 Denys Vlasenko <dvlasenk@redhat.com> Martin Liska <mliska@suse.cz> PR middle-end/66240 PR target/45996 PR c/84100 * common.opt: Rename align options with 'str_' prefix. * common/config/i386/i386-common.c (set_malign_value): New function. (ix86_handle_option): Use it to set -falign-* options/ * config/aarch64/aarch64-protos.h (struct tune_params): Change type from int to string. * config/aarch64/aarch64.c: Update default values from int to string. * config/alpha/alpha.c (alpha_override_options_after_change): Likewise. * config/arm/arm.c (arm_override_options_after_change_1): Likewise. * config/i386/dragonfly.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. * config/i386/freebsd.h (SUBALIGN_LOG): New. (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. * config/i386/gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. * config/i386/gnu-user.h (SUBALIGN_LOG): New. (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. * config/i386/i386.c (struct ptt): Change type from int to string. (ix86_default_align): Set default values. * config/i386/i386.h (ASM_OUTPUT_MAX_SKIP_PAD): Print max skip conditionally. * config/i386/iamcu.h (SUBALIGN_LOG): New. (ASM_OUTPUT_MAX_SKIP_ALIGN): * config/i386/lynx.h (ASM_OUTPUT_MAX_SKIP_ALIGN): * config/i386/netbsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. * config/i386/openbsdelf.h (SUBALIGN_LOG): New. (ASM_OUTPUT_MAX_SKIP_ALIGN) Print max skip conditionally.: * config/i386/x86-64.h (SUBALIGN_LOG): New. (ASM_OUTPUT_MAX_SKIP_ALIGN): Print max skip conditionally. (ASM_OUTPUT_MAX_SKIP_PAD): Likewise. * config/ia64/ia64.c (ia64_option_override): Set default values for alignment options. * config/m68k/m68k.c: Handle new str_align_* options. * config/mips/mips.c (mips_set_compression_mode): Change type of constants. (mips_option_override): Set default values for options. * config/powerpcspe/powerpcspe.c (rs6000_option_override_internal): Likewise. * config/rs6000/rs6000.c (rs6000_option_override_internal): Likewise. * config/rx/rx.c (rx_option_override): Likewise. * config/rx/rx.h (JUMP_ALIGN): Use align_jumps_log. (LABEL_ALIGN): Use align_labels_log. (LOOP_ALIGN): Use align_loops_align. * config/s390/s390.c (s390_asm_output_function_label): Use new macros. * config/sh/sh.c (sh_override_options_after_change): Change type of constants. * config/spu/spu.c (spu_sched_init): Likewise. * config/sparc/sparc.c (sparc_option_override): Set default values for options. * config/visium/visium.c (visium_option_override): Likewise. * config/visium/visium.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Do not emit p2align format with last argument if it's not needed. * doc/invoke.texi: Document extended format of -falign-*. * final.c: Use align_labels alignment. * flags.h (struct target_flag_state): Change type to use align_flags. (struct align_flags_tuple): New. (struct align_flags): Likewise. (align_loops_log): Redefine macro to use new types. (align_loops_max_skip): Redefine macro to use new types. (align_jumps_log): Redefine macro to use new types. (align_jumps_max_skip): Redefine macro to use new types. (align_labels_log): Redefine macro to use new types. (align_labels_max_skip): Redefine macro to use new types. (align_functions_log): Redefine macro to use new types. (align_loops): Redefine macro to use new types. (align_jumps): Redefine macro to use new types. (align_labels): Redefine macro to use new types. (align_functions): Redefine macro to use new types. (align_functions_max_skip): Redefine macro to use new types. (align_loops_value): New macro. (align_jumps_value): New macro. (align_labels_value): New macro. (align_functions_value): New macro. * function.c (invoke_set_current_function_hook): Propagate alignment values from flags to global variables default in topleev.h. * ipa-icf.c (sem_function::equals_wpa): Use cl_optimization_option_eq instead of memcmp. * lto-streamer.h (cl_optimization_stream_out): Support streaming of string types. (cl_optimization_stream_in): Likewise. * optc-save-gen.awk: Support strings in cl_optimization. * opth-gen.awk: Likewise. * opts.c (finish_options): Remove error checking of invalid value ranges. (MAX_CODE_ALIGN): Remove. (MAX_CODE_ALIGN_VALUE): Likewise. (parse_and_check_align_values): New function. (check_alignment_argument): Likewise. (common_handle_option): Use check_alignment_argument. * opts.h (parse_and_check_align_values): Declare. * toplev.c (init_alignments): Remove. (read_log_maxskip): New. (parse_N_M): Likewise. (parse_alignment_opts): Likewise. (backend_init_target): Remove usage of init_alignments. * toplev.h (parse_alignment_opts): Declare. * tree-streamer-in.c (streamer_read_tree_bitfields): Add new argument. * tree-streamer-out.c (streamer_write_tree_bitfields): Likewise. * tree.c (cl_option_hasher::equal): New. * varasm.c: Use new global macros. 2018-07-04 Martin Liska <mliska@suse.cz> PR middle-end/66240 PR target/45996 PR c/84100 * lto.c (compare_tree_sccs_1): Use cl_optimization_option_eq instead of memcmp. 2018-07-04 Martin Liska <mliska@suse.cz> PR middle-end/66240 PR target/45996 PR c/84100 * gcc.dg/pr84100.c (foo): * gcc.target/i386/falign-functions-2.c: New test. * gcc.target/i386/falign-functions.c: New test. From-SVN: r262375
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r--gcc/toplev.c136
1 files changed, 112 insertions, 24 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c
index d108096..cf7bab6 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1197,29 +1197,120 @@ target_supports_section_anchors_p (void)
return true;
}
-/* Default the align_* variables to 1 if they're still unset, and
- set up the align_*_log variables. */
+/* Parse "N[:M][:...]" into struct align_flags A.
+ VALUES contains parsed values (in reverse order), all processed
+ values are popped. */
+
static void
-init_alignments (void)
+read_log_maxskip (auto_vec<unsigned> &values, align_flags_tuple *a)
{
- if (align_loops <= 0)
- align_loops = 1;
- if (align_loops_max_skip > align_loops)
- align_loops_max_skip = align_loops - 1;
- align_loops_log = floor_log2 (align_loops * 2 - 1);
- if (align_jumps <= 0)
- align_jumps = 1;
- if (align_jumps_max_skip > align_jumps)
- align_jumps_max_skip = align_jumps - 1;
- align_jumps_log = floor_log2 (align_jumps * 2 - 1);
- if (align_labels <= 0)
- align_labels = 1;
- align_labels_log = floor_log2 (align_labels * 2 - 1);
- if (align_labels_max_skip > align_labels)
- align_labels_max_skip = align_labels - 1;
- if (align_functions <= 0)
- align_functions = 1;
- align_functions_log = floor_log2 (align_functions * 2 - 1);
+ unsigned n = values.pop ();
+ if (n != 0)
+ a->log = floor_log2 (n * 2 - 1);
+ if (values.is_empty ())
+ a->maxskip = n ? n - 1 : 0;
+ else
+ {
+ unsigned m = values.pop ();
+ if (m > n)
+ m = n;
+ /* -falign-foo=N:M means M-1 max bytes of padding, not M. */
+ if (m > 0)
+ m--;
+ a->maxskip = m;
+ }
+}
+
+/* Parse "N[:M[:N2[:M2]]]" string FLAG into a pair of struct align_flags. */
+
+static void
+parse_N_M (const char *flag, align_flags &a, unsigned int min_align_log)
+{
+ if (flag)
+ {
+ static hash_map <nofree_string_hash, align_flags> cache;
+ align_flags *entry = cache.get (flag);
+ if (entry)
+ {
+ a = *entry;
+ return;
+ }
+
+ auto_vec<unsigned> result_values;
+ bool r = parse_and_check_align_values (flag, NULL, result_values, false,
+ UNKNOWN_LOCATION);
+ if (!r)
+ return;
+
+ /* Reverse values for easier manipulation. */
+ result_values.reverse ();
+
+ read_log_maxskip (result_values, &a.levels[0]);
+ if (!result_values.is_empty ())
+ read_log_maxskip (result_values, &a.levels[1]);
+#ifdef SUBALIGN_LOG
+ else
+ {
+ /* N2[:M2] is not specified. This arch has a default for N2.
+ Before -falign-foo=N:M:N2:M2 was introduced, x86 had a tweak.
+ -falign-functions=N with N > 8 was adding secondary alignment.
+ -falign-functions=10 was emitting this before every function:
+ .p2align 4,,9
+ .p2align 3
+ Now this behavior (and more) can be explicitly requested:
+ -falign-functions=16:10:8
+ Retain old behavior if N2 is missing: */
+
+ int align = 1 << a.levels[0].log;
+ int subalign = 1 << SUBALIGN_LOG;
+
+ if (a.levels[0].log > SUBALIGN_LOG
+ && a.levels[0].maxskip >= subalign - 1)
+ {
+ /* Set N2 unless subalign can never have any effect. */
+ if (align > a.levels[0].maxskip + 1)
+ a.levels[1].log = SUBALIGN_LOG;
+ }
+ }
+#endif
+
+ /* Cache seen value. */
+ cache.put (flag, a);
+ }
+ else
+ {
+ /* Reset values to zero. */
+ for (unsigned i = 0; i < 2; i++)
+ {
+ a.levels[i].log = 0;
+ a.levels[i].maxskip = 0;
+ }
+ }
+
+ if ((unsigned int)a.levels[0].log < min_align_log)
+ {
+ a.levels[0].log = min_align_log;
+ a.levels[0].maxskip = (1 << min_align_log) - 1;
+ }
+}
+
+/* Minimum alignment requirements, if arch has them. */
+
+unsigned int min_align_loops_log = 0;
+unsigned int min_align_jumps_log = 0;
+unsigned int min_align_labels_log = 0;
+unsigned int min_align_functions_log = 0;
+
+/* Process -falign-foo=N[:M[:N2[:M2]]] options. */
+
+void
+parse_alignment_opts (void)
+{
+ parse_N_M (str_align_loops, state_align_loops, min_align_loops_log);
+ parse_N_M (str_align_jumps, state_align_jumps, min_align_jumps_log);
+ parse_N_M (str_align_labels, state_align_labels, min_align_labels_log);
+ parse_N_M (str_align_functions, state_align_functions,
+ min_align_functions_log);
}
/* Process the options that have been parsed. */
@@ -1722,9 +1813,6 @@ process_options (void)
static void
backend_init_target (void)
{
- /* Initialize alignment variables. */
- init_alignments ();
-
/* This depends on stack_pointer_rtx. */
init_fake_stack_mems ();