svn commit: r242835 - head/contrib/llvm/lib/Target/X86
Dimitry Andric
dim at FreeBSD.org
Sun Nov 11 14:17:05 UTC 2012
On 2012-11-11 12:53, Bruce Evans wrote:
> On Sat, 10 Nov 2012, Nathan Whitehorn wrote:
>> On 11/09/12 12:56, Dimitry Andric wrote:
>>> Log:
>>> Reduce LLVM's default stack alignment for i386 from 16 to 4 bytes, as
>>> the FreeBSD ABI requires. This is essentially a revert of upstream llvm
>>> commit r126226, and it will be reverted by upstream too.
>>> MFC after: 1 week
...
>> I'd like to object to this. We have an identical ABI to Linux (and Solaris,
>> as far as I know). Splitting this by platform will only propagate the stack
>> alignment breakage further -- what we need is LLVM/our C library to handle
>> different alignments. Please fix this for real instead of balkanizing the ABI
>> support in LLVM and introducing different ABIs for LLVM and GCC to FreeBSD.
>
> I'm not sure if either of us knows exactly what this does, but I like
> this change. clang does stack alignment correctly, so it doesn't need
> the gcc pessimization of aligning in the caller. clang aligns in the
> callee if necessary (except if is lied to about the ABI, then it doesn't
> know what is necessaary). It is rarely necessary, since most variables
> are 32 bits or smaller. (Necessary includes when an alignment attribute
> says so and for optimal alignment of long longs and doubles. The i386
> ABI doesn't require alignment for the latter, but optimization doesn't,
> and when the variables aren't in structs the ABI doesn't prevent them
> being aligned for optimization.) Always aligning in the caller wastes
> an average of not quite 8 bytes of stack and cache space per function
> call, plus sometimes an extra instruction or 2 to do the unnecessary
> alignment. gcc's alignment in callers doesn't even work, because gcc
> assumes that it is enough and never does it in callees even when it
> is necessary:
>
> auto int32_t foo[8] __aligned[32];
>
> gcc fails to do the necessary alignment. clang does it.
>
> auto int32_t foo[8] __aligned[16];
>
> Both gcc and (hopefully only without the above fix) clang fail to do the
> necessary alignment.
It works just fine now with clang. For the first example, I get:
pushl %ebp
movl %esp, %ebp
andl $-32, %esp
as prolog, and for the second:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
> The ABI doesn't require the stack to be 16-byte
> aligned, so alignment is necessary (unless -mpreferred-stack-boundary was
> used to explictly modify the ABI). gcc only aligns the stack in main(),
> only to the alignment specified by -mpreferred-stack-boundary, and
> laboriously passes it down to all functions. clang doesn't do any
> special alignment in main(), but assumes that crtso did it. clang also
> doesn't support -mpreferred-stack-boundary, so it is incompatible with
> nonstandard ABI's like the one given by always using
> -mpreferred-stack-boundary=32.
Apparently upstream never saw the need for this option. I strongly
doubt it is used very often outside FreeBSD...
...
>> as far as I know). Splitting this by platform will only propagate the stack
>> alignment breakage further -- what we need is LLVM/our C library to handle
>> different alignments. Please fix this for real instead of balkanizing the ABI
>> support in LLVM and introducing different ABIs for LLVM and GCC to FreeBSD.
>
> Yes, we need clang/our libraries to handle different alignments and
> not assume that callers do more than the ABI requires and pessimize
> on behalf of the libraries. Outside of libraries, the problem is small
> provided -mpreferred-stack-boundary works, since you can compile
> everything with the same -mpreferred-stack-boundary.
As far as I can see, with the 4 byte stack alignment that has been the
default, and is now also clang's default, our libraries should handle
any "incoming" stack alignment of >= 4 bytes. I don't think anybody
uses lower stack alignment, except maybe for the special case of boot
loaders, or extremely size-optimized code.
More information about the svn-src-all
mailing list