[cfe-commits] r45284 - /cfe/trunk/CodeGen/CodeGenTypes.cpp
Devang Patel
dpatel at apple.com
Fri Dec 21 10:43:55 PST 2007
Author: dpatel
Date: Fri Dec 21 12:43:53 2007
New Revision: 45284
URL: http://llvm.org/viewvc/llvm-project?rev=45284&view=rev
Log:
Keep track of llvm struct size while adding fields.
Update addPaddingFields() interface.
Modified:
cfe/trunk/CodeGen/CodeGenTypes.cpp
Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=45284&r1=45283&r2=45284&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Fri Dec 21 12:43:53 2007
@@ -34,7 +34,7 @@
public:
explicit RecordOrganizer(CodeGenTypes &Types) :
CGT(Types), STy(NULL), FieldNo(0), Cursor(0), ExtraBits(0),
- CurrentFieldStart(0) {}
+ CurrentFieldStart(0), llvmSize(0) {}
/// addField - Add new field.
void addField(const FieldDecl *FD);
@@ -47,7 +47,7 @@
/// addPaddingFields - Current cursor is not suitable place to add next
/// field. Add required padding fields.
- void addPaddingFields(unsigned RequiredBits);
+ void addPaddingFields(unsigned WaterMark);
/// layoutStructFields - Do the actual work and lay out all fields. Create
/// corresponding llvm struct type. This should be invoked only after
@@ -93,7 +93,8 @@
When current llvm field is shared by multiple bitfields, this is
used find starting bit offset for the bitfield from the beginning of
llvm field. */
- uint64_t CurrentFieldStart;
+ uint64_t CurrentFieldStart;
+ uint64_t llvmSize;
llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
std::vector<const llvm::Type*> LLVMFields;
llvm::SmallVector<uint64_t, 8> Offsets;
@@ -445,7 +446,8 @@
/// addPaddingFields - Current cursor is not suitable place to add next field.
/// Add required padding fields.
-void RecordOrganizer::addPaddingFields(unsigned RequiredBits) {
+void RecordOrganizer::addPaddingFields(unsigned WaterMark) {
+ unsigned RequiredBits = WaterMark - Cursor;
assert ((RequiredBits % 8) == 0 && "FIXME Invalid struct layout");
unsigned RequiredBytes = RequiredBits / 8;
for (unsigned i = 0; i != RequiredBytes; ++i)
@@ -461,16 +463,18 @@
unsigned End) {
unsigned AlignmentInBits = CGT.getTargetData().getABITypeAlignment(Ty) * 8;
- if (Cursor % AlignmentInBits != 0)
+ unsigned WaterMark = Cursor + (Cursor % AlignmentInBits);
+ if (Cursor != WaterMark)
// At the moment, insert padding fields even if target specific llvm
// type alignment enforces implict padding fields for FD. Later on,
// optimize llvm fields by removing implicit padding fields and
// combining consequetive padding fields.
- addPaddingFields(Cursor % AlignmentInBits);
+ addPaddingFields(WaterMark);
Offsets.push_back(Cursor);
CurrentFieldStart = Cursor;
Cursor += Size;
+ llvmSize += Size;
LLVMFields.push_back(Ty);
if (FD)
CGT.addFieldInfo(FD, FieldNo, Begin, End);
@@ -524,18 +528,12 @@
/// should be done only if next field (i.e. 'c' here) is not a bit-field
/// or last record field is a bit-field.
void RecordOrganizer::fixCursorPosition(const ASTRecordLayout &RL) {
- uint64_t llvmSize = 0;
- for(std::vector<const llvm::Type*>::iterator LI = LLVMFields.begin(),
- LE = LLVMFields.end(); LI != LE; ++LI) {
- const llvm::Type *Ty = *LI;
- llvmSize += CGT.getTargetData().getABITypeSizeInBits(Ty);
- }
Cursor = llvmSize;
unsigned llvmSizeBytes = llvmSize/8;
unsigned StructAlign = RL.getAlignment() / 8;
if (llvmSizeBytes % StructAlign) {
unsigned StructPadding = StructAlign - (llvmSizeBytes % StructAlign);
- addPaddingFields(StructPadding*8);
+ addPaddingFields(Cursor + StructPadding*8);
}
}
@@ -600,14 +598,25 @@
} else if (ExtraBits >= BitFieldSize) {
const llvm::Type *Ty = CGT.ConvertType(FD->getType());
uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- assert ( Cursor - CurrentFieldStart + BitFieldSize <= TySize
- && "Incomplete layout. struct {char a; int b:10; int c:18;};");
-
+ if (Cursor - CurrentFieldStart + BitFieldSize > TySize) {
+ // This is : struct { char a; int b:10; int c:18; };
+ // where 'b' shares first field with 'a'. However 'c' needs
+ // new llvm field.
+
+ //unsigned ExtraBitsInCurrentByte = 8 - (Cursor % 8);
+ //Cursor = Cursor + ExtraBitsInCurrentByte;
+ //ExtraBits = 0;
+ Cursor = llvmSize;
+ unsigned EndOfCurrentType = CurrentFieldStart + TySize;
+ addPaddingFields(EndOfCurrentType);
+ addLLVMField(Ty, TySize, FD, 0, BitFieldSize);
+ } else {
// Reuse existing llvm field
ExtraBits = ExtraBits - BitFieldSize;
CGT.addFieldInfo(FD, FieldNo, Cursor - CurrentFieldStart, ExtraBits);
Cursor = Cursor + BitFieldSize;
++FieldNo;
+ }
} else {
//ExtraBits are not enough to hold entire FD.
const llvm::Type *Ty = CGT.ConvertType(FD->getType());
More information about the cfe-commits
mailing list