From e6de53356769e13178975c18b4ce019a800ea946 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 17 Jul 2018 11:19:27 +0200 Subject: [PATCH] Clean up of new format of -falign-FOO. 2018-07-17 Martin Liska * align.h: New file. * config/alpha/alpha.c (alpha_align_insns_1): Use align_functions directly. * config/i386/i386.c (ix86_avoid_jump_mispredicts): Use new return type align_flags of label_to_alignment. * config/m32r/m32r.h (LOOP_ALIGN): Wrap returned values into align_flags class. * config/m68k/m68k.c: Do not use removed align_labels_value and align_loops_value. * config/nds32/nds32.h (JUMP_ALIGN): Wrap result into align_flags class. (LOOP_ALIGN): Likewise. (LABEL_ALIGN): Likewise. * config/powerpcspe/powerpcspe.c (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): Remove not used macro. (rs6000_loop_align): Change return type to align_flags. (rs6000_loop_align_max_skip): Remove. * config/rs6000/rs6000-protos.h (rs6000_loop_align): Change return type to align_flags. * config/rs6000/rs6000.c (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): Remove not used macro. (rs6000_loop_align): Change return type to align_flags. (rs6000_loop_align_max_skip): Remove. * config/rx/rx.h (JUMP_ALIGN): Wrap integer values * config/rx/rx-protos.h (rx_align_for_label): Make it static function. * config/rx/rx.c (rx_align_for_label): Change return type to align_flags. (rx_max_skip_for_label): Remove TARGET_ASM_*_ALIGN_MAX_SKIP macro definitions. into align_flags class. (LABEL_ALIGN): Likewise. (LOOP_ALIGN): Likewise. * config/s390/s390.c (s390_label_align): Use align_flags class member. (s390_asm_output_function_label): Likewise. * config/sh/sh.c (sh_override_options_after_change): Use align_flags class directly without macros. (find_barrier): Likewise. (barrier_align): Likewise. (sh_loop_align): Likewise. * config/spu/spu.c (spu_option_override): Use align_flags_tuple::get_value instead of removed macros. (spu_sched_init): Likewise. * config/spu/spu.h (GTY): Likewise. * config/visium/visium.c (visium_option_override): Set "8" as default secondary alignment. * config/visium/visium.h (SUBALIGN_LOG): Define to 3 in order to guarantee secondary alignment of 8. * coretypes.h: Include align.h header file. * doc/tm.texi: Remove TARGET_ASM_JUMP_ALIGN_MAX_SKIP, TARGET_ASM_LOOP_ALIGN_MAX_SKIP, TARGET_ASM_LABEL_ALIGN_MAX_SKIP and TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP macros. * doc/tm.texi.in: Likewise. * final.c (struct label_alignment): Remove not used structure. (LABEL_ALIGN): Change type to align_flags. (LOOP_ALIGN): Likewise. (JUMP_ALIGN): Likewise. (default_loop_align_max_skip): Remove. (default_label_align_max_skip): Likewise. (default_jump_align_max_skip): Likewise. (default_label_align_after_barrier_max_skip): (LABEL_TO_ALIGNMENT): Change to access label_align vector. (LABEL_TO_MAX_SKIP): Remove. (label_to_alignment): Return align_flags type instead of integer. (label_to_max_skip): Remove. (align_fuzz): Use align_flags type. (compute_alignments): Use align_flags type and use align_flags::max to combine multiple alignments. (grow_label_align): Grow vec instead of C array. (update_alignments): Assign just LABEL_TO_ALIGNMENT. (shorten_branches): Use align_flags type and use align_flags::max to combine multiple alignments. (final_scan_insn_1): Remove usage of secondary alignment that comes from label alignment, but instead use proper secondary alignment which is computed in grow_label_align. * flags.h (struct align_flags_tuple): Move to align.h. (struct align_flags): Likewise. (state_align_loops): Rename to align_loops. (state_align_jumps): Rename to align_jumps. (state_align_labels): Rename to align_labels. (state_align_functions): Rename to align_functions. (align_loops_log): Remove. (align_jumps_log): Remove. (align_labels_log): Remove. (align_functions_log): Remove. (align_loops_max_skip): Remove. (align_jumps_max_skip): Remove. (align_labels_max_skip): Remove. (align_functions_max_skip): Remove. (align_loops_value): Remove. (align_jumps_value): Remove. (align_labels_value): Remove. (align_functions_value): Remove. * output.h (label_to_alignment): Change return type to align_flags. (label_to_max_skip): Remove. * target.def: Remove loop_align_max_skip, label_align_max_skip, jump_align_max_skip macros. * targhooks.h (default_loop_align_max_skip): Remove. (default_label_align_max_skip): Likewise. (default_jump_align_max_skip): Likewise. (default_label_align_after_barrier_max_skip): Remove. * toplev.c (read_log_maxskip): Use ::normalize function. (parse_N_M): Remove not used argument and also call ::normalize. (parse_alignment_opts): Do not pass unused arguments. * varasm.c (assemble_start_function): Use directly align_functions instead of removed macros. * system.h: Do not poison removed macros. 2018-07-17 Martin Liska * gcc.target/powerpc/loop_align.c: Update scanned pattern. From-SVN: r262804 --- gcc/ChangeLog | 109 ++++++++++ gcc/align.h | 76 +++++++ gcc/config/alpha/alpha.c | 5 +- gcc/config/i386/i386.c | 5 +- gcc/config/m32r/m32r.h | 3 +- gcc/config/m68k/m68k.c | 10 +- gcc/config/nds32/nds32.h | 9 +- gcc/config/powerpcspe/powerpcspe.c | 18 +- gcc/config/rs6000/rs6000-protos.h | 2 +- gcc/config/rs6000/rs6000.c | 18 +- gcc/config/rx/rx-protos.h | 2 +- gcc/config/rx/rx.c | 59 +++--- gcc/config/rx/rx.h | 6 +- gcc/config/s390/s390.c | 9 +- gcc/config/sh/sh.c | 19 +- gcc/config/spu/spu.c | 6 +- gcc/config/spu/spu.h | 2 +- gcc/config/visium/visium.c | 2 +- gcc/config/visium/visium.h | 13 +- gcc/coretypes.h | 1 + gcc/doc/tm.texi | 24 --- gcc/doc/tm.texi.in | 8 - gcc/final.c | 188 +++++------------- gcc/flags.h | 38 +--- gcc/output.h | 6 +- gcc/system.h | 2 - gcc/target.def | 40 ---- gcc/targhooks.h | 4 - gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.target/powerpc/loop_align.c | 2 +- gcc/toplev.c | 44 ++-- gcc/varasm.c | 14 +- 32 files changed, 358 insertions(+), 390 deletions(-) create mode 100644 gcc/align.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 64aab92a08f..80512556ecc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,112 @@ +2018-07-17 Martin Liska + + * align.h: New file. + * config/alpha/alpha.c (alpha_align_insns_1): Use align_functions directly. + * config/i386/i386.c (ix86_avoid_jump_mispredicts): Use new return type + align_flags of label_to_alignment. + * config/m32r/m32r.h (LOOP_ALIGN): Wrap returned values into align_flags + class. + * config/m68k/m68k.c: Do not use removed align_labels_value and + align_loops_value. + * config/nds32/nds32.h (JUMP_ALIGN): Wrap result into align_flags class. + (LOOP_ALIGN): Likewise. + (LABEL_ALIGN): Likewise. + * config/powerpcspe/powerpcspe.c (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): + Remove not used macro. + (rs6000_loop_align): Change return type to align_flags. + (rs6000_loop_align_max_skip): Remove. + * config/rs6000/rs6000-protos.h (rs6000_loop_align): + Change return type to align_flags. + * config/rs6000/rs6000.c (TARGET_ASM_LOOP_ALIGN_MAX_SKIP): + Remove not used macro. + (rs6000_loop_align): Change return type to align_flags. + (rs6000_loop_align_max_skip): Remove. + * config/rx/rx.h (JUMP_ALIGN): Wrap integer values + * config/rx/rx-protos.h (rx_align_for_label): Make it + static function. + * config/rx/rx.c (rx_align_for_label): Change return type + to align_flags. + (rx_max_skip_for_label): Remove TARGET_ASM_*_ALIGN_MAX_SKIP + macro definitions. + into align_flags class. + (LABEL_ALIGN): Likewise. + (LOOP_ALIGN): Likewise. + * config/s390/s390.c (s390_label_align): Use align_flags + class member. + (s390_asm_output_function_label): Likewise. + * config/sh/sh.c (sh_override_options_after_change): + Use align_flags class directly without macros. + (find_barrier): Likewise. + (barrier_align): Likewise. + (sh_loop_align): Likewise. + * config/spu/spu.c (spu_option_override): + Use align_flags_tuple::get_value instead of removed macros. + (spu_sched_init): Likewise. + * config/spu/spu.h (GTY): Likewise. + * config/visium/visium.c (visium_option_override): + Set "8" as default secondary alignment. + * config/visium/visium.h (SUBALIGN_LOG): Define to 3 + in order to guarantee secondary alignment of 8. + * coretypes.h: Include align.h header file. + * doc/tm.texi: Remove TARGET_ASM_JUMP_ALIGN_MAX_SKIP, + TARGET_ASM_LOOP_ALIGN_MAX_SKIP, TARGET_ASM_LABEL_ALIGN_MAX_SKIP + and TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP macros. + * doc/tm.texi.in: Likewise. + * final.c (struct label_alignment): Remove not used structure. + (LABEL_ALIGN): Change type to align_flags. + (LOOP_ALIGN): Likewise. + (JUMP_ALIGN): Likewise. + (default_loop_align_max_skip): Remove. + (default_label_align_max_skip): Likewise. + (default_jump_align_max_skip): Likewise. + (default_label_align_after_barrier_max_skip): + (LABEL_TO_ALIGNMENT): Change to access label_align vector. + (LABEL_TO_MAX_SKIP): Remove. + (label_to_alignment): Return align_flags type instead of integer. + (label_to_max_skip): Remove. + (align_fuzz): Use align_flags type. + (compute_alignments): Use align_flags type and use align_flags::max + to combine multiple alignments. + (grow_label_align): Grow vec instead of C array. + (update_alignments): Assign just LABEL_TO_ALIGNMENT. + (shorten_branches): Use align_flags type and use align_flags::max + to combine multiple alignments. + (final_scan_insn_1): Remove usage of secondary alignment that comes + from label alignment, but instead use proper secondary alignment + which is computed in grow_label_align. + * flags.h (struct align_flags_tuple): Move to align.h. + (struct align_flags): Likewise. + (state_align_loops): Rename to align_loops. + (state_align_jumps): Rename to align_jumps. + (state_align_labels): Rename to align_labels. + (state_align_functions): Rename to align_functions. + (align_loops_log): Remove. + (align_jumps_log): Remove. + (align_labels_log): Remove. + (align_functions_log): Remove. + (align_loops_max_skip): Remove. + (align_jumps_max_skip): Remove. + (align_labels_max_skip): Remove. + (align_functions_max_skip): Remove. + (align_loops_value): Remove. + (align_jumps_value): Remove. + (align_labels_value): Remove. + (align_functions_value): Remove. + * output.h (label_to_alignment): Change return type to align_flags. + (label_to_max_skip): Remove. + * target.def: Remove loop_align_max_skip, label_align_max_skip, + jump_align_max_skip macros. + * targhooks.h (default_loop_align_max_skip): Remove. + (default_label_align_max_skip): Likewise. + (default_jump_align_max_skip): Likewise. + (default_label_align_after_barrier_max_skip): Remove. + * toplev.c (read_log_maxskip): Use ::normalize function. + (parse_N_M): Remove not used argument and also call ::normalize. + (parse_alignment_opts): Do not pass unused arguments. + * varasm.c (assemble_start_function): Use directly align_functions + instead of removed macros. + * system.h: Do not poison removed macros. + 2018-07-17 Jakub Jelinek PR middle-end/86539 diff --git a/gcc/align.h b/gcc/align.h new file mode 100644 index 00000000000..5a5d6c752a3 --- /dev/null +++ b/gcc/align.h @@ -0,0 +1,76 @@ +/* Alignment-related classes. + Copyright (C) 2018 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Align flags tuple with alignment in log form and with a maximum skip. */ + +struct align_flags_tuple +{ + /* Values of the -falign-* flags: how much to align labels in code. + log is "align to 2^log" (so 0 means no alignment). + maxskip is the maximum allowed amount of padding to insert. */ + int log; + int maxskip; + + /* Normalize filled values so that maxskip is not bigger than 1 << log. */ + void normalize () + { + int n = (1 << log); + if (maxskip > n) + maxskip = n - 1; + } + + /* Return original value of an alignment flag. */ + int get_value () + { + return maxskip + 1; + } +}; + +/* Alignment flags is structure used as value of -align-* options. + It's used in target-dependant code. */ + +struct align_flags +{ + /* Default constructor. */ + align_flags (int log0 = 0, int maxskip0 = 0, int log1 = 0, int maxskip1 = 0) + { + levels[0] = {log0, maxskip0}; + levels[1] = {log1, maxskip1}; + normalize (); + } + + /* Normalize both components of align_flags. */ + void normalize () + { + for (unsigned i = 0; i < 2; i++) + levels[i].normalize (); + } + + /* Get alignment that is common bigger alignment of alignments F0 and F1. */ + static align_flags max (const align_flags f0, const align_flags f1) + { + int log0 = MAX (f0.levels[0].log, f1.levels[0].log); + int maxskip0 = MAX (f0.levels[0].maxskip, f1.levels[0].maxskip); + int log1 = MAX (f0.levels[1].log, f1.levels[1].log); + int maxskip1 = MAX (f0.levels[1].maxskip, f1.levels[1].maxskip); + return align_flags (log0, maxskip0, log1, maxskip1); + } + + align_flags_tuple levels[2]; +}; diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 9adfe159381..993d2324464 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -9269,7 +9269,7 @@ alpha_align_insns_1 (unsigned int max_align, /* Let shorten branches care for assigning alignments to code labels. */ shorten_branches (get_insns ()); - unsigned int option_alignment = align_functions_max_skip + 1; + unsigned int option_alignment = align_functions.levels[0].get_value (); if (option_alignment < 4) align = 4; else if ((unsigned int) option_alignment < max_align) @@ -9291,7 +9291,8 @@ alpha_align_insns_1 (unsigned int max_align, /* When we see a label, resync alignment etc. */ if (LABEL_P (i)) { - unsigned int new_align = 1 << label_to_alignment (i); + unsigned int new_align + = label_to_alignment (i).levels[0].get_value (); if (new_align >= align) { diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ccc24e375ad..2b7e9489ed8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -41927,8 +41927,9 @@ ix86_avoid_jump_mispredicts (void) if (LABEL_P (insn)) { - int align = label_to_alignment (insn); - int max_skip = label_to_max_skip (insn); + align_flags alignment = label_to_alignment (insn); + int align = alignment.levels[0].log; + int max_skip = alignment.levels[0].maxskip; if (max_skip > 15) max_skip = 15; diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 426398d2957..4eb15a7ba60 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -866,7 +866,8 @@ L2: .word STATIC of a loop. */ /* On the M32R, align loops to 32 byte boundaries (cache line size) if -malign-loops. */ -#define LOOP_ALIGN(LABEL) (TARGET_ALIGN_LOOPS ? 5 : 0) +#define LOOP_ALIGN(LABEL) ((TARGET_ALIGN_LOOPS \ + ? align_flags (5) : align_flags ())) /* Define this to be the maximum number of insns to move around when moving a loop test from the top of a loop to the bottom diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index cea5c0ecab5..ef8604ebe3d 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -653,15 +653,17 @@ m68k_option_override (void) #ifndef ASM_OUTPUT_ALIGN_WITH_NOP parse_alignment_opts (); - if (align_labels_value > 2) + int label_alignment = align_labels.levels[0].get_value (); + if (label_alignment > 2) { - warning (0, "-falign-labels=%d is not supported", align_labels_value); + warning (0, "-falign-labels=%d is not supported", label_alignment); str_align_labels = "1"; } - if (align_loops_value > 2) + int loop_alignment = align_loops.levels[0].get_value (); + if (loop_alignment > 2) { - warning (0, "-falign-loops=%d is not supported", align_loops_value); + warning (0, "-falign-loops=%d is not supported", loop_alignment); str_align_loops = "1"; } #endif diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 9e36c8f2fac..3aac6a21bb8 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -1630,13 +1630,16 @@ enum reg_class #define DWARF2_UNWIND_INFO 1 #define JUMP_ALIGN(x) \ - (align_jumps_log ? align_jumps_log : nds32_target_alignment (x)) + (align_jumps.levels[0].log \ + ? align_jumps : align_flags (nds32_target_alignment (x))) #define LOOP_ALIGN(x) \ - (align_loops_log ? align_loops_log : nds32_target_alignment (x)) + (align_loops.levels[0].log \ + ? align_loops : align_flags (nds32_target_alignment (x))) #define LABEL_ALIGN(x) \ - (align_labels_log ? align_labels_log : nds32_target_alignment (x)) + (align_labels.levels[0].log \ + ? align_labels : align_flags (nds32_target_alignment (x))) #define ASM_OUTPUT_ALIGN(stream, power) \ fprintf (stream, "\t.align\t%d\n", power) diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c index 80f67de12fc..7dd24e47641 100644 --- a/gcc/config/powerpcspe/powerpcspe.c +++ b/gcc/config/powerpcspe/powerpcspe.c @@ -1829,9 +1829,6 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn -#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP -#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip - #undef TARGET_MD_ASM_ADJUST #define TARGET_MD_ASM_ADJUST rs6000_md_asm_adjust @@ -5723,7 +5720,7 @@ rs6000_builtin_mask_for_load (void) } /* Implement LOOP_ALIGN. */ -int +align_flags rs6000_loop_align (rtx label) { basic_block bb; @@ -5731,7 +5728,7 @@ rs6000_loop_align (rtx label) /* Don't override loop alignment if -falign-loops was specified. */ if (!can_override_loop_align) - return align_loops_log; + return align_loops; bb = BLOCK_FOR_INSN (label); ninsns = num_loop_insns(bb->loop_father); @@ -5744,16 +5741,9 @@ rs6000_loop_align (rtx label) || rs6000_cpu == PROCESSOR_POWER7 || rs6000_cpu == PROCESSOR_POWER8 || rs6000_cpu == PROCESSOR_POWER9)) - return 5; + return align_flags (5); else - return align_loops_log; -} - -/* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */ -static int -rs6000_loop_align_max_skip (rtx_insn *label) -{ - return (1 << rs6000_loop_align (label)) - 1; + return align_loops; } /* Return true iff, data reference of TYPE can reach vector alignment (16) diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index d548d801fa4..714b8a8f43a 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -156,7 +156,7 @@ extern rtx rs6000_machopic_legitimize_pic_address (rtx, machine_mode, rtx); extern rtx rs6000_address_for_fpconvert (rtx); extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool); -extern int rs6000_loop_align (rtx); +extern align_flags rs6000_loop_align (rtx); extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool); #endif /* RTX_CODE */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 62b8ea3d3b8..caa35e01787 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1817,9 +1817,6 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn -#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP -#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip - #undef TARGET_MD_ASM_ADJUST #define TARGET_MD_ASM_ADJUST rs6000_md_asm_adjust @@ -5275,7 +5272,7 @@ rs6000_builtin_mask_for_load (void) } /* Implement LOOP_ALIGN. */ -int +align_flags rs6000_loop_align (rtx label) { basic_block bb; @@ -5283,7 +5280,7 @@ rs6000_loop_align (rtx label) /* Don't override loop alignment if -falign-loops was specified. */ if (!can_override_loop_align) - return align_loops_log; + return align_loops; bb = BLOCK_FOR_INSN (label); ninsns = num_loop_insns(bb->loop_father); @@ -5295,16 +5292,9 @@ rs6000_loop_align (rtx label) || rs6000_tune == PROCESSOR_POWER6 || rs6000_tune == PROCESSOR_POWER7 || rs6000_tune == PROCESSOR_POWER8)) - return 5; + return align_flags (5); else - return align_loops_log; -} - -/* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */ -static int -rs6000_loop_align_max_skip (rtx_insn *label) -{ - return (1 << rs6000_loop_align (label)) - 1; + return align_loops; } /* Return true iff, data reference of TYPE can reach vector alignment (16) diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h index 0bb885d2da1..7e9817cfaf7 100644 --- a/gcc/config/rx/rx-protos.h +++ b/gcc/config/rx/rx-protos.h @@ -50,7 +50,7 @@ private: #ifdef RTX_CODE extern int rx_adjust_insn_length (rtx_insn *, int); -extern int rx_align_for_label (rtx, int); +extern align_flags rx_align_for_label (rtx_insn *, int); extern void rx_emit_stack_popm (rtx *, bool); extern void rx_emit_stack_pushm (rtx *); extern char * rx_gen_move_template (rtx *, bool); diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index af97bef301d..c2669edc62c 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -3308,23 +3308,6 @@ rx_match_ccmode (rtx insn, machine_mode cc_mode) return true; } -int -rx_align_for_label (rtx lab, int uses_threshold) -{ - /* This is a simple heuristic to guess when an alignment would not be useful - because the delay due to the inserted NOPs would be greater than the delay - due to the misaligned branch. If uses_threshold is zero then the alignment - is always useful. */ - if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold) - return 0; - - if (optimize_size) - return 0; - /* These values are log, not bytes. */ - if (rx_cpu_type == RX100 || rx_cpu_type == RX200) - return 2; /* 4 bytes */ - return 3; /* 8 bytes */ -} static int rx_max_skip_for_label (rtx_insn *lab) @@ -3350,10 +3333,41 @@ rx_max_skip_for_label (rtx_insn *lab) opsize = get_attr_length (op); if (opsize >= 0 && opsize < 8) - return opsize - 1; + return MAX (0, opsize - 1); return 0; } +static int +rx_align_log_for_label (rtx_insn *lab, int uses_threshold) +{ + /* This is a simple heuristic to guess when an alignment would not be useful + because the delay due to the inserted NOPs would be greater than the delay + due to the misaligned branch. If uses_threshold is zero then the alignment + is always useful. */ + if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold) + return 0; + + if (optimize_size) + return 0; + + /* Return zero if max_skip not a positive number. */ + int max_skip = rx_max_skip_for_label (lab); + if (max_skip <= 0) + return 0; + + /* These values are log, not bytes. */ + if (rx_cpu_type == RX100 || rx_cpu_type == RX200) + return 2; /* 4 bytes */ + return 3; /* 8 bytes */ +} + +align_flags +rx_align_for_label (rtx_insn *lab, int uses_threshold) +{ + return align_flags (rx_align_log_for_label (lab, uses_threshold), + rx_max_skip_for_label (lab)); +} + /* Compute the real length of the extending load-and-op instructions. */ int @@ -3633,15 +3647,6 @@ rx_modes_tieable_p (machine_mode mode1, machine_mode mode2) #undef TARGET_CAN_INLINE_P #define TARGET_CAN_INLINE_P rx_ok_to_inline -#undef TARGET_ASM_JUMP_ALIGN_MAX_SKIP -#define TARGET_ASM_JUMP_ALIGN_MAX_SKIP rx_max_skip_for_label -#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP -#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rx_max_skip_for_label -#undef TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP -#define TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP rx_max_skip_for_label -#undef TARGET_ASM_LABEL_ALIGN_MAX_SKIP -#define TARGET_ASM_LABEL_ALIGN_MAX_SKIP rx_max_skip_for_label - #undef TARGET_FUNCTION_VALUE #define TARGET_FUNCTION_VALUE rx_function_value diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index 2f5a0e94677..c87bb96b2f1 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -417,9 +417,9 @@ typedef unsigned int CUMULATIVE_ARGS; /* Compute the alignment needed for label X in various situations. If the user has specified an alignment then honour that, otherwise use rx_align_for_label. */ -#define JUMP_ALIGN(x) (align_jumps_log > 0 ? align_jumps_log : rx_align_for_label (x, 0)) -#define LABEL_ALIGN(x) (align_labels_log > 0 ? align_labels_log : rx_align_for_label (x, 3)) -#define LOOP_ALIGN(x) (align_loops_log > 0 ? align_loops_log : rx_align_for_label (x, 2)) +#define JUMP_ALIGN(x) (align_jumps.levels[0].log > 0 ? align_jumps : align_flags (rx_align_for_label (x, 0))) +#define LABEL_ALIGN(x) (align_labels.levels[0].log > 0 ? align_labels : align_flags (rx_align_for_label (x, 3))) +#define LOOP_ALIGN(x) (align_loops.levels[0].log > 0 ? align_loops : align_flags (rx_align_for_label (x, 2))) #define LABEL_ALIGN_AFTER_BARRIER(x) rx_align_for_label (x, 0) #define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM, LOG, MAX_SKIP) \ diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index ba18cb1c39a..cb896944797 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1233,7 +1233,7 @@ s390_label_align (rtx_insn *label) return 0; old: - return align_labels_log; + return align_labels.levels[0].log; } static GTY(()) rtx got_symbol; @@ -7542,10 +7542,11 @@ s390_asm_output_function_label (FILE *asm_out_file, const char *fname, NOPs. */ function_alignment = MAX (8, DECL_ALIGN (decl) / BITS_PER_UNIT); if (! DECL_USER_ALIGN (decl)) - function_alignment = MAX (function_alignment, - (unsigned int) align_functions_max_skip + 1); + function_alignment + = MAX (function_alignment, + (unsigned int) align_functions.levels[0].get_value ()); fputs ("\t# alignment for hotpatch\n", asm_out_file); - ASM_OUTPUT_ALIGN (asm_out_file, align_functions_log); + ASM_OUTPUT_ALIGN (asm_out_file, align_functions.levels[0].log); } if (S390_USE_TARGET_ATTRIBUTE && TARGET_DEBUG_ARG) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index e58533c3bab..4a0d5bae57b 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -1015,7 +1015,7 @@ sh_override_options_after_change (void) parse_alignment_opts (); if (flag_align_jumps && !str_align_jumps) str_align_jumps = "2"; - else if (align_jumps_value < 2) + else if (align_jumps.levels[0].get_value () < 2) str_align_jumps = "2"; if (flag_align_functions && !str_align_functions) @@ -1028,12 +1028,13 @@ sh_override_options_after_change (void) { /* Parse values so that we can compare for current value. */ parse_alignment_opts (); - int min_align = MAX (align_loops_value, align_jumps_value); + int min_align = MAX (align_loops.levels[0].get_value (), + align_jumps.levels[0].get_value ()); /* Also take possible .long constants / mova tables into account. */ if (min_align < 4) min_align = 4; - if (align_functions_value < min_align) + if (align_functions.levels[0].get_value () < min_align) { char *r = XNEWVEC (char, 16); sprintf (r, "%d", min_align); @@ -4986,7 +4987,7 @@ find_barrier (int num_mova, rtx_insn *mova, rtx_insn *from) && CODE_LABEL_NUMBER (from) <= max_labelno_before_reorg) { if (optimize) - new_align = 1 << label_to_alignment (from); + new_align = 1 << label_to_alignment (from).levels[0].log; else if (BARRIER_P (prev_nonnote_insn (from))) new_align = 1 << barrier_align (from); else @@ -5118,7 +5119,7 @@ find_barrier (int num_mova, rtx_insn *mova, rtx_insn *from) && (prev_nonnote_insn (from) == XEXP (MOVA_LABELREF (mova), 0)))) num_mova--; - if (barrier_align (next_real_insn (from)) == align_jumps_log) + if (barrier_align (next_real_insn (from)) == align_jumps.levels[0].log) { /* We have just passed the barrier in front of the ADDR_DIFF_VEC, which is stored in found_barrier. Since @@ -5752,7 +5753,7 @@ barrier_align (rtx_insn *barrier_or_label) return ((optimize_size || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat)) <= (unsigned) 1 << (CACHE_LOG - 2))) - ? 1 : align_jumps_log); + ? 1 : align_jumps.levels[0].log); } rtx_insn *next = next_active_insn (barrier_or_label); @@ -5770,7 +5771,7 @@ barrier_align (rtx_insn *barrier_or_label) return 0; if (! TARGET_SH2 || ! optimize) - return align_jumps_log; + return align_jumps.levels[0].log; /* When fixing up pcloads, a constant table might be inserted just before the basic block that ends with the barrier. Thus, we can't trust the @@ -5848,7 +5849,7 @@ barrier_align (rtx_insn *barrier_or_label) } } - return align_jumps_log; + return align_jumps.levels[0].log; } /* If we are inside a phony loop, almost any kind of label can turn up as the @@ -5874,7 +5875,7 @@ sh_loop_align (rtx_insn *label) || recog_memoized (next) == CODE_FOR_consttable_2) return 0; - return align_loops_log; + return align_loops.levels[0].log; } /* Do a final pass over the function, just before delayed branch diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index fe2a2a34a05..e2f45ddb72a 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -241,7 +241,7 @@ spu_option_override (void) /* Functions must be 8 byte aligned so we correctly handle dual issue */ parse_alignment_opts (); - if (align_functions_value < 8) + if (align_functions.levels[0].get_value () < 8) str_align_functions = "8"; spu_hint_dist = 8*4 - spu_max_nops*4; @@ -2772,7 +2772,9 @@ static void spu_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED, int max_ready ATTRIBUTE_UNUSED) { - if (align_labels_value > 4 || align_loops_value > 4 || align_jumps_value > 4) + if (align_labels.levels[0].get_value () > 4 + || align_loops.levels[0].get_value () > 4 + || align_jumps.levels[0].get_value () > 4) { /* When any block might be at least 8-byte aligned, assume they will all be at least 8-byte aligned to make sure dual issue diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index af7395852ce..99e2d4dd507 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -107,7 +107,7 @@ extern GTY(()) int spu_tune; (GET_CODE (X) == SYMBOL_REF \ && (SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1) == 0 \ && (! SYMBOL_REF_FUNCTION_P (X) \ - || align_functions_value >= 16)) + || align_functions.levels[0].get_value () >= 16)) #define PCC_BITFIELD_TYPE_MATTERS 1 diff --git a/gcc/config/visium/visium.c b/gcc/config/visium/visium.c index 37de6249797..2b402d11f76 100644 --- a/gcc/config/visium/visium.c +++ b/gcc/config/visium/visium.c @@ -466,7 +466,7 @@ visium_option_override (void) else { /* But not if they are too far away from a 256-byte boundary. */ - str_align_loops = "256:32"; + str_align_loops = "256:32:8"; } } diff --git a/gcc/config/visium/visium.h b/gcc/config/visium/visium.h index f1bd00fadb7..edfe3fc499e 100644 --- a/gcc/config/visium/visium.h +++ b/gcc/config/visium/visium.h @@ -1450,6 +1450,10 @@ do \ #define ASM_OUTPUT_CASE_END(STREAM, NUM, TABLE) \ asm_fprintf (STREAM, "\t.long 0\n") +/* Support subalignment values. */ + +#define SUBALIGN_LOG 3 + /* Assembler Commands for Alignment This describes commands for alignment. @@ -1495,15 +1499,8 @@ do \ if ((LOG) != 0) { \ if ((MAX_SKIP) == 0 || (MAX_SKIP) >= (1<<(LOG))-1) \ fprintf ((STREAM), "\t.p2align %d\n", (LOG)); \ - else { \ + else \ fprintf ((STREAM), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ - /* Make sure that we have at least 8-byte alignment if > 8-byte \ - alignment is preferred. */ \ - if ((LOG) > 3 \ - && (1 << (LOG)) > ((MAX_SKIP) + 1) \ - && (MAX_SKIP) >= 7) \ - fputs ("\t.p2align 3\n", (STREAM)); \ - } \ } /* Controlling Debugging Information Format diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 283b4eb33fe..09d2270e188 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -416,6 +416,7 @@ typedef unsigned char uchar; #include "insn-modes-inline.h" #include "machmode.h" #include "double-int.h" +#include "align.h" /* Most host source files will require the following headers. */ #if !defined (GENERATOR_FILE) #include "real.h" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ff6d5146010..0ddcd1aa2ac 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9560,12 +9560,6 @@ to set the variable @var{align_jumps} in the target's selection in @var{align_jumps} in a @code{JUMP_ALIGN} implementation. @end defmac -@deftypefn {Target Hook} int TARGET_ASM_JUMP_ALIGN_MAX_SKIP (rtx_insn *@var{label}) -The maximum number of bytes to skip before @var{label} when applying -@code{JUMP_ALIGN}. This works only if -@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined. -@end deftypefn - @defmac LABEL_ALIGN_AFTER_BARRIER (@var{label}) The alignment (log base 2) to put in front of @var{label}, which follows a @code{BARRIER}. @@ -9575,12 +9569,6 @@ to be done at such a time. Most machine descriptions do not currently define the macro. @end defmac -@deftypefn {Target Hook} int TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP (rtx_insn *@var{label}) -The maximum number of bytes to skip before @var{label} when applying -@code{LABEL_ALIGN_AFTER_BARRIER}. This works only if -@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined. -@end deftypefn - @defmac LOOP_ALIGN (@var{label}) The alignment (log base 2) to put in front of @var{label} that heads a frequently executed basic block (usually the header of a loop). @@ -9595,12 +9583,6 @@ to set the variable @code{align_loops} in the target's selection in @code{align_loops} in a @code{LOOP_ALIGN} implementation. @end defmac -@deftypefn {Target Hook} int TARGET_ASM_LOOP_ALIGN_MAX_SKIP (rtx_insn *@var{label}) -The maximum number of bytes to skip when applying @code{LOOP_ALIGN} to -@var{label}. This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is -defined. -@end deftypefn - @defmac LABEL_ALIGN (@var{label}) The alignment (log base 2) to put in front of @var{label}. If @code{LABEL_ALIGN_AFTER_BARRIER} / @code{LOOP_ALIGN} specify a different alignment, @@ -9612,12 +9594,6 @@ to set the variable @code{align_labels} in the target's selection in @code{align_labels} in a @code{LABEL_ALIGN} implementation. @end defmac -@deftypefn {Target Hook} int TARGET_ASM_LABEL_ALIGN_MAX_SKIP (rtx_insn *@var{label}) -The maximum number of bytes to skip when applying @code{LABEL_ALIGN} -to @var{label}. This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} -is defined. -@end deftypefn - @defmac ASM_OUTPUT_SKIP (@var{stream}, @var{nbytes}) A C statement to output to the stdio stream @var{stream} an assembler instruction to advance the location counter by @var{nbytes} bytes. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 2f97151f341..e275aca0eec 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -6524,8 +6524,6 @@ to set the variable @var{align_jumps} in the target's selection in @var{align_jumps} in a @code{JUMP_ALIGN} implementation. @end defmac -@hook TARGET_ASM_JUMP_ALIGN_MAX_SKIP - @defmac LABEL_ALIGN_AFTER_BARRIER (@var{label}) The alignment (log base 2) to put in front of @var{label}, which follows a @code{BARRIER}. @@ -6535,8 +6533,6 @@ to be done at such a time. Most machine descriptions do not currently define the macro. @end defmac -@hook TARGET_ASM_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP - @defmac LOOP_ALIGN (@var{label}) The alignment (log base 2) to put in front of @var{label} that heads a frequently executed basic block (usually the header of a loop). @@ -6551,8 +6547,6 @@ to set the variable @code{align_loops} in the target's selection in @code{align_loops} in a @code{LOOP_ALIGN} implementation. @end defmac -@hook TARGET_ASM_LOOP_ALIGN_MAX_SKIP - @defmac LABEL_ALIGN (@var{label}) The alignment (log base 2) to put in front of @var{label}. If @code{LABEL_ALIGN_AFTER_BARRIER} / @code{LOOP_ALIGN} specify a different alignment, @@ -6564,8 +6558,6 @@ to set the variable @code{align_labels} in the target's selection in @code{align_labels} in a @code{LABEL_ALIGN} implementation. @end defmac -@hook TARGET_ASM_LABEL_ALIGN_MAX_SKIP - @defmac ASM_OUTPUT_SKIP (@var{stream}, @var{nbytes}) A C statement to output to the stdio stream @var{stream} an assembler instruction to advance the location counter by @var{nbytes} bytes. diff --git a/gcc/final.c b/gcc/final.c index ea238656d34..59eb75c3d63 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -327,15 +327,9 @@ int insn_current_align; for each insn we'll call the alignment chain of this insn in the following comments. */ -struct label_alignment -{ - short alignment; - short max_skip; -}; - static rtx *uid_align; static int *uid_shuid; -static struct label_alignment *label_align; +static vec label_align; /* Indicate that branch shortening hasn't yet been done. */ @@ -473,11 +467,11 @@ get_attr_min_length (rtx_insn *insn) address mod X to one mod Y, which is Y - X. */ #ifndef LABEL_ALIGN -#define LABEL_ALIGN(LABEL) align_labels_log +#define LABEL_ALIGN(LABEL) align_labels #endif #ifndef LOOP_ALIGN -#define LOOP_ALIGN(LABEL) align_loops_log +#define LOOP_ALIGN(LABEL) align_loops #endif #ifndef LABEL_ALIGN_AFTER_BARRIER @@ -485,33 +479,9 @@ get_attr_min_length (rtx_insn *insn) #endif #ifndef JUMP_ALIGN -#define JUMP_ALIGN(LABEL) align_jumps_log +#define JUMP_ALIGN(LABEL) align_jumps #endif -int -default_label_align_after_barrier_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) -{ - return 0; -} - -int -default_loop_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) -{ - return align_loops_max_skip; -} - -int -default_label_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) -{ - return align_labels_max_skip; -} - -int -default_jump_align_max_skip (rtx_insn *insn ATTRIBUTE_UNUSED) -{ - return align_jumps_max_skip; -} - #ifndef ADDR_VEC_ALIGN static int final_addr_vec_align (rtx_jump_table_data *addr_vec) @@ -536,27 +506,16 @@ final_addr_vec_align (rtx_jump_table_data *addr_vec) static int min_labelno, max_labelno; #define LABEL_TO_ALIGNMENT(LABEL) \ - (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment) - -#define LABEL_TO_MAX_SKIP(LABEL) \ - (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip) + (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno]) /* For the benefit of port specific code do this also as a function. */ -int +align_flags label_to_alignment (rtx label) { if (CODE_LABEL_NUMBER (label) <= max_labelno) return LABEL_TO_ALIGNMENT (label); - return 0; -} - -int -label_to_max_skip (rtx label) -{ - if (CODE_LABEL_NUMBER (label) <= max_labelno) - return LABEL_TO_MAX_SKIP (label); - return 0; + return align_flags (); } /* The differences in addresses @@ -604,8 +563,8 @@ align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth) align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid]; if (uid_shuid[uid] > end_shuid) break; - known_align_log = LABEL_TO_ALIGNMENT (align_label); - new_align = 1 << known_align_log; + align_flags alignment = LABEL_TO_ALIGNMENT (align_label); + new_align = 1 << alignment.levels[0].log; if (new_align < known_align) continue; fuzz += (-align_addr ^ growth) & (new_align - known_align); @@ -667,18 +626,14 @@ insn_current_reference_address (rtx_insn *branch) unsigned int compute_alignments (void) { - int log, max_skip, max_log; basic_block bb; + align_flags max_alignment; - if (label_align) - { - free (label_align); - label_align = 0; - } + label_align.truncate (0); max_labelno = max_label_num (); min_labelno = get_first_label_num (); - label_align = XCNEWVEC (struct label_alignment, max_labelno - min_labelno + 1); + label_align.safe_grow_cleared (max_labelno - min_labelno + 1); /* If not optimizing or optimizing for size, don't assign any alignments. */ if (! optimize || optimize_function_for_size_p (cfun)) @@ -718,8 +673,7 @@ compute_alignments (void) bb_loop_depth (bb)); continue; } - max_log = LABEL_ALIGN (label); - max_skip = targetm.asm_out.label_align_max_skip (label); + max_alignment = LABEL_ALIGN (label); profile_count fallthru_count = profile_count::zero (); profile_count branch_count = profile_count::zero (); @@ -765,14 +719,10 @@ compute_alignments (void) <= ENTRY_BLOCK_PTR_FOR_FN (cfun) ->count.apply_scale (1, 2))))) { - log = JUMP_ALIGN (label); + align_flags alignment = JUMP_ALIGN (label); if (dump_file) fprintf (dump_file, " jump alignment added.\n"); - if (max_log < log) - { - max_log = log; - max_skip = targetm.asm_out.jump_align_max_skip (label); - } + max_alignment = align_flags::max (max_alignment, alignment); } /* In case block is frequent and reached mostly by non-fallthru edge, align it. It is most likely a first block of loop. */ @@ -785,17 +735,12 @@ compute_alignments (void) > fallthru_count.apply_scale (PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS), 1))) { - log = LOOP_ALIGN (label); + align_flags alignment = LOOP_ALIGN (label); if (dump_file) fprintf (dump_file, " internal loop alignment added.\n"); - if (max_log < log) - { - max_log = log; - max_skip = targetm.asm_out.loop_align_max_skip (label); - } + max_alignment = align_flags::max (max_alignment, alignment); } - LABEL_TO_ALIGNMENT (label) = max_log; - LABEL_TO_MAX_SKIP (label) = max_skip; + LABEL_TO_ALIGNMENT (label) = max_alignment; } loop_optimizer_finalize (); @@ -817,14 +762,11 @@ grow_label_align (void) n_labels = max_labelno - min_labelno + 1; n_old_labels = old - min_labelno + 1; - label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); + label_align.safe_grow_cleared (n_labels); /* Range of labels grows monotonically in the function. Failing here means that the initialization of array got lost. */ gcc_assert (n_old_labels <= n_labels); - - memset (label_align + n_old_labels, 0, - (n_labels - n_old_labels) * sizeof (struct label_alignment)); } /* Update the already computed alignment information. LABEL_PAIRS is a vector @@ -842,10 +784,7 @@ update_alignments (vec &label_pairs) FOR_EACH_VEC_ELT (label_pairs, i, iter) if (i & 1) - { - LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter); - LABEL_TO_MAX_SKIP (label) = LABEL_TO_MAX_SKIP (iter); - } + LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter); else label = iter; } @@ -903,8 +842,6 @@ shorten_branches (rtx_insn *first) rtx_insn *insn; int max_uid; int i; - int max_log; - int max_skip; #define MAX_CODE_ALIGN 16 rtx_insn *seq; int something_changed = 1; @@ -926,17 +863,14 @@ shorten_branches (rtx_insn *first) /* Initialize label_align and set up uid_shuid to be strictly monotonically rising with insn order. */ - /* We use max_log here to keep track of the maximum alignment we want to + /* We use alignment here to keep track of the maximum alignment we want to impose on the next CODE_LABEL (or the current one if we are processing the CODE_LABEL itself). */ - max_log = 0; - max_skip = 0; + align_flags max_alignment; for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn)) { - int log; - INSN_SHUID (insn) = i++; if (INSN_P (insn)) continue; @@ -944,22 +878,14 @@ shorten_branches (rtx_insn *first) if (rtx_code_label *label = dyn_cast (insn)) { /* Merge in alignments computed by compute_alignments. */ - log = LABEL_TO_ALIGNMENT (label); - if (max_log < log) - { - max_log = log; - max_skip = LABEL_TO_MAX_SKIP (label); - } + align_flags alignment = LABEL_TO_ALIGNMENT (label); + max_alignment = align_flags::max (max_alignment, alignment); rtx_jump_table_data *table = jump_table_for_label (label); if (!table) { - log = LABEL_ALIGN (label); - if (max_log < log) - { - max_log = log; - max_skip = targetm.asm_out.label_align_max_skip (label); - } + align_flags alignment = LABEL_ALIGN (label); + max_alignment = align_flags::max (max_alignment, alignment); } /* ADDR_VECs only take room if read-only data goes into the text section. */ @@ -967,17 +893,11 @@ shorten_branches (rtx_insn *first) || readonly_data_section == text_section) && table) { - log = ADDR_VEC_ALIGN (table); - if (max_log < log) - { - max_log = log; - max_skip = targetm.asm_out.label_align_max_skip (label); - } + align_flags alignment = align_flags (ADDR_VEC_ALIGN (table)); + max_alignment = align_flags::max (max_alignment, alignment); } - LABEL_TO_ALIGNMENT (label) = max_log; - LABEL_TO_MAX_SKIP (label) = max_skip; - max_log = 0; - max_skip = 0; + LABEL_TO_ALIGNMENT (label) = max_alignment; + max_alignment = align_flags (); } else if (BARRIER_P (insn)) { @@ -987,12 +907,9 @@ shorten_branches (rtx_insn *first) label = NEXT_INSN (label)) if (LABEL_P (label)) { - log = LABEL_ALIGN_AFTER_BARRIER (insn); - if (max_log < log) - { - max_log = log; - max_skip = targetm.asm_out.label_align_after_barrier_max_skip (label); - } + align_flags alignment + = align_flags (LABEL_ALIGN_AFTER_BARRIER (insn)); + max_alignment = align_flags::max (max_alignment, alignment); break; } } @@ -1023,11 +940,12 @@ shorten_branches (rtx_insn *first) { int uid = INSN_UID (seq); int log; - log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq) : 0); + log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq).levels[0].log : 0); uid_align[uid] = align_tab[0]; if (log) { /* Found an alignment label. */ + gcc_checking_assert (log < MAX_CODE_ALIGN + 1); uid_align[uid] = align_tab[log]; for (i = log - 1; i >= 0; i--) align_tab[i] = seq; @@ -1078,8 +996,10 @@ shorten_branches (rtx_insn *first) max = shuid; max_lab = lab; } - if (min_align > LABEL_TO_ALIGNMENT (lab)) - min_align = LABEL_TO_ALIGNMENT (lab); + + int label_alignment = LABEL_TO_ALIGNMENT (lab).levels[0].log; + if (min_align > label_alignment) + min_align = label_alignment; } XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab); XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab); @@ -1113,7 +1033,7 @@ shorten_branches (rtx_insn *first) if (LABEL_P (insn)) { - int log = LABEL_TO_ALIGNMENT (insn); + int log = LABEL_TO_ALIGNMENT (insn).levels[0].log; if (log) { int align = 1 << log; @@ -1221,7 +1141,7 @@ shorten_branches (rtx_insn *first) if (rtx_code_label *label = dyn_cast (insn)) { - int log = LABEL_TO_ALIGNMENT (label); + int log = LABEL_TO_ALIGNMENT (label).levels[0].log; #ifdef CASE_VECTOR_SHORTEN_MODE /* If the mode of a following jump table was changed, we @@ -1296,7 +1216,7 @@ shorten_branches (rtx_insn *first) prev = PREV_INSN (prev)) if (varying_length[INSN_UID (prev)] & 2) { - rel_align = LABEL_TO_ALIGNMENT (prev); + rel_align = LABEL_TO_ALIGNMENT (prev).levels[0].log; break; } @@ -2519,26 +2439,20 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, some insn, e.g. sh.c output_branchy_insn. */ if (CODE_LABEL_NUMBER (insn) <= max_labelno) { - int align = LABEL_TO_ALIGNMENT (insn); -#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - int max_skip = LABEL_TO_MAX_SKIP (insn); -#endif - - if (align && NEXT_INSN (insn)) + align_flags alignment = LABEL_TO_ALIGNMENT (insn); + if (alignment.levels[0].log && NEXT_INSN (insn)) { #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - ASM_OUTPUT_MAX_SKIP_ALIGN (file, align, max_skip); - /* Above, we don't know whether a label, jump or loop - alignment was used. Conservatively apply - label subalignment, not jump or loop - subalignment (they are almost always larger). */ - ASM_OUTPUT_MAX_SKIP_ALIGN (file, state_align_labels.levels[1].log, - state_align_labels.levels[1].maxskip); + /* Output both primary and secondary alignment. */ + ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[0].log, + alignment.levels[0].maxskip); + ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[1].log, + alignment.levels[1].maxskip); #else #ifdef ASM_OUTPUT_ALIGN_WITH_NOP - ASM_OUTPUT_ALIGN_WITH_NOP (file, align); + ASM_OUTPUT_ALIGN_WITH_NOP (file, alignment.levels[0].log); #else - ASM_OUTPUT_ALIGN (file, align); + ASM_OUTPUT_ALIGN (file, alignment.levels[0].log); #endif #endif } diff --git a/gcc/flags.h b/gcc/flags.h index bfd645b7f29..f025efb4b8e 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -42,24 +42,6 @@ extern bool final_insns_dump_p; /* Other basic status info about current function. */ -/* Align flags tuple with alignment in log form and with a maximum skip. */ - -struct align_flags_tuple -{ - /* Values of the -falign-* flags: how much to align labels in code. - log is "align to 2^log" (so 0 means no alignment). - maxskip is the maximum allowed amount of padding to insert. */ - int log; - int maxskip; -}; - -/* Target-dependent global state. */ - -struct align_flags -{ - align_flags_tuple levels[2]; -}; - struct target_flag_state { /* Each falign-foo can generate up to two levels of alignment: @@ -80,22 +62,10 @@ extern struct target_flag_state *this_target_flag_state; #define this_target_flag_state (&default_target_flag_state) #endif -#define state_align_loops (this_target_flag_state->x_align_loops) -#define state_align_jumps (this_target_flag_state->x_align_jumps) -#define state_align_labels (this_target_flag_state->x_align_labels) -#define state_align_functions (this_target_flag_state->x_align_functions) -#define align_loops_log (state_align_loops.levels[0].log) -#define align_jumps_log (state_align_jumps.levels[0].log) -#define align_labels_log (state_align_labels.levels[0].log) -#define align_functions_log (state_align_functions.levels[0].log) -#define align_loops_max_skip (state_align_loops.levels[0].maxskip) -#define align_jumps_max_skip (state_align_jumps.levels[0].maxskip) -#define align_labels_max_skip (state_align_labels.levels[0].maxskip) -#define align_functions_max_skip (state_align_functions.levels[0].maxskip) -#define align_loops_value (align_loops_max_skip + 1) -#define align_jumps_value (align_jumps_max_skip + 1) -#define align_labels_value (align_labels_max_skip + 1) -#define align_functions_value (align_functions_max_skip + 1) +#define align_loops (this_target_flag_state->x_align_loops) +#define align_jumps (this_target_flag_state->x_align_jumps) +#define align_labels (this_target_flag_state->x_align_labels) +#define align_functions (this_target_flag_state->x_align_functions) /* String representaions of the above options are available in const char *str_align_foo. NULL if not set. */ diff --git a/gcc/output.h b/gcc/output.h index afe72bece31..333389e484c 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -96,11 +96,7 @@ extern int insn_current_reference_address (rtx_insn *); /* Find the alignment associated with a CODE_LABEL. Defined in final.c. */ -extern int label_to_alignment (rtx); - -/* Find the alignment maximum skip associated with a CODE_LABEL. - Defined in final.c. */ -extern int label_to_max_skip (rtx); +extern align_flags label_to_alignment (rtx); /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ extern void output_asm_label (rtx); diff --git a/gcc/system.h b/gcc/system.h index 8295577618a..f87fbaae69e 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -918,8 +918,6 @@ extern void fancy_abort (const char *, int, const char *) RETURN_POPS_ARGS UNITS_PER_SIMD_WORD OVERRIDE_OPTIONS \ OPTIMIZATION_OPTIONS CLASS_LIKELY_SPILLED_P \ USING_SJLJ_EXCEPTIONS TARGET_UNWIND_INFO \ - LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP \ - LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \ CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME \ HOT_TEXT_SECTION_NAME LEGITIMATE_CONSTANT_P ALWAYS_STRIP_DOTDOT \ OUTPUT_ADDR_CONST_EXTRA SMALL_REGISTER_CLASSES ASM_OUTPUT_IDENT \ diff --git a/gcc/target.def b/gcc/target.def index ff89e72dd2b..2598d3c7783 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -65,46 +65,6 @@ the string should contain a tab, a pseudo-op, and then another tab.", DEFHOOKPOD (aligned_op, "*", struct asm_int_op, TARGET_ASM_ALIGNED_INT_OP) DEFHOOKPOD (unaligned_op, "*", struct asm_int_op, TARGET_ASM_UNALIGNED_INT_OP) -/* The maximum number of bytes to skip when applying - LABEL_ALIGN_AFTER_BARRIER. */ -DEFHOOK -(label_align_after_barrier_max_skip, - "The maximum number of bytes to skip before @var{label} when applying\n\ -@code{LABEL_ALIGN_AFTER_BARRIER}. This works only if\n\ -@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.", - int, (rtx_insn *label), - default_label_align_after_barrier_max_skip) - -/* The maximum number of bytes to skip when applying - LOOP_ALIGN. */ -DEFHOOK -(loop_align_max_skip, - "The maximum number of bytes to skip when applying @code{LOOP_ALIGN} to\n\ -@var{label}. This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is\n\ -defined.", - int, (rtx_insn *label), - default_loop_align_max_skip) - -/* The maximum number of bytes to skip when applying - LABEL_ALIGN. */ -DEFHOOK -(label_align_max_skip, - "The maximum number of bytes to skip when applying @code{LABEL_ALIGN}\n\ -to @var{label}. This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN}\n\ -is defined.", - int, (rtx_insn *label), - default_label_align_max_skip) - -/* The maximum number of bytes to skip when applying - JUMP_ALIGN. */ -DEFHOOK -(jump_align_max_skip, - "The maximum number of bytes to skip before @var{label} when applying\n\ -@code{JUMP_ALIGN}. This works only if\n\ -@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.", - int, (rtx_insn *label), - default_jump_align_max_skip) - /* Try to output the assembler code for an integer object whose value is given by X. SIZE is the size of the object in bytes and ALIGNED_P indicates whether it is aligned. Return true if diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 8d234cf9467..76fcec83570 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -236,10 +236,6 @@ extern enum unwind_info_type default_debug_unwind_info (void); extern void default_canonicalize_comparison (int *, rtx *, rtx *, bool); -extern int default_label_align_after_barrier_max_skip (rtx_insn *); -extern int default_loop_align_max_skip (rtx_insn *); -extern int default_label_align_max_skip (rtx_insn *); -extern int default_jump_align_max_skip (rtx_insn *); extern section * default_function_section(tree decl, enum node_frequency freq, bool startup, bool exit); extern unsigned int default_dwarf_poly_indeterminate_value (unsigned int, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 652d164a85c..a17d60fb17d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-07-17 Martin Liska + + * gcc.target/powerpc/loop_align.c: Update scanned pattern. + 2018-07-17 Ed Schonberg * gnat.dg/generic_call_cw.adb, gnat.dg/generic_call_iface.adb: New diff --git a/gcc/testsuite/gcc.target/powerpc/loop_align.c b/gcc/testsuite/gcc.target/powerpc/loop_align.c index 7eabc118217..44d989b041e 100644 --- a/gcc/testsuite/gcc.target/powerpc/loop_align.c +++ b/gcc/testsuite/gcc.target/powerpc/loop_align.c @@ -2,7 +2,7 @@ /* { dg-skip-if "" { powerpc*-*-darwin* powerpc-ibm-aix* } } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */ /* { dg-options "-O2 -mcpu=power7 -falign-functions=16" } */ -/* { dg-final { scan-assembler ".p2align 5,,31" } } */ +/* { dg-final { scan-assembler ".p2align 5" } } */ void f(double *a, double *b, double *c, unsigned long n) { unsigned long i; diff --git a/gcc/toplev.c b/gcc/toplev.c index cf7bab655bd..1fb8fcc1c8b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1207,24 +1207,26 @@ read_log_maxskip (auto_vec &values, align_flags_tuple *a) 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; } + + /* Normalize the tuple. */ + a->normalize (); } /* 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) +parse_N_M (const char *flag, align_flags &a) { if (flag) { @@ -1269,7 +1271,10 @@ parse_N_M (const char *flag, align_flags &a, unsigned int min_align_log) { /* Set N2 unless subalign can never have any effect. */ if (align > a.levels[0].maxskip + 1) - a.levels[1].log = SUBALIGN_LOG; + { + a.levels[1].log = SUBALIGN_LOG; + a.levels[1].normalize (); + } } } #endif @@ -1277,40 +1282,17 @@ parse_N_M (const char *flag, align_flags &a, unsigned int min_align_log) /* 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); + parse_N_M (str_align_loops, align_loops); + parse_N_M (str_align_jumps, align_jumps); + parse_N_M (str_align_labels, align_labels); + parse_N_M (str_align_functions, align_functions); } /* Process the options that have been parsed. */ diff --git a/gcc/varasm.c b/gcc/varasm.c index 81f460643ea..0d3609e2807 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1801,25 +1801,25 @@ assemble_start_function (tree decl, const char *fnname) Note that we still need to align to DECL_ALIGN, as above, because ASM_OUTPUT_MAX_SKIP_ALIGN might not do any alignment at all. */ if (! DECL_USER_ALIGN (decl) - && align_functions_log > align + && align_functions.levels[0].log > align && optimize_function_for_speed_p (cfun)) { #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - int align_log = state_align_functions.levels[0].log; + int align_log = align_functions.levels[0].log; #endif - int max_skip = state_align_functions.levels[0].maxskip; + int max_skip = align_functions.levels[0].maxskip; if (flag_limit_function_alignment && crtl->max_insn_address > 0 && max_skip >= crtl->max_insn_address) max_skip = crtl->max_insn_address - 1; #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, align_log, max_skip); - if (max_skip == state_align_functions.levels[0].maxskip) + if (max_skip == align_functions.levels[0].maxskip) ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, - state_align_functions.levels[1].log, - state_align_functions.levels[1].maxskip); + align_functions.levels[1].log, + align_functions.levels[1].maxskip); #else - ASM_OUTPUT_ALIGN (asm_out_file, state_align_functions.levels[0].log); + ASM_OUTPUT_ALIGN (asm_out_file, align_functions.levels[0].log); #endif } -- 2.30.2