From c518c1025b435e1c593a745036fc9b8ed04c5819 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 4 Jul 2018 07:51:08 +0000 Subject: [multiple changes] 2018-07-04 Denys Vlasenko Martin Liska 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 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 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 --- gcc/toplev.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 24 deletions(-) (limited to 'gcc/toplev.c') 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 &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 cache; + align_flags *entry = cache.get (flag); + if (entry) + { + a = *entry; + return; + } + + auto_vec 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 (); -- cgit v1.1