[cfe-dev] Alignment of globals and target datalayout

Moritz Roth moritz.roth11 at imperial.ac.uk
Tue Apr 22 09:46:30 PDT 2014


Hi Rafael,

First of all thanks for your input -

> I think it is safe, but changing getAlignOfGlobalVar to use the
> preferred alignment would be a big change for all targets, so it would
> need a really large benchmarking run.
Agreed, this would be a big change. Perhaps it should be target-specific -
i.e modifying ASTContext::get[Preferred]TypeAlign so the behaviour only
changes for certain targets - although at the moment the front-end is quite
limited in that regard as it only has access to ASTContext::TargetInfo,
which doesn't contain much relevant data.

> I think it would also prevent the linker from merging global strings.
Due to the alignment change it would at least be restricted (e.g. in
Thumb1, the maximum offset from a global is 127). On the other hand,
allowing an increased alignment allows other optimisations in the back-end
such as inlining calls to strcpy/memcpy - LDM/IA has 32-bit alignment
requirements.

I think this issue is only really relevant to architectures which don't
have extensive support for unaligned memory accesses, and thus a solution
shouldn't change the behaviour on most platforms. For now, it might be best
to leave this alone and simply set a minimum alignment for the specific
target, and then investigate further from there.

Cheers
Moritz



2014-04-22 15:52 GMT+01:00 Rafael EspĂ­ndola <rafael.espindola at gmail.com>:

> On 15 April 2014 13:29, Moritz Roth <moritz.roth11 at gmail.com> wrote:
> > Hi,
> >
> > I've run into some interesting behaviour with how globals are aligned -
> it
> > seems like the alignment preferences specified in the target datalayout
> are
> > being ignored. Example:
> >
> > $ cat test.c
> > void f(const char *);
> > void g(const char *c) {
> >   const char *b = "jgksj";
> >   return f(b + 1);
> > }
> >
> > $ clang -target arm-none-linux-gnueabi -mcpu=cortex-m0 test.c -S
> -emit-llvm
> > -o - -O0
> > ; ModuleID = 'test.c'
> > target datalayout =
> >
> "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-v128:64:128-a:0:32-n32-S64"
> > target triple = "thumbv6m-none-linux-gnueabi"
> >
> > @.str = private unnamed_addr constant [6 x i8] c"jgksj\00", align 1
> >
> > (...)
> >
> > Shouldn't @.str be aligned to the preferred alignment of i8, i.e. 4?
> >
> > If I set MinGlobalAlignment for my target to 32, @.str is aligned to 4
> bytes
> > (as expected). This leads me to believe that the behaviour is caused by
> > ASTContext::getAlignOfGlobalVar, which in turn calls
> > ASTContext::getTypeAlign - and from there gets the ABI alignment (which
> of
> > course is 8 bits / 1 in this case).
> >
> > I imagine a fix would do something like
> >
> > unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
> >   return std::max(getPreferredTypeAlign(T.getTypePtr()),
> > getTargetInfo().getMinGlobalAlign());
> > }
> >
> > However, I'd then also need to change getPreferredTypeAlign so it
> actually
> > considers what the target specifies as the preferred alignment, not just
> the
> > ABI align and type size. Is this the right place to make changes? Or is
> all
> > this intended behaviour?
>
> I think it is safe, but changing getAlignOfGlobalVar to use the
> preferred alignment would be a big change for all targets, so it would
> need a really large benchmarking run. I think it would also prevent
> the linker from merging global strings.
>
> > Any opinions would be greatly appreciated.
> >
> > Thanks
> > Moritz
>
> Cheers,
> Rafael
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140422/cc5ca01e/attachment.html>


More information about the cfe-dev mailing list