forked from OSchip/llvm-project
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. llvm-svn: 100474
This commit is contained in:
parent
cf04b02d1d
commit
dc406b8e92
|
@ -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<DeclRefExpr>(E) && !LV.isBitfield() && LV.isSimple())
|
||||
if (!isa<DeclRefExpr>(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<llvm::PointerType>(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<llvm::PointerType>(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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue