[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