+2018-07-17 Martin Liska <mliska@suse.cz>
+
+ * 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 <jakub@redhat.com>
PR middle-end/86539
--- /dev/null
+/* 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
+<http://www.gnu.org/licenses/>. */
+
+/* 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];
+};
/* 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)
/* 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)
{
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;
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
#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
#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)
#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
}
/* Implement LOOP_ALIGN. */
-int
+align_flags
rs6000_loop_align (rtx label)
{
basic_block bb;
/* 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);
|| 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)
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 */
#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
}
/* Implement LOOP_ALIGN. */
-int
+align_flags
rs6000_loop_align (rtx label)
{
basic_block bb;
/* 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);
|| 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)
#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);
return true;
}
\f
-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)
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
#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
/* 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) \
return 0;
old:
- return align_labels_log;
+ return align_labels.levels[0].log;
}
static GTY(()) rtx got_symbol;
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)
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)
{
/* 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);
&& 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
&& (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
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);
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
}
}
- 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
|| 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
/* 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;
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
(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
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";
}
}
#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.
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
#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"
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}.
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).
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,
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.
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}.
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).
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,
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.
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<align_flags> label_align;
/* Indicate that branch shortening hasn't yet been done. */
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
#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)
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
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);
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))
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 ();
<= 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. */
> 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 ();
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
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;
}
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;
/* 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;
if (rtx_code_label *label = dyn_cast <rtx_code_label *> (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. */
|| 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))
{
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;
}
}
{
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;
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);
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;
if (rtx_code_label *label = dyn_cast <rtx_code_label *> (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
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;
}
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
}
\f
/* 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:
#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. */
/* 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);
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 \
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
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,
+2018-07-17 Martin Liska <mliska@suse.cz>
+
+ * gcc.target/powerpc/loop_align.c: Update scanned pattern.
+
2018-07-17 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/generic_call_cw.adb, gnat.dg/generic_call_iface.adb: New
/* { 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;
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)
{
{
/* 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
/* 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. */
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
}