From: Daniel Dunbar Date: Mon, 5 Apr 2010 21:36:35 +0000 (+0000) Subject: IRgen: Move BitField LValues to just hold a reference to the CGBitFieldInfo. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0fe5bc0e46038dc79cdd27fcf0c77ad4789fdff;p=clang IRgen: Move BitField LValues to just hold a reference to the CGBitFieldInfo. - Unfortunately, this requires some horrible code in CGObjCMac which always allocats a CGBitFieldInfo because we don't currently build a proper layout for Objective-C classes. It needs to be cleaned up, but I don't want the bit-field cleanups to be blocked on that. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100474 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index f1115531e9..fcade1ba47 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -345,7 +345,7 @@ EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } // Store the updated result through the lvalue. - if (LV.isBitfield()) + if (LV.isBitField()) EmitStoreThroughBitfieldLValue(RValue::get(NextVal), LV, ValTy, &NextVal); else EmitStoreThroughLValue(RValue::get(NextVal), LV, ValTy); @@ -429,7 +429,7 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E, LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) { LValue LV = EmitLValue(E); - if (!isa(E) && !LV.isBitfield() && LV.isSimple()) + if (!isa(E) && !LV.isBitField() && LV.isSimple()) EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8); return LV; } @@ -593,7 +593,7 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { if (LV.isExtVectorElt()) return EmitLoadOfExtVectorElementLValue(LV, ExprType); - if (LV.isBitfield()) + if (LV.isBitField()) return EmitLoadOfBitfieldLValue(LV, ExprType); if (LV.isPropertyRef()) @@ -605,9 +605,9 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType) { - unsigned StartBit = LV.getBitfieldStartBit(); - unsigned BitfieldSize = LV.getBitfieldSize(); - llvm::Value *Ptr = LV.getBitfieldAddr(); + unsigned StartBit = LV.getBitFieldInfo().Start; + unsigned BitfieldSize = LV.getBitFieldInfo().Size; + llvm::Value *Ptr = LV.getBitFieldAddr(); const llvm::Type *EltTy = cast(Ptr->getType())->getElementType(); @@ -650,7 +650,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, } // Sign extend if necessary. - if (LV.isBitfieldSigned()) { + if (LV.isBitFieldSigned()) { llvm::Value *ExtraBits = llvm::ConstantInt::get(EltTy, EltTySize - BitfieldSize); Val = Builder.CreateAShr(Builder.CreateShl(Val, ExtraBits), @@ -733,7 +733,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, if (Dst.isExtVectorElt()) return EmitStoreThroughExtVectorComponentLValue(Src, Dst, Ty); - if (Dst.isBitfield()) + if (Dst.isBitField()) return EmitStoreThroughBitfieldLValue(Src, Dst, Ty); if (Dst.isPropertyRef()) @@ -781,9 +781,9 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty, llvm::Value **Result) { - unsigned StartBit = Dst.getBitfieldStartBit(); - unsigned BitfieldSize = Dst.getBitfieldSize(); - llvm::Value *Ptr = Dst.getBitfieldAddr(); + unsigned StartBit = Dst.getBitFieldInfo().Start; + unsigned BitfieldSize = Dst.getBitFieldInfo().Size; + llvm::Value *Ptr = Dst.getBitFieldAddr(); const llvm::Type *EltTy = cast(Ptr->getType())->getElementType(); @@ -805,7 +805,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, "bf.reload.val"); // Sign extend if necessary. - if (Dst.isBitfieldSigned()) { + if (Dst.isBitFieldSigned()) { unsigned SrcTySize = CGM.getTargetData().getTypeSizeInBits(SrcTy); llvm::Value *ExtraBits = llvm::ConstantInt::get(SrcTy, SrcTySize - BitfieldSize); @@ -1488,9 +1488,8 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue, llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 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); + return LValue::MakeBitfield(V, Info, Field->getType()->isSignedIntegerType(), + Field->getType().getCVRQualifiers()|CVRQualifiers); } LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue, diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 42bf68ed52..d1c0f8dc3d 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1140,7 +1140,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, // specially because the result is altered by the store, i.e., [C99 6.5.16p1] // 'An assignment expression has the value of the left operand after the // assignment...'. - if (LHSLV.isBitfield()) { + if (LHSLV.isBitField()) { if (!LHSLV.isVolatileQualified()) { CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, LHSTy, &Result); @@ -1575,7 +1575,7 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { // because the result is altered by the store, i.e., [C99 6.5.16p1] // 'An assignment expression has the value of the left operand after // the assignment...'. - if (LHS.isBitfield()) { + if (LHS.isBitField()) { if (!LHS.isVolatileQualified()) { CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, E->getType(), &RHS); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index e4df872d35..467ad43bb2 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -118,10 +118,19 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, uint64_t BitFieldSize = Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); + // Allocate a new CGBitFieldInfo object to describe this access. + // + // FIXME: This is incredibly wasteful, these should be uniqued or part of some + // layout object. However, this is blocked on other cleanups to the + // Objective-C code, so for now we just live with allocating a bunch of these + // objects. + unsigned FieldNo = 0; // This value is unused. + CGBitFieldInfo *Info = + new (CGF.CGM.getContext()) CGBitFieldInfo(FieldNo, BitOffset, BitFieldSize); + // FIXME: We need to set a very conservative alignment on this, or make sure // that the runtime is doing the right thing. - return LValue::MakeBitfield(V, BitOffset, BitFieldSize, - IvarTy->isSignedIntegerType(), + return LValue::MakeBitfield(V, *Info, IvarTy->isSignedIntegerType(), Quals.getCVRQualifiers()); } diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index b781940ffa..e478394fb1 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -61,12 +61,11 @@ namespace CodeGen { /// Implements runtime-specific code generation functions. class CGObjCRuntime { -public: +protected: // Utility functions for unified ivar access. These need to // eventually be folded into other places (the structure layout // code). -protected: /// Compute an offset to the given ivar, suitable for passing to /// EmitValueForIvarAtOffset. Note that the correct handling of /// bit-fields is carefully coordinated by these two, use caution! diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index fa77471bce..465ea76913 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -27,6 +27,7 @@ namespace clang { class ObjCImplicitSetterGetterRefExpr; namespace CodeGen { + class CGBitFieldInfo; /// RValue - This trivial value class is used to represent the result of an /// expression that is evaluated. It can be one of three things: either a @@ -128,14 +129,11 @@ class LValue { llvm::Constant *VectorElts; // BitField start bit and size - struct { - unsigned short StartBit; - unsigned short Size; - bool IsSigned; - } BitfieldData; + const CGBitFieldInfo *BitFieldInfo; // Obj-C property reference expression const ObjCPropertyRefExpr *PropertyRefExpr; + // ObjC 'implicit' property reference expression const ObjCImplicitSetterGetterRefExpr *KVCRefExpr; }; @@ -156,6 +154,9 @@ class LValue { // Lvalue is a global reference of an objective-c object bool GlobalObjCRef : 1; + /// Is the bit-field value signed. + bool BitFieldIsSigned : 1; + Expr *BaseIvarExp; private: void SetQualifiers(Qualifiers Quals) { @@ -170,7 +171,7 @@ private: public: bool isSimple() const { return LVType == Simple; } bool isVectorElt() const { return LVType == VectorElt; } - bool isBitfield() const { return LVType == BitField; } + bool isBitField() const { return LVType == BitField; } bool isExtVectorElt() const { return LVType == ExtVectorElt; } bool isPropertyRef() const { return LVType == PropertyRef; } bool isKVCRef() const { return LVType == KVCRef; } @@ -209,29 +210,32 @@ public: // simple lvalue llvm::Value *getAddress() const { assert(isSimple()); return V; } + // vector elt lvalue llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; } llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; } + // extended vector elements. llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; } llvm::Constant *getExtVectorElts() const { assert(isExtVectorElt()); return VectorElts; } + // bitfield lvalue - llvm::Value *getBitfieldAddr() const { assert(isBitfield()); return V; } - unsigned short getBitfieldStartBit() const { - assert(isBitfield()); - return BitfieldData.StartBit; + llvm::Value *getBitFieldAddr() const { + assert(isBitField()); + return V; } - unsigned short getBitfieldSize() const { - assert(isBitfield()); - return BitfieldData.Size; + const CGBitFieldInfo &getBitFieldInfo() const { + assert(isBitField()); + return *BitFieldInfo; } - bool isBitfieldSigned() const { - assert(isBitfield()); - return BitfieldData.IsSigned; + bool isBitFieldSigned() const { + assert(isBitField()); + return BitFieldIsSigned; } + // property ref lvalue const ObjCPropertyRefExpr *getPropertyRefExpr() const { assert(isPropertyRef()); @@ -272,15 +276,13 @@ public: return R; } - static LValue MakeBitfield(llvm::Value *V, unsigned short StartBit, - unsigned short Size, bool IsSigned, - unsigned CVR) { + static LValue MakeBitfield(llvm::Value *V, const CGBitFieldInfo &Info, + bool IsSigned, unsigned CVR) { LValue R; R.LVType = BitField; R.V = V; - R.BitfieldData.StartBit = StartBit; - R.BitfieldData.Size = Size; - R.BitfieldData.IsSigned = IsSigned; + R.BitFieldInfo = &Info; + R.BitFieldIsSigned = IsSigned; R.SetQualifiers(Qualifiers::fromCVRMask(CVR)); return R; }