[llvm-commits] [dragonegg] r133258 - in /dragonegg/trunk: include/dragonegg/Internals.h src/Convert.cpp src/Types.cpp

Duncan Sands baldrick at free.fr
Fri Jun 17 08:10:20 PDT 2011


Author: baldrick
Date: Fri Jun 17 10:10:20 2011
New Revision: 133258

URL: http://llvm.org/viewvc/llvm-project?rev=133258&view=rev
Log:
Remove the code that tries to track which LLVM struct fields were inserted
as padding.  This was for the benefit of the code that copies aggregates,
when it chose to do an element by element copy (rather than applying memcpy).
Instead, do element by element copies by iterating over the fields of the GCC
type.  This avoids copying LLVM padding by definition.  Since GCC types can be
complicated, the new code bails out in tricky cases.  Note that it bails out if
it sees a bitfield or a union, which used to be handled.  They could be handled
here too but I don't think it was worth it.  Also, now that LLVM handles memcpy
much better (presumably thanks to clang which just always does a memcpy for
struct copies), this element-by-element optimization is not as useful as it was,
so I halved the threshold: now it only kicks in if there are no more than four
elements to copy.

Modified:
    dragonegg/trunk/include/dragonegg/Internals.h
    dragonegg/trunk/src/Convert.cpp
    dragonegg/trunk/src/Types.cpp

Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=133258&r1=133257&r2=133258&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Fri Jun 17 10:10:20 2011
@@ -204,12 +204,6 @@
   /// of the given GCC type (getRegType should be used for values in registers).
   const Type *ConvertType(tree_node *type);
 
-  /// GCCTypeOverlapsWithLLVMTypePadding - Return true if the specified GCC type
-  /// has any data that overlaps with structure padding in the specified LLVM
-  /// type.
-  static bool GCCTypeOverlapsWithLLVMTypePadding(tree_node *t, const Type *Ty);
-
-
   /// ConvertFunctionType - Convert the specified FUNCTION_TYPE or METHOD_TYPE
   /// tree to an LLVM type.  This does the same thing that ConvertType does, but
   /// it also returns the function's LLVM calling convention and attributes.
@@ -570,8 +564,16 @@
   /// the previous block falls through into it, add an explicit branch.
   void BeginBlock(BasicBlock *BB);
 
+  /// CopyElementByElement - Recursively traverse the potentially aggregate
+  /// src/dest ptrs, copying all of the elements.  Helper for EmitAggregateCopy.
+  void CopyElementByElement(MemRef DestLoc, MemRef SrcLoc, tree_node *type);
+
+  /// ZeroElementByElement - Recursively traverse the potentially aggregate
+  /// DestLoc, zero'ing all of the elements.  Helper for EmitAggregateZero.
+  void ZeroElementByElement(MemRef DestLoc, tree_node *type);
+
   /// EmitAggregateZero - Zero the elements of DestLoc.
-  void EmitAggregateZero(MemRef DestLoc, tree_node *GCCType);
+  void EmitAggregateZero(MemRef DestLoc, tree_node *type);
 
   /// EmitMemCpy/EmitMemMove/EmitMemSet - Emit an llvm.memcpy/llvm.memmove or
   /// llvm.memset call with the specified operands.  Returns DestPtr bitcast

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=133258&r1=133257&r2=133258&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Fri Jun 17 10:10:20 2011
@@ -1456,92 +1456,136 @@
   Builder.SetInsertPoint(BB);  // It is now the current block.
 }
 
-/// CopyAggregate - Recursively traverse the potientially aggregate src/dest
-/// ptrs, copying all of the elements.
-static void CopyAggregate(MemRef DestLoc, MemRef SrcLoc,
-                          LLVMBuilder &Builder, tree gccType) {
-  assert(DestLoc.Ptr->getType() == SrcLoc.Ptr->getType() &&
-         "Cannot copy between two pointers of different type!");
-  const Type *ElTy =
-    cast<PointerType>(DestLoc.Ptr->getType())->getElementType();
-
-  unsigned Alignment = std::min(DestLoc.getAlignment(), SrcLoc.getAlignment());
-
-  if (ElTy->isSingleValueType()) {
-    LoadInst *V = Builder.CreateLoad(SrcLoc.Ptr, SrcLoc.Volatile);
-    StoreInst *S = Builder.CreateStore(V, DestLoc.Ptr, DestLoc.Volatile);
-    V->setAlignment(Alignment);
-    S->setAlignment(Alignment);
-  } else if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
-    const StructLayout *SL = getTargetData().getStructLayout(STy);
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-      if (gccType && isPaddingElement(gccType, i))
-        continue;
-      Value *DElPtr = Builder.CreateStructGEP(DestLoc.Ptr, i);
-      Value *SElPtr = Builder.CreateStructGEP(SrcLoc.Ptr, i);
-      unsigned Align = MinAlign(Alignment, SL->getElementOffset(i));
-      CopyAggregate(MemRef(DElPtr, Align, DestLoc.Volatile),
-                    MemRef(SElPtr, Align, SrcLoc.Volatile),
-                    Builder, 0);
-    }
-  } else {
-    const ArrayType *ATy = cast<ArrayType>(ElTy);
-    unsigned EltSize = getTargetData().getTypeAllocSize(ATy->getElementType());
-    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
-      Value *DElPtr = Builder.CreateStructGEP(DestLoc.Ptr, i);
-      Value *SElPtr = Builder.CreateStructGEP(SrcLoc.Ptr, i);
-      unsigned Align = MinAlign(Alignment, i * EltSize);
-      CopyAggregate(MemRef(DElPtr, Align, DestLoc.Volatile),
-                    MemRef(SElPtr, Align, SrcLoc.Volatile),
-                    Builder, 0);
-    }
+static const unsigned TooCostly = 8;
+
+/// CostOfAccessingAllElements - Return a number representing the cost of doing
+/// an element by element copy of the specified type.  If it is clear that the
+/// type should not be copied this way, for example because it has a bazillion
+/// elements or contains fields of variable size, then TooCostly (or larger) is
+/// returned.
+static unsigned CostOfAccessingAllElements(tree type) {
+  // If the type is incomplete, enormous or of variable size then don't copy it.
+  if (!isInt64(TYPE_SIZE(type), true))
+    return TooCostly;
+
+  // A scalar copy has a cost of 1.
+  if (!AGGREGATE_TYPE_P(type))
+    return 1;
+
+  // The cost of a record type is the sum of the costs of its fields.
+  if (TREE_CODE(type) == RECORD_TYPE) {
+    const Type *Ty = ConvertType(type);
+    unsigned TotalCost = 0;
+    for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
+      assert(TREE_CODE(Field) == FIELD_DECL && "Lang data not freed?");
+      // Bitfields are too hard - give up.
+      if (DECL_BIT_FIELD(Field))
+        return TooCostly;
+      // If there is no corresponding LLVM field then something funky is going
+      // on - just give up.
+      if (GetFieldIndex(Field, Ty) == INT_MIN)
+        return TooCostly;
+      TotalCost += CostOfAccessingAllElements(TREE_TYPE(Field));
+      if (TotalCost >= TooCostly)
+        return TooCostly;
+    }
+    return TotalCost;
+  }
+
+  // For array types, multiply the array length by the component cost.
+  if (TREE_CODE(type) == ARRAY_TYPE) {
+    // If this is an array with a funky component type then just give up.
+    if (!isSequentialCompatible(type))
+      return TooCostly;
+    uint64_t ArrayLength = ArrayLengthOf(type);
+    if (ArrayLength >= TooCostly)
+      return TooCostly;
+    unsigned ComponentCost = CostOfAccessingAllElements(TREE_TYPE(type));
+    if (ComponentCost >= TooCostly)
+      return TooCostly;
+    return ArrayLength * ComponentCost;
+  }
+
+  // Other types are not supported.
+  return TooCostly;
+}
+
+/// CopyElementByElement - Recursively traverse the potentially aggregate
+/// src/dest ptrs, copying all of the elements.  Helper for EmitAggregateCopy.
+void TreeToLLVM::CopyElementByElement(MemRef DestLoc, MemRef SrcLoc,
+                                      tree type) {
+  if (!AGGREGATE_TYPE_P(type)) {
+    // Copy scalar.
+    StoreRegisterToMemory(LoadRegisterFromMemory(SrcLoc, type, Builder),
+                          DestLoc, type, Builder);
+    return;
   }
-}
 
-/// CountAggregateElements - Return the number of elements in the specified type
-/// that will need to be loaded/stored if we copy this by explicit accesses.
-static unsigned CountAggregateElements(const Type *Ty) {
-  if (Ty->isSingleValueType()) return 1;
-
-  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
-    unsigned NumElts = 0;
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
-      NumElts += CountAggregateElements(STy->getElementType(i));
-    return NumElts;
-  } else {
-    const ArrayType *ATy = cast<ArrayType>(Ty);
-    return ATy->getNumElements()*CountAggregateElements(ATy->getElementType());
+  if (TREE_CODE(type) == RECORD_TYPE) {
+    // Ensure the source and destination are pointers to the record type.
+    const Type *Ty = ConvertType(type);
+    DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, Ty->getPointerTo());
+    SrcLoc.Ptr = Builder.CreateBitCast(SrcLoc.Ptr, Ty->getPointerTo());
+
+    // Copy each field in turn.
+    for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
+      // Get the address of the field.
+      int FieldIdx = GetFieldIndex(Field, Ty);
+      assert(FieldIdx != INT_MIN && "Should not be copying if no LLVM field!");
+      Value *DestFieldPtr = Builder.CreateStructGEP(DestLoc.Ptr, FieldIdx);
+      Value *SrcFieldPtr = Builder.CreateStructGEP(SrcLoc.Ptr, FieldIdx);
+
+      // Compute the field's alignment.
+      unsigned DestFieldAlign = DestLoc.getAlignment();
+      unsigned SrcFieldAlign = SrcLoc.getAlignment();
+      if (FieldIdx) {
+        DestFieldAlign = MinAlign(DestFieldAlign, DECL_ALIGN(Field) / 8);
+        SrcFieldAlign = MinAlign(SrcFieldAlign, DECL_ALIGN(Field) / 8);
+      }
+
+      // Copy the field.
+      MemRef DestFieldLoc(DestFieldPtr, DestFieldAlign, DestLoc.Volatile);
+      MemRef SrcFieldLoc(SrcFieldPtr, SrcFieldAlign, SrcLoc.Volatile);
+      CopyElementByElement(DestFieldLoc, SrcFieldLoc, TREE_TYPE(Field));
+    }
+    return;
   }
-}
 
-/// containsFPField - indicates whether the given LLVM type
-/// contains any floating point elements.
+  assert(TREE_CODE(type) == ARRAY_TYPE && "Expected an array!");
 
-static bool containsFPField(const Type *LLVMTy) {
-  if (LLVMTy->isFloatingPointTy())
-    return true;
-  const StructType* STy = dyn_cast<StructType>(LLVMTy);
-  if (STy) {
-    for (StructType::element_iterator I = STy->element_begin(),
-                                      E = STy->element_end(); I != E; I++) {
-      const Type *Ty = *I;
-      if (Ty->isFloatingPointTy())
-        return true;
-      if (Ty->isStructTy() && containsFPField(Ty))
-        return true;
-      const ArrayType *ATy = dyn_cast<ArrayType>(Ty);
-      if (ATy && containsFPField(ATy->getElementType()))
-        return true;
-      const VectorType *VTy = dyn_cast<VectorType>(Ty);
-      if (VTy && containsFPField(VTy->getElementType()))
-        return true;
+  // Turn the source and destination into pointers to the component type.
+  const Type *CompType = ConvertType(TREE_TYPE(type));
+  DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, CompType->getPointerTo());
+  SrcLoc.Ptr = Builder.CreateBitCast(SrcLoc.Ptr, CompType->getPointerTo());
+
+  // Copy each component in turn.
+  unsigned ComponentBytes = getTargetData().getTypeAllocSize(CompType);
+  unsigned ArrayLength = ArrayLengthOf(type);
+  for (unsigned i = 0; i != ArrayLength; ++i) {
+    // Get the address of the component.
+    Value *DestCompPtr = DestLoc.Ptr, *SrcCompPtr = SrcLoc.Ptr;
+    if (i) {
+      DestCompPtr = Builder.CreateConstInBoundsGEP1_32(DestCompPtr, i);
+      SrcCompPtr = Builder.CreateConstInBoundsGEP1_32(SrcCompPtr, i);
+    }
+
+    // Compute the component's alignment.
+    unsigned DestCompAlign = DestLoc.getAlignment();
+    unsigned SrcCompAlign = SrcLoc.getAlignment();
+    if (i) {
+      DestCompAlign = MinAlign(DestCompAlign, i * ComponentBytes);
+      SrcCompAlign = MinAlign(SrcCompAlign, i * ComponentBytes);
     }
+
+    // Copy the component.
+    MemRef DestCompLoc(DestCompPtr, DestCompAlign, DestLoc.Volatile);
+    MemRef SrcCompLoc(SrcCompPtr, SrcCompAlign, SrcLoc.Volatile);
+    CopyElementByElement(DestCompLoc, SrcCompLoc, TREE_TYPE(type));
   }
-  return false;
 }
 
-#ifndef TARGET_LLVM_MIN_BYTES_COPY_BY_MEMCPY
-#define TARGET_LLVM_MIN_BYTES_COPY_BY_MEMCPY 64
+#ifndef TARGET_DRAGONEGG_MEMCPY_COST
+#define TARGET_DRAGONEGG_MEMCPY_COST 4
 #endif
 
 /// EmitAggregateCopy - Copy the elements from SrcLoc to DestLoc, using the
@@ -1550,30 +1594,11 @@
   if (DestLoc.Ptr == SrcLoc.Ptr && !DestLoc.Volatile && !SrcLoc.Volatile)
     return;  // noop copy.
 
-  // If the type is small, copy the elements instead of using a block copy.
-  const Type *LLVMTy = ConvertType(type);
-  unsigned NumElts = CountAggregateElements(LLVMTy);
-  if (TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST &&
-      (NumElts == 1 ||
-       TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) <
-       TARGET_LLVM_MIN_BYTES_COPY_BY_MEMCPY)) {
-
-    // Some targets (x87) cannot pass non-floating-point values using FP
-    // instructions.  The LLVM type for a union may include FP elements,
-    // even if some of the union fields do not; it is unsafe to pass such
-    // converted types element by element.  PR 2680.
-
-    // If the GCC type is not fully covered by the LLVM type, use memcpy. This
-    // can occur with unions etc.
-    if ((TREE_CODE(type) != UNION_TYPE || !containsFPField(LLVMTy)) &&
-        !TheTypeConverter->GCCTypeOverlapsWithLLVMTypePadding(type, LLVMTy) &&
-        // Don't copy tons of tiny elements.
-        NumElts <= 8) {
-      DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, LLVMTy->getPointerTo());
-      SrcLoc.Ptr = Builder.CreateBitCast(SrcLoc.Ptr, LLVMTy->getPointerTo());
-      CopyAggregate(DestLoc, SrcLoc, Builder, type);
-      return;
-    }
+  // If the type is small, copy element by element instead of using memcpy.
+  unsigned Cost = CostOfAccessingAllElements(type);
+  if (Cost < TooCostly && Cost < TARGET_DRAGONEGG_MEMCPY_COST) {
+    CopyElementByElement(DestLoc, SrcLoc, type);
+    return;
   }
 
   Value *TypeSize = EmitRegister(TYPE_SIZE_UNIT(type));
@@ -1581,50 +1606,77 @@
              std::min(DestLoc.getAlignment(), SrcLoc.getAlignment()));
 }
 
-/// ZeroAggregate - Recursively traverse the potentially aggregate DestLoc,
-/// zero'ing all of the elements.
-static void ZeroAggregate(MemRef DestLoc, LLVMBuilder &Builder) {
-  const Type *ElTy =
-    cast<PointerType>(DestLoc.Ptr->getType())->getElementType();
-  if (ElTy->isSingleValueType()) {
-    StoreInst *St = Builder.CreateStore(Constant::getNullValue(ElTy),
-                                        DestLoc.Ptr, DestLoc.Volatile);
-    St->setAlignment(DestLoc.getAlignment());
-  } else if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
-    const StructLayout *SL = getTargetData().getStructLayout(STy);
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-      Value *Ptr = Builder.CreateStructGEP(DestLoc.Ptr, i);
-      unsigned Alignment = MinAlign(DestLoc.getAlignment(),
-                                    SL->getElementOffset(i));
-      ZeroAggregate(MemRef(Ptr, Alignment, DestLoc.Volatile), Builder);
-    }
-  } else {
-    const ArrayType *ATy = cast<ArrayType>(ElTy);
-    unsigned EltSize = getTargetData().getTypeAllocSize(ATy->getElementType());
-    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) {
-      Value *Ptr = Builder.CreateStructGEP(DestLoc.Ptr, i);
-      unsigned Alignment = MinAlign(DestLoc.getAlignment(), i * EltSize);
-      ZeroAggregate(MemRef(Ptr, Alignment, DestLoc.Volatile), Builder);
+/// ZeroElementByElement - Recursively traverse the potentially aggregate
+/// DestLoc, zero'ing all of the elements.  Helper for EmitAggregateZero.
+void TreeToLLVM::ZeroElementByElement(MemRef DestLoc, tree type) {
+  if (!AGGREGATE_TYPE_P(type)) {
+    // Zero scalar.
+    StoreRegisterToMemory(Constant::getNullValue(getRegType(type)), DestLoc,
+                          type, Builder);
+    return;
+  }
+
+  if (TREE_CODE(type) == RECORD_TYPE) {
+    // Ensure the pointer is to the record type.
+    const Type *Ty = ConvertType(type);
+    DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, Ty->getPointerTo());
+
+    // Zero each field in turn.
+    for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
+      // Get the address of the field.
+      int FieldIdx = GetFieldIndex(Field, Ty);
+      assert(FieldIdx != INT_MIN && "Should not be zeroing if no LLVM field!");
+      Value *FieldPtr = Builder.CreateStructGEP(DestLoc.Ptr, FieldIdx);
+
+      // Compute the field's alignment.
+      unsigned FieldAlign = DestLoc.getAlignment();
+      if (FieldIdx)
+        FieldAlign = MinAlign(FieldAlign, DECL_ALIGN(Field) / 8);
+
+      // Zero the field.
+      MemRef FieldLoc(FieldPtr, FieldAlign, DestLoc.Volatile);
+      ZeroElementByElement(FieldLoc, TREE_TYPE(Field));
     }
+    return;
+  }
+
+  assert(TREE_CODE(type) == ARRAY_TYPE && "Expected an array!");
+
+  // Turn the pointer into a pointer to the component type.
+  const Type *CompType = ConvertType(TREE_TYPE(type));
+  DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, CompType->getPointerTo());
+
+  // Zero each component in turn.
+  unsigned ComponentBytes = getTargetData().getTypeAllocSize(CompType);
+  unsigned ArrayLength = ArrayLengthOf(type);
+  for (unsigned i = 0; i != ArrayLength; ++i) {
+    // Get the address of the component.
+    Value *CompPtr = DestLoc.Ptr;
+    if (i)
+      CompPtr = Builder.CreateConstInBoundsGEP1_32(CompPtr, i);
+
+    // Compute the component's alignment.
+    unsigned CompAlign = DestLoc.getAlignment();
+    if (i)
+      CompAlign = MinAlign(CompAlign, i * ComponentBytes);
+
+    // Zero the component.
+    MemRef CompLoc(CompPtr, CompAlign, DestLoc.Volatile);
+    ZeroElementByElement(CompLoc, TREE_TYPE(type));
   }
 }
 
+#ifndef TARGET_DRAGONEGG_MEMSET_COST
+#define TARGET_DRAGONEGG_MEMSET_COST 4
+#endif
+
 /// EmitAggregateZero - Zero the elements of DestLoc.
 void TreeToLLVM::EmitAggregateZero(MemRef DestLoc, tree type) {
-  // If the type is small, copy the elements instead of using a block copy.
-  if (TREE_CODE(TYPE_SIZE(type)) == INTEGER_CST &&
-      TREE_INT_CST_LOW(TYPE_SIZE_UNIT(type)) < 128) {
-    const Type *LLVMTy = ConvertType(type);
-
-    // If the GCC type is not fully covered by the LLVM type, use memset. This
-    // can occur with unions etc.
-    if (!TheTypeConverter->GCCTypeOverlapsWithLLVMTypePadding(type, LLVMTy) &&
-        // Don't zero tons of tiny elements.
-        CountAggregateElements(LLVMTy) <= 8) {
-      DestLoc.Ptr = Builder.CreateBitCast(DestLoc.Ptr, LLVMTy->getPointerTo());
-      ZeroAggregate(DestLoc, Builder);
-      return;
-    }
+  // If the type is small, zero element by element instead of using memset.
+  unsigned Cost = CostOfAccessingAllElements(type);
+  if (Cost < TooCostly && Cost < TARGET_DRAGONEGG_MEMSET_COST) {
+    ZeroElementByElement(DestLoc, type);
+    return;
   }
 
   EmitMemSet(DestLoc.Ptr, Builder.getInt8(0),

Modified: dragonegg/trunk/src/Types.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Types.cpp?rev=133258&r1=133257&r2=133258&view=diff
==============================================================================
--- dragonegg/trunk/src/Types.cpp (original)
+++ dragonegg/trunk/src/Types.cpp Fri Jun 17 10:10:20 2011
@@ -482,164 +482,6 @@
   return set_decl_index(decl, Index);
 }
 
-/// FindLLVMTypePadding - If the specified struct has any inter-element padding,
-/// add it to the Padding array.
-static void FindLLVMTypePadding(const Type *Ty, tree type, uint64_t BitOffset,
-                       SmallVector<std::pair<uint64_t,uint64_t>, 16> &Padding) {
-  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
-    const TargetData &TD = getTargetData();
-    const StructLayout *SL = TD.getStructLayout(STy);
-    uint64_t PrevFieldEnd = 0;
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-      // If this field is marked as being padding, then pretend it is not there.
-      // This results in it (or something bigger) being added to Padding.  This
-      // matches the logic in CopyAggregate.
-      if (type && isPaddingElement(type, i))
-        continue;
-
-      uint64_t FieldBitOffset = SL->getElementOffset(i)*8;
-
-      // Get padding of sub-elements.
-      FindLLVMTypePadding(STy->getElementType(i), 0,
-                          BitOffset+FieldBitOffset, Padding);
-      // Check to see if there is any padding between this element and the
-      // previous one.
-      if (PrevFieldEnd < FieldBitOffset)
-        Padding.push_back(std::make_pair(PrevFieldEnd+BitOffset,
-                                         FieldBitOffset-PrevFieldEnd));
-      PrevFieldEnd =
-        FieldBitOffset + TD.getTypeSizeInBits(STy->getElementType(i));
-    }
-
-    //  Check for tail padding.
-    if (PrevFieldEnd < SL->getSizeInBits())
-      Padding.push_back(std::make_pair(PrevFieldEnd,
-                                       SL->getSizeInBits()-PrevFieldEnd));
-  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
-    uint64_t EltSize = getTargetData().getTypeSizeInBits(ATy->getElementType());
-    for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
-      FindLLVMTypePadding(ATy->getElementType(), 0, BitOffset+i*EltSize,
-                          Padding);
-  }
-
-  // primitive and vector types have no padding.
-}
-
-/// GCCTypeOverlapsWithPadding - Return true if the specified gcc type overlaps
-/// with the specified region of padding.  This only needs to handle types with
-/// a constant size.
-static bool GCCTypeOverlapsWithPadding(tree type, int PadStartBits,
-                                       int PadSizeBits) {
-  assert(type != error_mark_node);
-  // LLVM doesn't care about variants such as const, volatile, or restrict.
-  type = TYPE_MAIN_VARIANT(type);
-
-  // If the type does not overlap, don't bother checking below.
-
-  if (!isInt64(TYPE_SIZE(type), true))
-    // No size, negative size (!) or huge - be conservative.
-    return true;
-
-  if (!getInt64(TYPE_SIZE(type), true) ||
-      PadStartBits >= (int64_t)getInt64(TYPE_SIZE(type), false) ||
-      PadStartBits+PadSizeBits <= 0)
-    return false;
-
-
-  switch (TREE_CODE(type)) {
-  default:
-    DieAbjectly("Unknown type to compare!", type);
-  case VOID_TYPE:
-  case BOOLEAN_TYPE:
-  case ENUMERAL_TYPE:
-  case INTEGER_TYPE:
-  case REAL_TYPE:
-  case COMPLEX_TYPE:
-  case VECTOR_TYPE:
-  case POINTER_TYPE:
-  case REFERENCE_TYPE:
-  case OFFSET_TYPE:
-    // These types have no holes.
-    return true;
-
-  case ARRAY_TYPE: {
-    uint64_t NumElts = ArrayLengthOf(type);
-    if (NumElts == NO_LENGTH)
-      return true;
-    unsigned EltSizeBits = getInt64(TYPE_SIZE(TREE_TYPE(type)), true);
-
-    // Check each element for overlap.  This is inelegant, but effective.
-    for (unsigned i = 0; i != NumElts; ++i)
-      if (GCCTypeOverlapsWithPadding(TREE_TYPE(type),
-                                     PadStartBits- i*EltSizeBits, PadSizeBits))
-        return true;
-    return false;
-  }
-  case QUAL_UNION_TYPE:
-  case UNION_TYPE: {
-    // If this is a union with the transparent_union attribute set, it is
-    // treated as if it were just the same as its first type.
-    if (TYPE_TRANSPARENT_AGGR(type)) {
-      tree Field = TYPE_FIELDS(type);
-      assert(Field && "Transparent union must have some elements!");
-      assert(TREE_CODE(Field) == FIELD_DECL && "Lang data not freed?");
-      return GCCTypeOverlapsWithPadding(TREE_TYPE(Field),
-                                        PadStartBits, PadSizeBits);
-    }
-
-    // See if any elements overlap.
-    for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
-      assert(TREE_CODE(Field) == FIELD_DECL && "Lang data not freed?");
-      assert(getFieldOffsetInBits(Field) == 0 && "Union with non-zero offset?");
-      // Skip fields that are known not to be present.
-      if (TREE_CODE(type) == QUAL_UNION_TYPE &&
-          integer_zerop(DECL_QUALIFIER(Field)))
-        continue;
-
-      if (GCCTypeOverlapsWithPadding(TREE_TYPE(Field),
-                                     PadStartBits, PadSizeBits))
-        return true;
-
-      // Skip remaining fields if this one is known to be present.
-      if (TREE_CODE(type) == QUAL_UNION_TYPE &&
-          integer_onep(DECL_QUALIFIER(Field)))
-        break;
-    }
-
-    return false;
-  }
-
-  case RECORD_TYPE:
-    for (tree Field = TYPE_FIELDS(type); Field; Field = TREE_CHAIN(Field)) {
-      assert(TREE_CODE(Field) == FIELD_DECL && "Lang data not freed?");
-
-      if (!OffsetIsLLVMCompatible(Field))
-        // Variable or humongous offset.
-        return true;
-
-      uint64_t FieldBitOffset = getFieldOffsetInBits(Field);
-      if (GCCTypeOverlapsWithPadding(TREE_TYPE(Field),
-                                     PadStartBits-FieldBitOffset, PadSizeBits))
-        return true;
-    }
-    return false;
-  }
-}
-
-bool TypeConverter::GCCTypeOverlapsWithLLVMTypePadding(tree type,
-                                                       const Type *Ty) {
-
-  // Start by finding all of the padding in the LLVM Type.
-  SmallVector<std::pair<uint64_t,uint64_t>, 16> StructPadding;
-  FindLLVMTypePadding(Ty, type, 0, StructPadding);
-
-  for (unsigned i = 0, e = StructPadding.size(); i != e; ++i)
-    if (GCCTypeOverlapsWithPadding(type, StructPadding[i].first,
-                                   StructPadding[i].second))
-      return true;
-  return false;
-}
-
 
 //===----------------------------------------------------------------------===//
 //                      Main Type Conversion Routines
@@ -1633,47 +1475,6 @@
   OS.flush();
 }
 
-std::map<tree, 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(tree type, unsigned index) {
-
-  StructTypeConversionInfo *Info = StructTypeInfoMap[type];
-
-  // 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];
-}
-
-/// OldTy and NewTy are union members. If they are representing
-/// structs then adjust their PaddingElement bits. Padding
-/// field in one struct may not be a padding field in another
-/// struct.
-void adjustPaddingElement(tree oldtree, tree newtree) {
-
-  StructTypeConversionInfo *OldInfo = StructTypeInfoMap[oldtree];
-  StructTypeConversionInfo *NewInfo = StructTypeInfoMap[newtree];
-
-  if (!OldInfo || !NewInfo)
-    return;
-
-  /// FIXME : Find overlapping padding fields and preserve their
-  /// isPaddingElement bit. For now, clear all isPaddingElement bits.
-  for (unsigned i = 0, size =  NewInfo->PaddingElement.size(); i != size; ++i)
-    NewInfo->PaddingElement[i] = false;
-
-  for (unsigned i = 0, size =  OldInfo->PaddingElement.size(); i != size; ++i)
-    OldInfo->PaddingElement[i] = false;
-
-}
-
 /// DecodeStructFields - This method decodes the specified field, if it is a
 /// FIELD_DECL, adding or updating the specified StructTypeConversionInfo to
 /// reflect it.  Return true if field is decoded correctly. Otherwise return
@@ -1931,8 +1732,6 @@
     unsigned Align = Info.getTypeAlignment(TheTy);
     uint64_t Size  = Info.getTypeSize(TheTy);
 
-    adjustPaddingElement(GccUnionTy, TheGccTy);
-
     // Select TheTy as union type if it is the biggest/smallest field (depending
     // on the value of FindBiggest).  If more than one field achieves this size
     // then choose the least aligned.
@@ -2099,7 +1898,6 @@
     Info->RemoveExtraBytes();
 
   const Type *ResultTy = Info->getLLVMType();
-  StructTypeInfoMap[type] = Info;
 
   const OpaqueType *OldTy = cast_or_null<OpaqueType>(GET_TYPE_LLVM(type));
   TypeDB.setType(type, ResultTy);





More information about the llvm-commits mailing list