[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