diff options
author | Anders Carlsson <andersca@mac.com> | 2009-07-23 17:01:21 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-07-23 17:01:21 +0000 |
commit | 8330ceeebb3bfac31116b387b90ff2ce3cef85e4 (patch) | |
tree | 35042c9a783cc668d2dab4fa0e9166736d50acf5 | |
parent | bd1099efde211cbb63fce3feee4ebcc6bac58781 (diff) |
Move the LLVM field number for bit fields into the BitFieldInfo structure, since it's meaning is completely different than for non-bit fields.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76882 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.h | 6 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 21 |
6 files changed, 46 insertions, 41 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index de44e69721..9b5b68d3f6 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1026,7 +1026,8 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, FieldDecl* Field, unsigned CVRQualifiers) { - unsigned idx = CGM.getTypes().getLLVMFieldNo(Field); + CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); + // FIXME: CodeGenTypes should expose a method to get the appropriate type for // FieldTy (the appropriate type is ABI-dependent). const llvm::Type *FieldTy = @@ -1037,13 +1038,12 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, BaseValue = Builder.CreateBitCast(BaseValue, VMContext.getPointerType(FieldTy, AS), "tmp"); - llvm::Value *V = Builder.CreateGEP(BaseValue, - VMContext.getConstantInt(llvm::Type::Int32Ty, idx), - "tmp"); - CodeGenTypes::BitFieldInfo bitFieldInfo = - CGM.getTypes().getBitFieldInfo(Field); - return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size, + llvm::Value *Idx = + VMContext.getConstantInt(llvm::Type::Int32Ty, Info.FieldNo); + llvm::Value *V = Builder.CreateGEP(BaseValue, Idx, "tmp"); + + return LValue::MakeBitfield(V, Info.Start, Info.Size, Field->getType()->isSignedIntegerType(), Field->getType().getCVRQualifiers()|CVRQualifiers); } diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 43284b5173..61b217bc66 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -139,16 +139,16 @@ public: const llvm::Type* Ty = CI->getType(); const llvm::TargetData &TD = CGM.getTypes().getTargetData(); unsigned size = TD.getTypeAllocSizeInBits(Ty); - unsigned fieldOffset = CGM.getTypes().getLLVMFieldNo(Field) * size; - CodeGenTypes::BitFieldInfo bitFieldInfo = - CGM.getTypes().getBitFieldInfo(Field); - fieldOffset += bitFieldInfo.Begin; + CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field); + unsigned FieldOffset = Info.FieldNo * size; + + FieldOffset += Info.Start; // Find where to start the insertion // FIXME: This is O(n^2) in the number of bit-fields! // FIXME: This won't work if the struct isn't completely packed! unsigned offset = 0, i = 0; - while (offset < (fieldOffset & -8)) + while (offset < (FieldOffset & -8)) offset += TD.getTypeAllocSizeInBits(Elts[i++]->getType()); // Advance over 0 sized elements (must terminate in bounds since @@ -160,15 +160,15 @@ public: // FIXME: This should never occur, but currently it can because initializer // constants are cast to bool, and because clang is not enforcing bitfield // width limits. - if (bitFieldInfo.Size > V.getBitWidth()) - V.zext(bitFieldInfo.Size); + if (Info.Size > V.getBitWidth()) + V.zext(Info.Size); // Insert the bits into the struct // FIXME: This algorthm is only correct on X86! // FIXME: THis algorthm assumes bit-fields only have byte-size elements! - unsigned bitsToInsert = bitFieldInfo.Size; - unsigned curBits = std::min(8 - (fieldOffset & 7), bitsToInsert); - unsigned byte = V.getLoBits(curBits).getZExtValue() << (fieldOffset & 7); + unsigned bitsToInsert = Info.Size; + unsigned curBits = std::min(8 - (FieldOffset & 7), bitsToInsert); + unsigned byte = V.getLoBits(curBits).getZExtValue() << (FieldOffset & 7); do { llvm::Constant* byteC = VMContext.getConstantInt(llvm::Type::Int8Ty, byte); diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index fa096bd630..5f6946db6b 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -85,8 +85,8 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType()); uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8; - LLVMFields.push_back(LLVMFieldInfo(D, FieldOffset / TypeSizeInBits)); - LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset % TypeSizeInBits, + LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset / TypeSizeInBits, + FieldOffset % TypeSizeInBits, FieldSize)); AppendBytes(NumBytesToAppend); @@ -190,13 +190,13 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { // Now add our field. if (FD) { AppendField(0, Size, Ty); - Types.addFieldInfo(FD, 0); if (FD->isBitField()) { uint64_t FieldSize = FD->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue(); - Types.addBitFieldInfo(FD, 0, FieldSize); - } + Types.addBitFieldInfo(FD, 0, 0, FieldSize); + } else + Types.addFieldInfo(FD, 0); } // Append tail padding. @@ -324,7 +324,7 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types, for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) { const LLVMBitFieldInfo &Info = Builder.LLVMBitFields[i]; - Types.addBitFieldInfo(Info.FD, Info.Start, Info.Size); + Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size); } return new CGRecordLayout(Ty, llvm::SmallSet<unsigned, 8>()); diff --git a/lib/CodeGen/CGRecordLayoutBuilder.h b/lib/CodeGen/CGRecordLayoutBuilder.h index c1ba6056d7..2f212f86c0 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.h +++ b/lib/CodeGen/CGRecordLayoutBuilder.h @@ -66,11 +66,13 @@ class CGRecordLayoutBuilder { /// LLVMBitFieldInfo - Holds location and size information about a bit field. struct LLVMBitFieldInfo { - LLVMBitFieldInfo(const FieldDecl *FD, unsigned Start, unsigned Size) - : FD(FD), Start(Start), Size(Size) { } + LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start, + unsigned Size) + : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { } const FieldDecl *FD; + unsigned FieldNo; unsigned Start; unsigned Size; }; diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 59463fa24f..0869b2d11c 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -494,6 +494,8 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) { /// getLLVMFieldNo - Return llvm::StructType element number /// that corresponds to the field FD. unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) { + assert(!FD->isBitField() && "Don't use getLLVMFieldNo on bit fields!"); + llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD); assert (I != FieldInfo.end() && "Unable to find field info"); return I->second; @@ -513,9 +515,9 @@ CodeGenTypes::BitFieldInfo CodeGenTypes::getBitFieldInfo(const FieldDecl *FD) { } /// addBitFieldInfo - Assign a start bit and a size to field FD. -void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned Begin, - unsigned Size) { - BitFields.insert(std::make_pair(FD, BitFieldInfo(Begin, Size))); +void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, + unsigned Start, unsigned Size) { + BitFields.insert(std::make_pair(FD, BitFieldInfo(FieldNo, Start, Size))); } /// getCGRecordLayout - Return record layout info for the given llvm::Type. @@ -559,8 +561,7 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) { // Bitfield field info is different from other field info; // it actually ignores the underlying LLVM struct because // there isn't any convenient mapping. - CGT.addFieldInfo(*Field, offset / size); - CGT.addBitFieldInfo(*Field, offset % size, BitFieldSize); + CGT.addBitFieldInfo(*Field, offset / size, offset % size, BitFieldSize); } else { // Put the element into the struct. This would be simpler // if we didn't bother, but it seems a bit too strange to @@ -603,8 +604,7 @@ void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) { uint64_t BitFieldSize = BitWidth->EvaluateAsInt(CGT.getContext()).getZExtValue(); - CGT.addFieldInfo(*Field, 0); - CGT.addBitFieldInfo(*Field, offset, BitFieldSize); + CGT.addBitFieldInfo(*Field, 0, offset, BitFieldSize); } else { CGT.addFieldInfo(*Field, 0); } diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index 925b933fca..0f6e51d1d3 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -113,13 +113,15 @@ class CodeGenTypes { llvm::FoldingSet<CGFunctionInfo> FunctionInfos; public: - class BitFieldInfo { - public: - explicit BitFieldInfo(unsigned short B, unsigned short S) - : Begin(B), Size(S) {} - - unsigned short Begin; - unsigned short Size; + struct BitFieldInfo { + BitFieldInfo(unsigned FieldNo, + unsigned Start, + unsigned Size) + : FieldNo(FieldNo), Start(Start), Size(Size) {} + + unsigned FieldNo; + unsigned Start; + unsigned Size; }; private: @@ -188,10 +190,11 @@ public: public: // These are internal details of CGT that shouldn't be used externally. /// addFieldInfo - Assign field number to field FD. - void addFieldInfo(const FieldDecl *FD, unsigned No); + void addFieldInfo(const FieldDecl *FD, unsigned FieldNo); /// addBitFieldInfo - Assign a start bit and a size to field FD. - void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size); + void addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, + unsigned Start, unsigned Size); /// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field /// FD. |