From 7f2896406c8f14bf123578610043a919ba1a1c8a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 8 Apr 2010 02:59:45 +0000 Subject: [PATCH] IRgen: Move the bit-field access type into CGBitFieldInfo, and change bit-field LValues to just store the base address of object containing the bit-field. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100745 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 33 +++++++++++++++------------ lib/CodeGen/CGObjCMac.cpp | 4 ++-- lib/CodeGen/CGRecordLayout.h | 9 +++++--- lib/CodeGen/CGRecordLayoutBuilder.cpp | 8 +++---- lib/CodeGen/CGValue.h | 12 +++++++--- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0aa4438f4f..6fd18f395c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -603,12 +603,27 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { return EmitLoadOfKVCRefLValue(LV, ExprType); } +static llvm::Value *getBitFieldAddr(LValue LV, CGBuilderTy &Builder) { + const CGBitFieldInfo &Info = LV.getBitFieldInfo(); + + llvm::Value *BaseValue = LV.getBitFieldBaseAddr(); + const llvm::PointerType *BaseTy = + cast(BaseValue->getType()); + + // Cast to the type of the access we will perform. + llvm::Value *V = Builder.CreateBitCast( + BaseValue, llvm::PointerType::get(Info.FieldTy, BaseTy->getAddressSpace())); + + // Offset by the access index. + return Builder.CreateConstGEP1_32(V, Info.FieldNo); +} + RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType) { const CGBitFieldInfo &Info = LV.getBitFieldInfo(); unsigned StartBit = Info.Start; unsigned BitfieldSize = Info.Size; - llvm::Value *Ptr = LV.getBitFieldAddr(); + llvm::Value *Ptr = getBitFieldAddr(LV, Builder); const llvm::Type *EltTy = cast(Ptr->getType())->getElementType(); @@ -785,7 +800,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, const CGBitFieldInfo &Info = Dst.getBitFieldInfo(); unsigned StartBit = Info.Start; unsigned BitfieldSize = Info.Size; - llvm::Value *Ptr = Dst.getBitFieldAddr(); + llvm::Value *Ptr = getBitFieldAddr(Dst, Builder); const llvm::Type *EltTy = cast(Ptr->getType())->getElementType(); @@ -1474,19 +1489,7 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(Field->getParent()); const CGBitFieldInfo &Info = RL.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 = - CGM.getTypes().ConvertTypeForMem(Field->getType()); - const llvm::PointerType *BaseTy = - cast(BaseValue->getType()); - unsigned AS = BaseTy->getAddressSpace(); - BaseValue = Builder.CreateBitCast(BaseValue, - llvm::PointerType::get(FieldTy, AS)); - llvm::Value *V = Builder.CreateConstGEP1_32(BaseValue, Info.FieldNo); - - return LValue::MakeBitfield(V, Info, + return LValue::MakeBitfield(BaseValue, Info, Field->getType().getCVRQualifiers()|CVRQualifiers); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index ac8fa057a0..be17e59d97 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -126,8 +126,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, // objects. unsigned FieldNo = 0; // This value is unused. CGBitFieldInfo *Info = - new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize, - IvarTy->isSignedIntegerType()); + new (CGF.CGM.getContext()) CGBitFieldInfo( + LTy, FieldNo, BitOffset, BitFieldSize, IvarTy->isSignedIntegerType()); // FIXME: We need to set a very conservative alignment on this, or make sure // that the runtime is doing the right thing. diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h index fd1775ea5e..86c57d10c4 100644 --- a/lib/CodeGen/CGRecordLayout.h +++ b/lib/CodeGen/CGRecordLayout.h @@ -21,11 +21,14 @@ namespace CodeGen { class CGBitFieldInfo { public: - CGBitFieldInfo(unsigned FieldNo, unsigned Start, unsigned Size, - bool IsSigned) - : FieldNo(FieldNo), Start(Start), Size(Size), IsSigned(IsSigned) {} + CGBitFieldInfo(const llvm::Type *FieldTy, unsigned FieldNo, + unsigned Start, unsigned Size, bool IsSigned) + : FieldTy(FieldTy), FieldNo(FieldNo), + Start(Start), Size(Size), IsSigned(IsSigned) {} + const llvm::Type *FieldTy; unsigned FieldNo; + unsigned Start; unsigned Size; bool IsSigned : 1; diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 4b9ec66e17..fdd8d05926 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -180,7 +180,7 @@ void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, bool IsSigned = D->getType()->isSignedIntegerType(); LLVMBitFields.push_back(LLVMBitFieldInfo( - D, CGBitFieldInfo(FieldOffset / TypeSizeInBits, + D, CGBitFieldInfo(Ty, FieldOffset / TypeSizeInBits, FieldOffset % TypeSizeInBits, FieldSize, IsSigned))); @@ -270,6 +270,8 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) { assert(Layout.getFieldOffset(FieldNo) == 0 && "Union field offset did not start at the beginning of record!"); + const llvm::Type *FieldTy = + Types.ConvertTypeForMemRecursive(Field->getType()); if (Field->isBitField()) { uint64_t FieldSize = @@ -282,7 +284,7 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { // Add the bit field info. bool IsSigned = Field->getType()->isSignedIntegerType(); LLVMBitFields.push_back(LLVMBitFieldInfo( - *Field, CGBitFieldInfo(0, 0, FieldSize, + *Field, CGBitFieldInfo(FieldTy, 0, 0, FieldSize, IsSigned))); } else { LLVMFields.push_back(LLVMFieldInfo(*Field, 0)); @@ -290,8 +292,6 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { HasOnlyZeroSizedBitFields = false; - const llvm::Type *FieldTy = - Types.ConvertTypeForMemRecursive(Field->getType()); unsigned FieldAlign = Types.getTargetData().getABITypeAlignment(FieldTy); uint64_t FieldSize = Types.getTargetData().getTypeAllocSize(FieldTy); diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 91fb714315..e7343e2018 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -220,7 +220,7 @@ public: } // bitfield lvalue - llvm::Value *getBitFieldAddr() const { + llvm::Value *getBitFieldBaseAddr() const { assert(isBitField()); return V; } @@ -269,11 +269,17 @@ public: return R; } - static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info, + /// \brief Create a new object to represent a bit-field access. + /// + /// \param BaseValue - The base address of the structure containing the + /// bit-field. + /// \param Info - The information describing how to perform the bit-field + /// access. + static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info, unsigned CVR) { LValue R; R.LVType = BitField; - R.V = V; + R.V = BaseValue; R.BitFieldInfo = &Info; R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); return R; -- 2.40.0