[cfe-commits] r44875 - /cfe/trunk/CodeGen/CodeGenTypes.cpp
Devang Patel
dpatel at apple.com
Tue Dec 11 11:51:40 PST 2007
Author: dpatel
Date: Tue Dec 11 13:51:39 2007
New Revision: 44875
URL: http://llvm.org/viewvc/llvm-project?rev=44875&view=rev
Log:
Refactor bit-field handling code into a separate method.
No functionality change.
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=44875&r1=44874&r2=44875&view=diff
==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Tue Dec 11 13:51:39 2007
@@ -78,6 +78,9 @@
/// or last record field is a bit-field.
void fixCursorPosition(const ASTRecordLayout &RL);
+ /// placeBitField - Find a place for FD, which is a bit-field.
+ void placeBitField(const FieldDecl *FD);
+
private:
CodeGenTypes &CGT;
llvm::Type *STy;
@@ -415,75 +418,9 @@
E = FieldDecls.end(); I != E; ++I) {
const FieldDecl *FD = *I;
- if (FD->isBitField()) {
- Expr *BitWidth = FD->getBitWidth();
- llvm::APSInt FieldSize(32);
- bool isBitField =
- BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
- assert (isBitField && "Invalid BitField size expression");
- uint64_t BitFieldSize = FieldSize.getZExtValue();
- if (ExtraBits == 0) {
- // CurrentField is a bit-field and structure is in one of the
- // following form.
- // struct { char CurrentField:2; char B:4; }
- // struct { char A; char CurrentField:2; };
- // struct { char A; short CurrentField:2; };
- const llvm::Type *Ty = CGT.ConvertType(FD->getType());
- // Calculate extra bits available in this bitfield.
- ExtraBits = CGT.getTargetData().getABITypeSizeInBits(Ty) - BitFieldSize;
-
- if (LLVMFields.empty())
- // Ths is - struct { char CurrentField:2; char B:4; }
- addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
- else {
- const llvm::Type *PrevTy = LLVMFields.back();
- if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >=
- CGT.getTargetData().getABITypeSizeInBits(Ty))
- // This is - struct { char A; char CurrentField:2; };
- addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
- else {
- // This is - struct { char A; short CurrentField:2; };
- // Use one of the previous filed to access current field.
- bool FoundPrevField = false;
- unsigned TotalOffsets = Offsets.size();
- uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- for (unsigned i = TotalOffsets; i != 0; --i) {
- uint64_t O = Offsets[i - 1];
- if (O % TySize == 0) {
- // This is appropriate llvm field to share access.
- FoundPrevField = true;
- CurrentFieldStart = O % TySize;
- unsigned FieldBegin = Cursor - (O % TySize);
- unsigned FieldEnd = TySize - (FieldBegin + BitFieldSize);
- Cursor += BitFieldSize;
- CGT.addFieldInfo(FD, i, FieldBegin, FieldEnd);
- }
- }
- assert(FoundPrevField &&
- "Unable to find a place for bitfield in struct layout");
- }
- }
- } else if (ExtraBits >= BitFieldSize) {
- // 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());
- const llvm::Type *PrevTy = LLVMFields.back();
- uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
- if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >= TySize) {
- // Previous field does not allow sharing of ExtraBits. Use new field.
- // struct { char a; char b:5; char c:4; } where c is current FD.
- Cursor += ExtraBits;
- ExtraBits = 0;
- addLLVMField(Ty, TySize, FD, 0, BitFieldSize);
- } else
- assert (!FD->isBitField() && "Bit fields are not yet supported");
- }
- } else {
+ if (FD->isBitField())
+ placeBitField(FD);
+ else {
ExtraBits = 0;
// FD is not a bitfield. If prev field was a bit field then it may have
// positioned cursor such that it needs adjustment now.
@@ -597,3 +534,83 @@
addPaddingFields(StructPadding*8);
}
}
+
+/// placeBitField - Find a place for FD, which is a bit-field.
+/// There are three separate cases to handle
+/// 1) Cursor starts at byte boundry and there are no extra
+/// bits are available in last llvm struct field.
+/// 2) Extra bits from previous last llvm struct field are
+/// available and have enough space to hold entire FD.
+/// 3) Extra bits from previous last llvm struct field are
+/// available but they are not enough to hold FD entirly.
+void RecordOrganizer::placeBitField(const FieldDecl *FD) {
+
+ assert (FD->isBitField() && "FD is not a bit-field");
+ Expr *BitWidth = FD->getBitWidth();
+ llvm::APSInt FieldSize(32);
+ bool isBitField =
+ BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
+ assert (isBitField && "Invalid BitField size expression");
+ uint64_t BitFieldSize = FieldSize.getZExtValue();
+ if (ExtraBits == 0) {
+ // CurrentField is a bit-field and structure is in one of the
+ // following form.
+ // struct { char CurrentField:2; char B:4; }
+ // struct { char A; char CurrentField:2; };
+ // struct { char A; short CurrentField:2; };
+ const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+ // Calculate extra bits available in this bitfield.
+ ExtraBits = CGT.getTargetData().getABITypeSizeInBits(Ty) - BitFieldSize;
+
+ if (LLVMFields.empty())
+ // Ths is - struct { char CurrentField:2; char B:4; }
+ addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
+ else {
+ const llvm::Type *PrevTy = LLVMFields.back();
+ if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >=
+ CGT.getTargetData().getABITypeSizeInBits(Ty))
+ // This is - struct { char A; char CurrentField:2; };
+ addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
+ else {
+ // This is - struct { char A; short CurrentField:2; };
+ // Use one of the previous filed to access current field.
+ bool FoundPrevField = false;
+ unsigned TotalOffsets = Offsets.size();
+ uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
+ for (unsigned i = TotalOffsets; i != 0; --i) {
+ uint64_t O = Offsets[i - 1];
+ if (O % TySize == 0) {
+ // This is appropriate llvm field to share access.
+ FoundPrevField = true;
+ CurrentFieldStart = O % TySize;
+ unsigned FieldBegin = Cursor - (O % TySize);
+ unsigned FieldEnd = TySize - (FieldBegin + BitFieldSize);
+ Cursor += BitFieldSize;
+ CGT.addFieldInfo(FD, i, FieldBegin, FieldEnd);
+ }
+ }
+ assert(FoundPrevField &&
+ "Unable to find a place for bitfield in struct layout");
+ }
+ }
+ } else if (ExtraBits >= BitFieldSize) {
+ // 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());
+ const llvm::Type *PrevTy = LLVMFields.back();
+ uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
+ if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >= TySize) {
+ // Previous field does not allow sharing of ExtraBits. Use new field.
+ // struct { char a; char b:5; char c:4; } where c is current FD.
+ Cursor += ExtraBits;
+ ExtraBits = 0;
+ addLLVMField(Ty, TySize, FD, 0, BitFieldSize);
+ } else
+ assert (!FD->isBitField() && "Bit fields are not yet supported");
+ }
+}
More information about the cfe-commits
mailing list