aboutsummaryrefslogtreecommitdiff
path: root/CodeGen/CodeGenTypes.cpp
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@gmail.com>2008-02-07 19:29:53 +0000
committerLauro Ramos Venancio <lauro.venancio@gmail.com>2008-02-07 19:29:53 +0000
commitd957aa09333ff428f9675fb9f66dde632c2bcf5d (patch)
treeca4754ad26061e89ee1e397be42f0afa9f5fea9c /CodeGen/CodeGenTypes.cpp
parent8432f4b4cdd1707f7f5dc06f35b4597dca252f2c (diff)
Simplify bitfield codegen.
Fix codegen of struct { short a[3]; int b:15; }. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46859 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'CodeGen/CodeGenTypes.cpp')
-rw-r--r--CodeGen/CodeGenTypes.cpp64
1 files changed, 18 insertions, 46 deletions
diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp
index 93b441bc62..bed01eeb61 100644
--- a/CodeGen/CodeGenTypes.cpp
+++ b/CodeGen/CodeGenTypes.cpp
@@ -73,7 +73,6 @@ namespace {
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 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
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 @@ void RecordOrganizer::addLLVMField(const llvm::Type *Ty, bool isPaddingField) {
}
unsigned TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- Offsets.push_back(llvmSize);
llvmSize += TySize;
if (isPaddingField)
PaddingFields.insert(llvmFieldNo);
@@ -555,51 +552,26 @@ void RecordOrganizer::placeBitField(const FieldDecl *FD) {
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);
- 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;
- }
- }
+ unsigned Idx = Cursor / TySize;
+ unsigned BitsLeft = TySize - (Cursor % TySize);
- assert(FoundPrevField &&
- "Unable to find a place for bitfield in struct layout");
+ 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);
+ Cursor = (Idx + 1) * TySize + BitFieldSize;
+ }
+ addPaddingFields(Cursor);
}