TargetData::getPreferredAlignment(const GlobalVariable *GV) is strange ...

Hello everybody,

I am somewhat confused by the following method within the LLVM,
especially the lines
"confusion starts" -> "confusion ends" are hard to follow. Maybe the
idea is that if there
are such big data structures one does not waste much memory anyway if
they are aligned
to a 16-byte boundary. However, my assembler complains here because
it only supports
1-, 2-, 4- and 8-byte boundaries :frowning:

I checked the svn log but I didn't find any explanation, the doxygen
docu is not very helpful
here, too. So, any help on this issue is highly appreciated.

Thanks in advance!

Ciao, Fabian

unsigned TargetData::getPreferredAlignment(const GlobalVariable *GV) const {
  const Type *ElemType = GV->getType()->getElementType();
  unsigned Alignment = getPrefTypeAlignment(ElemType);
  if (GV->getAlignment() > Alignment)
    Alignment = GV->getAlignment();

==================== confusion starts ========================
  if (GV->hasInitializer()) {
    if (Alignment < 16) {
      // If the global is not external, see if it is large. If so, give it a
      // larger alignment.
      if (getTypeSizeInBits(ElemType) > 128)
        Alignment = 16; // 16-byte alignment.
    }
  }
==================== confusion ends =========================

  return Alignment;
}

Hi Fabian,

I am somewhat confused by the following method within the LLVM,
especially the lines
"confusion starts" -> "confusion ends" are hard to follow.

yes, this seems like a wart. It has been there ever since Chris added the
getPreferredAlignmentLog method in commit 25978. Maybe he can comment on
whether the code to bump up the alignment for big objects is still needed.

Ciao, Duncan.

  Maybe the

Hi Fabian,

I am somewhat confused by the following method within the LLVM,
especially the lines
"confusion starts" -> "confusion ends" are hard to follow.

yes, this seems like a wart. It has been there ever since Chris added the
getPreferredAlignmentLog method in commit 25978. Maybe he can comment on
whether the code to bump up the alignment for big objects is still needed.

Ah, I really vaguely remember this. IIRC, there was some fortran benchmark (that was running through f2c) which had a large array of doubles. On X86, double is only 4-byte aligned, and the huge array was getting put at a "mod 16=4" offset. This caused really really awful performance.

A reasonable solution to this was to bump up the alignment of stuff proactively, but you don't want to do this for everything, because this ends up wasting lots of memory. GCC has a similar policy IIRC.

Is there some problem that this is causing?

-Chris

Ah, I really vaguely remember this. IIRC, there was some fortran benchmark (that was running through f2c) which had a large array of doubles. On X86, double is only 4-byte aligned, and the huge array was getting put at a "mod 16=4" offset. This caused really really awful performance.

A reasonable solution to this was to bump up the alignment of stuff proactively, but you don't want to do this for everything, because this ends up wasting lots of memory. GCC has a similar policy IIRC.

Is there some problem that this is causing?

Well, LLVM generates assembly that is not acepted by the binutils for
the TriCore processor I am using if the program contains large
structs. If LLVM-targets had a "maxAlign"-property this could be tuned
according to the needs of the specific target.

Ciao, Fabian