[llvm-commits] [126997] Fix PR1278.

dpatel at apple.com dpatel at apple.com
Mon May 7 23:15:09 PDT 2007


Revision: 126997
Author:   dpatel
Date:     2007-05-07 23:15:09 -0700 (Mon, 07 May 2007)

Log Message:
-----------
Fix PR1278.

- While adding padding elements at the end of LLVM struct use
  an array of i32 (instead of an array of i8) if possible.

- Keep track of padding elements at the end of LLVM struct.
  Do not copy them while copying aggregates.

Modified Paths:
--------------
    apple-local/branches/llvm/gcc/llvm-convert.cpp
    apple-local/branches/llvm/gcc/llvm-internal.h
    apple-local/branches/llvm/gcc/llvm-types.cpp

Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-05-08 05:09:41 UTC (rev 126996)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp	2007-05-08 06:15:09 UTC (rev 126997)
@@ -1085,6 +1085,8 @@
   } else if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
     Constant *Zero = ConstantInt::get(Type::Int32Ty, 0);
     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+      if (isPaddingElement(STy, i))
+        continue;
       Constant *Idx = ConstantInt::get(Type::Int32Ty, i);
       Value *DElPtr = new GetElementPtrInst(DestPtr, Zero, Idx, "tmp", CurBB);
       Value *SElPtr = new GetElementPtrInst(SrcPtr, Zero, Idx, "tmp", CurBB);

Modified: apple-local/branches/llvm/gcc/llvm-internal.h
===================================================================
--- apple-local/branches/llvm/gcc/llvm-internal.h	2007-05-08 05:09:41 UTC (rev 126996)
+++ apple-local/branches/llvm/gcc/llvm-internal.h	2007-05-08 06:15:09 UTC (rev 126997)
@@ -96,6 +96,10 @@
 
 struct StructTypeConversionInfo;
 
+/// Return true if and only if field no. N from struct type T is a padding
+/// element added to match llvm struct type size and gcc struct type size.
+bool isPaddingElement(const Type *T, unsigned N);
+
 /// TypeConverter - Implement the converter from GCC types to LLVM types.
 ///
 class TypeConverter {

Modified: apple-local/branches/llvm/gcc/llvm-types.cpp
===================================================================
--- apple-local/branches/llvm/gcc/llvm-types.cpp	2007-05-08 05:09:41 UTC (rev 126996)
+++ apple-local/branches/llvm/gcc/llvm-types.cpp	2007-05-08 06:15:09 UTC (rev 126997)
@@ -893,6 +893,7 @@
   std::vector<const Type*> Elements;
   std::vector<uint64_t> ElementOffsetInBytes;
   std::vector<uint64_t> ElementSizeInBytes;
+  std::vector<bool> PaddingElement; // True if field is used for padding
   const TargetData &TD;
   unsigned GCCStructAlignmentInBytes;
   bool Packed; // True if struct is packed
@@ -1071,10 +1072,12 @@
   
   /// addElement - Add an element to the structure with the specified type,
   /// offset and size.
-  void addElement(const Type *Ty, uint64_t Offset, uint64_t Size) {
+  void addElement(const Type *Ty, uint64_t Offset, uint64_t Size,
+                  bool ExtraPadding = false) {
     Elements.push_back(Ty);
     ElementOffsetInBytes.push_back(Offset);
     ElementSizeInBytes.push_back(Size);
+    PaddingElement.push_back(ExtraPadding);
     lastFieldStartsAtNonByteBoundry(false);
     ExtraBitsAvailable = 0;
   }
@@ -1223,7 +1226,25 @@
   }
 }
 
+std::map<const Type *, StructTypeConversionInfo *> StructTypeInfoMap;
 
+/// Return true if and only if field no. N from struct type T is a padding
+/// element added to match llvm struct type size and gcc struct type size.
+bool isPaddingElement(const Type *Ty, unsigned index) {
+  
+  StructTypeConversionInfo *Info = StructTypeInfoMap[Ty];
+
+  // If info is not available then be conservative and return false.
+  if (!Info)
+    return false;
+
+  assert ( Info->Elements.size() == Info->PaddingElement.size()
+           && "Invalid StructTypeConversionInfo");
+  assert ( index < Info->PaddingElement.size()  
+           && "Invalid PaddingElement index");
+  return Info->PaddingElement[index];
+}
+
 /// getFieldOffsetInBits - Return the offset (in bits) of a FIELD_DECL in a
 /// structure.
 static unsigned getFieldOffsetInBits(tree Field) {
@@ -1417,29 +1438,46 @@
       ConvertType(BINFO_TYPE(BINFO_BASE_BINFO(binfo, i)));
   }
   
-  StructTypeConversionInfo Info(*TheTarget, TYPE_ALIGN_UNIT(type), 
-                                TYPE_PACKED(type));
+  StructTypeConversionInfo *Info = 
+    new StructTypeConversionInfo(*TheTarget, TYPE_ALIGN_UNIT(type), 
+                             TYPE_PACKED(type));
+                                
   
   // Convert over all of the elements of the struct.
   for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field))
-    DecodeStructFields(Field, Info);
+    DecodeStructFields(Field, *Info);
 
-  Info.RemoveExtraBytes();
+  Info->RemoveExtraBytes();
   // If the LLVM struct requires explicit tail padding to be the same size as
   // the GCC struct, insert tail padding now.  This handles, e.g., "{}" in C++.
   if (TYPE_SIZE(type) && TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST) {
-    uint64_t LLVMStructSize = Info.getSizeAsLLVMStruct();
+    uint64_t LLVMStructSize = Info->getSizeAsLLVMStruct();
     uint64_t GCCTypeSize = ((uint64_t)TREE_INT_CST_LOW(TYPE_SIZE(type))+7)/8;
     
     if (LLVMStructSize != GCCTypeSize) {
       assert(LLVMStructSize < GCCTypeSize &&
              "LLVM type size doesn't match GCC type size!");
-      uint64_t LLVMLastElementEnd = Info.getNewElementByteOffset(1);
-      const Type *PadTy = Type::Int8Ty;
-      if (GCCTypeSize-LLVMLastElementEnd != 1)
-        PadTy = ArrayType::get(PadTy, GCCTypeSize-LLVMStructSize);
-      Info.addElement(PadTy, GCCTypeSize-LLVMLastElementEnd, 
-                      GCCTypeSize-LLVMLastElementEnd);
+      uint64_t LLVMLastElementEnd = Info->getNewElementByteOffset(1);
+
+      // If only one byte is needed then insert i8.
+      if (GCCTypeSize-LLVMLastElementEnd == 1) 
+        Info->addElement(Type::Int8Ty, 1, 1);
+      else {
+        if ( ((GCCTypeSize-LLVMStructSize) % 4) == 0) {
+          // insert array of i32
+          unsigned Int32ArraySize = (GCCTypeSize-LLVMStructSize)/4;
+          const Type *PadTy = ArrayType::get(Type::Int32Ty, Int32ArraySize);
+          Info->addElement(PadTy, GCCTypeSize - LLVMLastElementEnd,
+                           Int32ArraySize, true /* Padding Element */);
+        } else {
+          const Type *PadTy = 
+            ArrayType::get(Type::Int8Ty, GCCTypeSize-LLVMStructSize);
+          Info->addElement(PadTy, GCCTypeSize - LLVMLastElementEnd, 
+                           GCCTypeSize - LLVMLastElementEnd, 
+                           true /* Padding Element */);
+          
+        }
+      }
     }
   }
   
@@ -1460,7 +1498,7 @@
       if (tree DeclaredType = DECL_BIT_FIELD_TYPE(Field)) {
         // If this is a bitfield, the declared type must be an integral type.
         const Type *DeclFieldTy = ConvertType(DeclaredType);
-        unsigned DeclBitAlignment = Info.getTypeAlignment(DeclFieldTy)*8;
+        unsigned DeclBitAlignment = Info->getTypeAlignment(DeclFieldTy)*8;
         
         FieldOffsetInBits &= ~(DeclBitAlignment-1ULL);
       }
@@ -1471,11 +1509,12 @@
         integer_zerop(TYPE_SIZE(FieldType));
 
       unsigned FieldNo = 
-        Info.getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField);
+        Info->getLLVMFieldFor(FieldOffsetInBits, CurFieldNo, isZeroSizeField);
       SET_DECL_LLVM(Field, ConstantInt::get(Type::Int32Ty, FieldNo));
     }
   
-  const Type *ResultTy = Info.getLLVMType();
+  const Type *ResultTy = Info->getLLVMType();
+  StructTypeInfoMap[ResultTy] = Info;
   
   const OpaqueType *OldTy = cast_or_null<OpaqueType>(GET_TYPE_LLVM(type));
   TypeDB.setType(type, ResultTy);





More information about the llvm-commits mailing list