Darwin: Update rules for handling alignment of globals.
The current rule was too strict and has not been required since Darwin11. This relaxes the constraint to allow up to 2^28 alignment for non-common entities. Common is still restricted to a maximum aligment of 2^15. When the host is an older version of Darwin ( earlier that 11 ) then the existing constraint is still applied. Note that this is a host constraint not a target one (so that a compilation on 10.7 targeting 10.6 is allowed to use a greater alignment than the tools on 10.6 support). This matches the behaviour of clang. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk> gcc/ChangeLog: * config.gcc: Emit L2_MAX_OFILE_ALIGNMENT with suitable values for the host. * config/darwin.c (darwin_emit_common): Error for alignment values > 32768. * config/darwin.h (MAX_OFILE_ALIGNMENT): Rework to use the configured L2_MAX_OFILE_ALIGNMENT. gcc/testsuite/ChangeLog: * gcc.dg/darwin-aligned-globals.c: New test. * gcc.dg/darwin-comm-1.c: New test. * gcc.dg/attr-aligned.c: Amend for new alignment values on Darwin. * gcc.target/i386/pr89261.c: Likewise.
This commit is contained in:
parent
8381075ff3
commit
19bf83a9a0
|
@ -677,6 +677,20 @@ case ${target} in
|
|||
macos_min=0
|
||||
fi
|
||||
def_ld64=85.2
|
||||
# Tools hosted on earlier versions of Darwin constrained all object
|
||||
# alignment to be 2^15 or smaller. From Darwin11 (macOS 10.7) the
|
||||
# alignment of non-common is allowed to be up to 2^28. Note that the
|
||||
# larger alignment is permitted when targeting 10.6 from 10.7 so that
|
||||
# the constraint only need be applied per host (and only if the host
|
||||
# is Darwin).
|
||||
case ${host} in
|
||||
*-*-darwin[4-9]* | *-*-darwin10*)
|
||||
tm_defines="$tm_defines L2_MAX_OFILE_ALIGNMENT=15U"
|
||||
;;
|
||||
*)
|
||||
tm_defines="$tm_defines L2_MAX_OFILE_ALIGNMENT=28U"
|
||||
;;
|
||||
esac
|
||||
case ${target} in
|
||||
# Darwin 4 to 19 correspond to macOS 10.0 to 10.15
|
||||
*-*-darwin[4-9]* | *-*-darwin1[0-9]*)
|
||||
|
|
|
@ -2558,7 +2558,6 @@ darwin_emit_common (FILE *fp, const char *name,
|
|||
rounded = (size + (align-1)) & ~(align-1);
|
||||
|
||||
l2align = floor_log2 (align);
|
||||
gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
|
||||
|
||||
in_section = comm_section;
|
||||
/* We mustn't allow multiple public symbols to share an address when using
|
||||
|
@ -2709,6 +2708,10 @@ darwin_asm_output_aligned_decl_common (FILE *fp, tree decl, const char *name,
|
|||
#ifdef DEBUG_DARWIN_MEM_ALLOCATORS
|
||||
fprintf (fp, "# adcom: %s (%d,%d) decl=0x0\n", name, (int)size, (int)align);
|
||||
#endif
|
||||
/* Common variables are limited to a maximum alignment of 2^15. */
|
||||
if (align > 32768)
|
||||
error_at (UNKNOWN_LOCATION, "common variables must have an alignment"
|
||||
" of 32678 or less");
|
||||
darwin_emit_common (fp, name, size, align);
|
||||
return;
|
||||
}
|
||||
|
@ -2736,7 +2739,7 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
|
|||
}
|
||||
|
||||
/* We shouldn't be messing with this if the decl has a section name. */
|
||||
gcc_assert (DECL_SECTION_NAME (decl) == NULL);
|
||||
gcc_checking_assert (DECL_SECTION_NAME (decl) == NULL);
|
||||
|
||||
/* We would rather not have to check this here - but it seems that we might
|
||||
be passed a decl that should be in coalesced space. */
|
||||
|
@ -2765,10 +2768,16 @@ fprintf (fp, "# adcom: %s (%lld,%d) ro %d cst %d stat %d com %d pub %d"
|
|||
|
||||
l2align = floor_log2 (align / BITS_PER_UNIT);
|
||||
/* Check we aren't asking for more aligment than the platform allows. */
|
||||
gcc_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
|
||||
gcc_checking_assert (l2align <= L2_MAX_OFILE_ALIGNMENT);
|
||||
|
||||
if (TREE_PUBLIC (decl) != 0)
|
||||
darwin_emit_common (fp, name, size, align);
|
||||
{
|
||||
/* Common variables are limited to a maximum alignment of 2^15. */
|
||||
if (l2align > 15)
|
||||
error_at (DECL_SOURCE_LOCATION (decl), "common variables must have"
|
||||
" an alignment of 32678 or less");
|
||||
darwin_emit_common (fp, name, size, align);
|
||||
}
|
||||
else
|
||||
darwin_emit_local_bss (fp, decl, name, size, l2align);
|
||||
}
|
||||
|
|
|
@ -873,13 +873,12 @@ int darwin_label_is_anonymous_local_objc_name (const char *name);
|
|||
if ((LOG) != 0) \
|
||||
fprintf (FILE, "\t%s\t%d\n", ALIGN_ASM_OP, (LOG))
|
||||
|
||||
/* The maximum alignment which the object file format can support in
|
||||
bits. For Mach-O, this is 2^15 bytes. */
|
||||
/* The maximum alignment which the object file format can support in bits
|
||||
which depends on the OS version and whether the object is a common
|
||||
variable. */
|
||||
|
||||
#undef MAX_OFILE_ALIGNMENT
|
||||
#define MAX_OFILE_ALIGNMENT (0x8000 * 8)
|
||||
|
||||
#define L2_MAX_OFILE_ALIGNMENT 15
|
||||
#define MAX_OFILE_ALIGNMENT ((1U << L2_MAX_OFILE_ALIGNMENT) * 8U)
|
||||
|
||||
/* These are the three variants that emit referenced blank space. */
|
||||
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
# define ALIGN_MAX_STATIC 0x1000
|
||||
/* Excessive alignment for functions and objects with static storage
|
||||
duration that's expected to trigger an error. */
|
||||
#elif __MACH__
|
||||
# define ALIGN_MAX_STATIC 0x8000
|
||||
#elif __APPLE__
|
||||
# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
|
||||
# define ALIGN_MAX_STATIC 0x8000
|
||||
# else
|
||||
# define ALIGN_MAX_STATIC ALIGN_MAX_HARD
|
||||
# endif
|
||||
#elif pdp11
|
||||
# define ALIGN_MAX_STATIC 2
|
||||
/* Work around a pdp11 ICE (see PR target/87821). */
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* { dg-do compile { target *-*-darwin* } } */
|
||||
/* { dg-additional-options "-fcommon" } */
|
||||
|
||||
/* Test alignment rules which differ for earlier hosts (so we must
|
||||
work on the principle that this test will be exercised by self-
|
||||
hosted compilers. */
|
||||
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070
|
||||
#define align_OK (1ul << 28)
|
||||
#define align_BAD (1ul << 29)
|
||||
#else
|
||||
#define align_OK (1ul << 15)
|
||||
#define align_BAD (1ul << 16)
|
||||
#endif
|
||||
|
||||
/* All non common vars are allowed larger alignment on modern systems. */
|
||||
static int xn __attribute__ ((aligned (align_OK)));
|
||||
static int xi __attribute__ ((aligned (align_OK))) = 5 ;
|
||||
int gxi __attribute__ ((aligned (align_OK))) = 6 ;
|
||||
|
||||
/* test that we detect bad cases. */
|
||||
static int yn __attribute__ ((aligned (align_BAD))); /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
|
||||
static int yi __attribute__ ((aligned (align_BAD))) = 5; /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
|
||||
int yni __attribute__ ((aligned (align_BAD))) = 6; /* { dg-error {requested alignment .[0-9]+. exceeds object file maximum} } */
|
|
@ -0,0 +1,5 @@
|
|||
/* { dg-do compile { target *-*-darwin[912]* } } */
|
||||
/* { dg-options "-fcommon" } */
|
||||
|
||||
/* In all cases, common has a max alignment of 2^15. */
|
||||
int badcommon __attribute__ ((aligned (65536))); /* { dg-error "common variables must have an alignment" } */
|
|
@ -5,6 +5,7 @@
|
|||
typedef double __v2df __attribute__ ((vector_size (16), aligned (1 << 28)));
|
||||
|
||||
__v2df foo = { 1.0, 2.0 };
|
||||
/* { dg-error {alignment of 'foo' is greater than maximum object file alignment 32768} "" { target *-*-darwin* } .-1 } */
|
||||
/* { dg-error {alignment of 'foo' is greater than maximum object file alignment 32768} "" { target { *-*-darwin[89]* *-*-darwin10* } } .-1 } */
|
||||
|
||||
/* { dg-final { scan-assembler "\.align\[ \t]+268435456" { target { ! *-*-darwin* } } } } */
|
||||
/* { dg-final { scan-assembler "\.align\[ \t]+28" { target { *-*-darwin1[1-9]* *-*-darwin2* } } } } */
|
||||
|
|
Loading…
Reference in New Issue