[llvm-branch-commits] [llvm-gcc-branch] r100727 - in /llvm-gcc-4.2/branches/Apple/Morbo: ./ gcc/llvm-types.cpp

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed Apr 7 16:56:39 PDT 2010


Author: stoklund
Date: Wed Apr  7 18:56:38 2010
New Revision: 100727

URL: http://llvm.org/viewvc/llvm-project?rev=100727&view=rev
Log:
$ svn merge -c 100721 https://llvm.org/svn/llvm-project/llvm-gcc-4.2/trunk
--- Merging r100721 into '.':
U    gcc/llvm-types.cpp

Bitfields

Modified:
    llvm-gcc-4.2/branches/Apple/Morbo/   (props changed)
    llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-types.cpp

Propchange: llvm-gcc-4.2/branches/Apple/Morbo/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Apr  7 18:56:38 2010
@@ -1,2 +1,2 @@
 /llvm/trunk:100565
-/llvm-gcc-4.2/trunk:98728,98841,98893,99196,99305,99592-99593,99629,99670,99982,99984-99986,99988,99992-99993,99995,99997-99999,100035,100149,100303,100565,100624-100626
+/llvm-gcc-4.2/trunk:98728,98841,98893,99196,99305,99592-99593,99629,99670,99982,99984-99986,99988,99992-99993,99995,99997-99999,100035,100149,100303,100565,100624-100626,100721

Modified: llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-types.cpp?rev=100727&r1=100726&r2=100727&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-types.cpp Wed Apr  7 18:56:38 2010
@@ -1618,7 +1618,8 @@
     return ~0U;
   }
 
-  void addNewBitField(uint64_t Size, uint64_t FirstUnallocatedByte);
+  void addNewBitField(uint64_t Size, uint64_t Extra,
+                      uint64_t FirstUnallocatedByte);
 
   void dump() const;
 };
@@ -1626,22 +1627,43 @@
 // Add new element which is a bit field. Size is not the size of bit field,
 // but size of bits required to determine type of new Field which will be
 // used to access this bit field.
-void StructTypeConversionInfo::addNewBitField(uint64_t Size,
+// If possible, allocate a field with room for Size+Extra bits.
+void StructTypeConversionInfo::addNewBitField(uint64_t Size, uint64_t Extra,
                                               uint64_t FirstUnallocatedByte) {
 
   // Figure out the LLVM type that we will use for the new field.
   // Note, Size is not necessarily size of the new field. It indicates
   // additional bits required after FirstunallocatedByte to cover new field.
-  const Type *NewFieldTy;
-  if (Size <= 8)
-    NewFieldTy = Type::getInt8Ty(Context);
-  else if (Size <= 16)
-    NewFieldTy = Type::getInt16Ty(Context);
-  else if (Size <= 32)
-    NewFieldTy = Type::getInt32Ty(Context);
-  else {
-    assert(Size <= 64 && "Bitfield too large!");
-    NewFieldTy = Type::getInt64Ty(Context);
+  const Type *NewFieldTy = 0;
+
+  // First try an ABI-aligned field including (some of) the Extra bits.
+  // This field must satisfy Size <= w && w <= XSize.
+  uint64_t XSize = Size + Extra;
+  for (unsigned w = NextPowerOf2(std::min(UINT64_C(64), XSize))/2;
+       w >= Size && w >= 8; w /= 2) {
+    if (TD.isIllegalInteger(w))
+      continue;
+    // Would a w-sized integer field be aligned here?
+    const unsigned a = TD.getABIIntegerTypeAlignment(w);
+    if (FirstUnallocatedByte & (a-1) || a > getGCCStructAlignmentInBytes())
+      continue;
+    // OK, use w-sized integer.
+    NewFieldTy = IntegerType::get(Context, w);
+    break;
+  }
+
+  // Try an integer field that holds Size bits.
+  if (!NewFieldTy) {
+    if (Size <= 8)
+      NewFieldTy = Type::getInt8Ty(Context);
+    else if (Size <= 16)
+      NewFieldTy = Type::getInt16Ty(Context);
+    else if (Size <= 32)
+      NewFieldTy = Type::getInt32Ty(Context);
+    else {
+      assert(Size <= 64 && "Bitfield too large!");
+      NewFieldTy = Type::getInt64Ty(Context);
+    }
   }
 
   // Check that the alignment of NewFieldTy won't cause a gap in the structure!
@@ -1985,7 +2007,34 @@
   // LLVM struct such that there are no holes in the struct where the bitfield
   // is: these holes would make it impossible to statically initialize a global
   // of this type that has an initializer for the bitfield.
-  
+
+  // We want the integer-typed fields as large as possible up to the machine
+  // word size. If there are more bitfields following this one, try to include
+  // them in the same field.
+
+  // Calculate the total number of bits in the continuous group of bitfields
+  // following this one. This is the number of bits that addNewBitField should
+  // try to include.
+  unsigned ExtraSizeInBits = 0;
+  tree LastBitField = 0;
+  for (tree f = TREE_CHAIN(Field); f; f = TREE_CHAIN(f)) {
+    if (TREE_CODE(f) != FIELD_DECL ||
+        TREE_CODE(DECL_FIELD_OFFSET(f)) != INTEGER_CST)
+      break;
+    if (isBitfield(f))
+      LastBitField = f;
+    else {
+      // We can use all this bits up to the next non-bitfield.
+      LastBitField = 0;
+      ExtraSizeInBits = getFieldOffsetInBits(f) - EndBitOffset;
+      break;
+    }
+  }
+  // Record ended in a bitfield? Use all of the last byte.
+  if (LastBitField)
+    ExtraSizeInBits = RoundUpToAlignment(getFieldOffsetInBits(LastBitField) +
+      TREE_INT_CST_LOW(DECL_SIZE(LastBitField)), 8) - EndBitOffset;
+
   // Compute the number of bits that we need to add to this struct to cover
   // this field.
   uint64_t FirstUnallocatedByte = Info.getEndUnallocatedByte();
@@ -1999,7 +2048,7 @@
       // This field starts at byte boundry. Need to allocate space
       // for additional bytes not yet allocated.
       unsigned NumBitsToAdd = FieldSizeInBits - AvailableBits;
-      Info.addNewBitField(NumBitsToAdd, FirstUnallocatedByte);
+      Info.addNewBitField(NumBitsToAdd, ExtraSizeInBits, FirstUnallocatedByte);
       return;
     }
 
@@ -2023,7 +2072,7 @@
       for (unsigned idx = 0; idx < (prevFieldTypeSizeInBits/8); ++idx)
 	FirstUnallocatedByte--;
     }
-    Info.addNewBitField(NumBitsRequired, FirstUnallocatedByte);
+    Info.addNewBitField(NumBitsRequired, ExtraSizeInBits, FirstUnallocatedByte);
     // Do this after adding Field.
     Info.lastFieldStartsAtNonByteBoundry(true);
     return;
@@ -2057,7 +2106,7 @@
   }
 
   // Now, Field starts at FirstUnallocatedByte and everything is aligned.
-  Info.addNewBitField(FieldSizeInBits, FirstUnallocatedByte);
+  Info.addNewBitField(FieldSizeInBits, ExtraSizeInBits, FirstUnallocatedByte);
 }
 
 /// UnionHasOnlyZeroOffsets - Check if a union type has only members with
@@ -2129,7 +2178,7 @@
 
     if (isBitfield(UnionField)) {
       unsigned FieldSizeInBits = TREE_INT_CST_LOW(DECL_SIZE(UnionField));
-      Info.addNewBitField(FieldSizeInBits, 0);
+      Info.addNewBitField(FieldSizeInBits, 0, 0);
     } else {
       Info.allFieldsAreNotBitFields();
       Info.addElement(UnionTy, 0, Info.getTypeSize(UnionTy));





More information about the llvm-branch-commits mailing list