[llvm-commits] [llvm-gcc-4.2] r58387 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-types.cpp
Duncan Sands
baldrick at free.fr
Wed Oct 29 10:59:32 PDT 2008
Author: baldrick
Date: Wed Oct 29 12:59:31 2008
New Revision: 58387
URL: http://llvm.org/viewvc/llvm-project?rev=58387&view=rev
Log:
Really fix tramp3d-v4 on x86-64-linux. This reverts
commit 57992 which only solved part of the problem:
that gcc struct fields were sometimes being mapped
to LLVM fields with a different offset from the start
of the struct.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=58387&r1=58386&r2=58387&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Oct 29 12:59:31 2008
@@ -6023,38 +6023,6 @@
BitStart -= SL->getElementOffset(MemberIndex) * 8;
}
- // Type conversion does not ensure that there is always an LLVM field
- // starting at the same byte as the gcc field. Correct for this now.
- // An example of how this can occur is:
- // Field A: offset 0, length 1
- // Field B: offset 4, length 4 (4 byte alignment)
- // Field C: offset 6
- // Since field C overlaps field B, we delete field B and replace it with
- // padding:
- // LLVM A: offset 0, length 1
- // LLVM B: offset 1, length 5 (1 byte alignment) - padding array
- // LLVM C: offset 6
- // A COMPONENT_REF for gcc field B will get LLVM field B which has
- // offset 1 not 4.
- unsigned ByteStart = BitStart/8;
- if (ByteStart && !isBitfield(FieldDecl)) {
- const Type *ContainingType =
- cast<StructType>(StructTy)->getTypeAtIndex(MemberIndex);
- Value *Offset = ConstantInt::get(TD.getIntPtrType(), ByteStart);
-
- const ArrayType *ATy = dyn_cast<ArrayType>(ContainingType);
- if (ATy && ATy->getElementType() == Type::Int8Ty) {
- // Only known case: the LLVM field is an array of bytes.
- FieldPtr = Builder.CreateGEP(FieldPtr, Offset);
- } else {
- // Do pointer arithmetic.
- FieldPtr = Builder.CreatePtrToInt(FieldPtr, Offset->getType());
- FieldPtr = Builder.CreateAdd(FieldPtr, Offset);
- FieldPtr = Builder.CreateIntToPtr(FieldPtr,
- PointerType::getUnqual(Type::Int8Ty));
- }
- BitStart -= ByteStart * 8;
- }
} else {
Value *Offset = Emit(field_offset, 0);
Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=58387&r1=58386&r2=58387&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Oct 29 12:59:31 2008
@@ -1425,10 +1425,22 @@
SavedTy = Elements.back();
if (ElementOffsetInBytes.back()+ElementSizeInBytes.back() > ByteOffset) {
// The last element overlapped with this one, remove it.
+ uint64_t PoppedOffset = ElementOffsetInBytes.back();
Elements.pop_back();
ElementOffsetInBytes.pop_back();
ElementSizeInBytes.pop_back();
PaddingElement.pop_back();
+ uint64_t EndOffset = getNewElementByteOffset(1);
+ if (EndOffset < PoppedOffset) {
+ // Make sure that some field starts at the position of the
+ // field we just popped. Otherwise we might end up with a
+ // gcc non-bitfield being mapped to an LLVM field with a
+ // different offset.
+ const Type *Pad = Type::Int8Ty;
+ if (PoppedOffset != EndOffset + 1)
+ Pad = ArrayType::get(Pad, PoppedOffset - EndOffset);
+ addElement(Pad, EndOffset, PoppedOffset - EndOffset);
+ }
}
}
@@ -2132,6 +2144,10 @@
unsigned FieldNo =
Info->getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField);
SetFieldIndex(Field, FieldNo);
+
+ assert((isBitfield(Field) || FieldNo == ~0U ||
+ FieldOffsetInBits == 8*Info->ElementOffsetInBytes[FieldNo]) &&
+ "Wrong LLVM field offset!");
}
// Put the original gcc struct back the way it was; necessary to prevent the
More information about the llvm-commits
mailing list