[cfe-commits] r46859 - in /cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CodeGenTypes.cpp test/CodeGen/bitfield.c

Lauro Ramos Venancio lauro.venancio at gmail.com
Thu Feb 7 11:29:55 PST 2008


Author: laurov
Date: Thu Feb  7 13:29:53 2008
New Revision: 46859

URL: http://llvm.org/viewvc/llvm-project?rev=46859&view=rev
Log:
Simplify bitfield codegen.
Fix codegen of struct { short a[3]; int b:15; }.


Modified:
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CodeGenTypes.cpp
    cfe/trunk/test/CodeGen/bitfield.c

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=46859&r1=46858&r2=46859&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Thu Feb  7 13:29:53 2008
@@ -454,7 +454,7 @@
 }
 
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
-
+  llvm::Value *V;
   bool isUnion = false;
   Expr *BaseExpr = E->getBase();
   llvm::Value *BaseValue = NULL;
@@ -476,14 +476,27 @@
   }
 
   FieldDecl *Field = E->getMemberDecl();
-
   unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
-  llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty), 
-                           llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
 
-  llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
+
+  if (Field->isBitField()) {
+    const llvm::Type * FieldTy = ConvertType(Field->getType());
+    const llvm::PointerType * BaseTy =
+      cast<llvm::PointerType>(BaseValue->getType());
+    unsigned AS = BaseTy->getAddressSpace();
+    BaseValue = Builder.CreateBitCast(BaseValue,
+                                      llvm::PointerType::get(FieldTy, AS),
+                                      "tmp");
+    V = Builder.CreateGEP(BaseValue,
+                          llvm::ConstantInt::get(llvm::Type::Int32Ty, idx),
+                          "tmp");
+  } else {
+    llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty),
+                             llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
+    V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
+  }
   // Match union field type.
-  if (isUnion || Field->isBitField()) {
+  if (isUnion) {
     const llvm::Type * FieldTy = ConvertType(Field->getType());
     const llvm::PointerType * BaseTy = 
       cast<llvm::PointerType>(BaseValue->getType());

Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=46859&r1=46858&r2=46859&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Thu Feb  7 13:29:53 2008
@@ -73,7 +73,6 @@
     uint64_t llvmSize;
     llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
     std::vector<const llvm::Type*> LLVMFields;
-    llvm::SmallVector<uint64_t, 8> Offsets;
     llvm::SmallSet<unsigned, 8> PaddingFields;
   };
 }
@@ -449,7 +448,6 @@
   llvmFieldNo = 0;
   Cursor = 0;
   LLVMFields.clear();
-  Offsets.clear();
 
   for (llvm::SmallVector<const FieldDecl *, 8>::iterator I = FieldDecls.begin(),
          E = FieldDecls.end(); I != E; ++I) {
@@ -499,7 +497,6 @@
   }
 
   unsigned TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-  Offsets.push_back(llvmSize);
   llvmSize += TySize;
   if (isPaddingField)
     PaddingFields.insert(llvmFieldNo);
@@ -555,51 +552,26 @@
   assert (isBitField  && "Invalid BitField size expression");
   uint64_t BitFieldSize =  FieldSize.getZExtValue();
 
-  bool FoundPrevField = false;
-  unsigned TotalOffsets = Offsets.size();
   const llvm::Type *Ty = CGT.ConvertType(FD->getType());
   uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-  
-  if (!TotalOffsets) {
-    // Special case: the first field. 
-    CGT.addFieldInfo(FD, llvmFieldNo);
+
+  unsigned Idx = Cursor / TySize;
+  unsigned BitsLeft = TySize - (Cursor % TySize);
+
+  if (BitsLeft >= BitFieldSize) {
+    // The bitfield fits in the last aligned field.
+    // This is : struct { char a; int CurrentField:10;};
+    // where 'CurrentField' shares first field with 'a'.
+    CGT.addFieldInfo(FD, Idx);
+    CGT.addBitFieldInfo(FD, TySize - BitsLeft, BitFieldSize);
+    Cursor += BitFieldSize;
+  } else {
+    // Place the bitfield in a new LLVM field.
+    // This is : struct { char a; short CurrentField:10;};
+    // where 'CurrentField' needs a new llvm field.
+    CGT.addFieldInfo(FD, Idx + 1);
     CGT.addBitFieldInfo(FD, 0, BitFieldSize);
-    addPaddingFields(BitFieldSize);
-    Cursor = BitFieldSize;
-    return;
-  }
-
-  // Search for the last aligned field.
-  for (unsigned i = TotalOffsets; i != 0; --i) {
-    uint64_t O = Offsets[i - 1];
-    if (O % TySize == 0) {
-      FoundPrevField = true;
-      if (TySize > (Cursor - O) && TySize - (Cursor - O) >= BitFieldSize) {
-	// The bitfield fits in the last aligned field.
-	// This is : struct { char a; int CurrentField:10;};
-	// where 'CurrentField' shares first field with 'a'.
-	addPaddingFields(Cursor + BitFieldSize);
-	CGT.addFieldInfo(FD, i - 1);
-	CGT.addBitFieldInfo(FD, Cursor - O, BitFieldSize);
-	Cursor += BitFieldSize;
-      } else {
-	// Place the bitfield in a new LLVM field.
-	// This is : struct { char a; short CurrentField:10;};
-	// where 'CurrentField' needs a new llvm field.
-        unsigned Padding = 0;
-        if (Cursor % TySize) {
-          Padding = TySize - (Cursor % TySize);
-          addPaddingFields(Cursor + Padding);
-        }
-	CGT.addFieldInfo(FD, llvmFieldNo);
-	CGT.addBitFieldInfo(FD, 0, BitFieldSize);
-        Cursor += Padding + BitFieldSize;
-	addPaddingFields(Cursor);
-      }
-      break;
-    }
+    Cursor = (Idx + 1) * TySize + BitFieldSize;
   }
-
-  assert(FoundPrevField && 
-	 "Unable to find a place for bitfield in struct layout");
+  addPaddingFields(Cursor);
 }

Modified: cfe/trunk/test/CodeGen/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/bitfield.c?rev=46859&r1=46858&r2=46859&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/bitfield.c (original)
+++ cfe/trunk/test/CodeGen/bitfield.c Thu Feb  7 13:29:53 2008
@@ -5,10 +5,12 @@
 // RUN: grep "lshr i16 %tmp5, 9" %t1
 // RUN: grep "and i32 %tmp, -8192" %t1
 // RUN: grep "and i16 %tmp5, -32513" %t1
+// RUN: grep "getelementptr (i32\* bitcast (.struct.STestB2\* @stb2 to i32\*), i32 1)" %t1
 // Test bitfield access
 
 
 struct STestB1 { int a:13; char b; unsigned short c:7;} stb1;
+struct STestB2 { short a[3]; int b:15} stb2;
 
 int f() {
   return stb1.a + stb1.b + stb1.c;
@@ -19,3 +21,12 @@
   stb1.b = 10;
   stb1.c = 15;
 }
+
+int h() {
+  return stb2.a[1] + stb2.b;
+}
+
+void i(){
+  stb2.a[2] = -40;
+  stb2.b = 10;
+}





More information about the cfe-commits mailing list