diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCRuntime.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGRecordLayout.h | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGValue.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 3 |
6 files changed, 28 insertions, 32 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index c8563d6044e..cb446dfeb4a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1047,6 +1047,9 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { llvm::Value *Res = 0; for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) { const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i); + CharUnits AccessAlignment = AI.AccessAlignment; + if (!LV.getAlignment().isZero()) + AccessAlignment = std::min(AccessAlignment, LV.getAlignment()); // Get the field pointer. llvm::Value *Ptr = LV.getBitFieldBaseAddr(); @@ -1070,8 +1073,7 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) { // Perform the load. llvm::LoadInst *Load = Builder.CreateLoad(Ptr, LV.isVolatileQualified()); - if (!AI.AccessAlignment.isZero()) - Load->setAlignment(AI.AccessAlignment.getQuantity()); + Load->setAlignment(AccessAlignment.getQuantity()); // Shift out unused low bits and mask out unused high bits. llvm::Value *Val = Load; @@ -1270,6 +1272,9 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, // Iterate over the components, writing each piece to memory. for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) { const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i); + CharUnits AccessAlignment = AI.AccessAlignment; + if (!Dst.getAlignment().isZero()) + AccessAlignment = std::min(AccessAlignment, Dst.getAlignment()); // Get the field pointer. llvm::Value *Ptr = Dst.getBitFieldBaseAddr(); @@ -1316,8 +1321,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, // If necessary, load and OR in bits that are outside of the bit-field. if (AI.TargetBitWidth != AI.AccessWidth) { llvm::LoadInst *Load = Builder.CreateLoad(Ptr, Dst.isVolatileQualified()); - if (!AI.AccessAlignment.isZero()) - Load->setAlignment(AI.AccessAlignment.getQuantity()); + Load->setAlignment(AccessAlignment.getQuantity()); // Compute the mask for zeroing the bits that are part of the bit-field. llvm::APInt InvMask = @@ -1331,8 +1335,7 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, // Write the value. llvm::StoreInst *Store = Builder.CreateStore(Val, Ptr, Dst.isVolatileQualified()); - if (!AI.AccessAlignment.isZero()) - Store->setAlignment(AI.AccessAlignment.getQuantity()); + Store->setAlignment(AccessAlignment.getQuantity()); } } @@ -2084,16 +2087,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) { llvm_unreachable("Unhandled member declaration!"); } -LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue, - const FieldDecl *Field, - unsigned CVRQualifiers) { - const CGRecordLayout &RL = - CGM.getTypes().getCGRecordLayout(Field->getParent()); - const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); - return LValue::MakeBitfield(BaseValue, Info, - Field->getType().withCVRQualifiers(CVRQualifiers)); -} - /// EmitLValueForAnonRecordField - Given that the field is a member of /// an anonymous struct or union buried inside a record, and given /// that the base value is a pointer to the enclosing record, derive @@ -2118,9 +2111,15 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue, LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field) { - if (field->isBitField()) - return EmitLValueForBitfield(base.getAddress(), field, - base.getVRQualifiers()); + if (field->isBitField()) { + const CGRecordLayout &RL = + CGM.getTypes().getCGRecordLayout(field->getParent()); + const CGBitFieldInfo &Info = RL.getBitFieldInfo(field); + QualType fieldType = + field->getType().withCVRQualifiers(base.getVRQualifiers()); + return LValue::MakeBitfield(base.getAddress(), Info, fieldType, + base.getAlignment()); + } const RecordDecl *rec = field->getParent(); QualType type = field->getType(); diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index 0f5cbc19d6b..7cf0ed236f2 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -120,6 +120,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, uint64_t ContainingTypeAlign = CGF.CGM.getContext().getTargetInfo().getCharAlign(); uint64_t ContainingTypeSize = TypeSizeInBits - (FieldBitOffset - BitOffset); uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext()); + CharUnits ContainingTypeAlignCharUnits = + CGF.CGM.getContext().toCharUnitsFromBits(ContainingTypeAlign); // Allocate a new CGBitFieldInfo object to describe this access. // @@ -132,7 +134,8 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, ContainingTypeSize, ContainingTypeAlign)); return LValue::MakeBitfield(V, *Info, - IvarTy.withCVRQualifiers(CVRQualifiers)); + IvarTy.withCVRQualifiers(CVRQualifiers), + ContainingTypeAlignCharUnits); } namespace { diff --git a/clang/lib/CodeGen/CGRecordLayout.h b/clang/lib/CodeGen/CGRecordLayout.h index 25a0a508f18..94c822f49f1 100644 --- a/clang/lib/CodeGen/CGRecordLayout.h +++ b/clang/lib/CodeGen/CGRecordLayout.h @@ -64,12 +64,7 @@ public: /// Bit width of the memory access to perform. unsigned AccessWidth; - /// The alignment of the memory access, or 0 if the default alignment should - /// be used. - // - // FIXME: Remove use of 0 to encode default, instead have IRgen do the right - // thing when it generates the code, if avoiding align directives is - // desired. + /// The alignment of the memory access, assuming the parent is aligned. CharUnits AccessAlignment; /// Offset for the target value. diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index 382cbfd10de..d642ef8533c 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -235,6 +235,8 @@ CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, uint64_t FieldSize, uint64_t ContainingTypeSizeInBits, unsigned ContainingTypeAlign) { + assert(ContainingTypeAlign && "Expected alignment to be specified"); + llvm::Type *Ty = Types.ConvertTypeForMem(FD->getType()); CharUnits TypeSizeInBytes = CharUnits::fromQuantity(Types.getTargetData().getTypeAllocSize(Ty)); diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index ac704e7dca4..dd9208f9138 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -153,7 +153,7 @@ class LValue { private: void Initialize(QualType Type, Qualifiers Quals, - CharUnits Alignment = CharUnits(), + CharUnits Alignment, llvm::MDNode *TBAAInfo = 0) { this->Type = Type; this->Quals = Quals; @@ -295,12 +295,12 @@ public: /// access. static LValue MakeBitfield(llvm::Value *BaseValue, const CGBitFieldInfo &Info, - QualType type) { + QualType type, CharUnits Alignment) { LValue R; R.LVType = BitField; R.V = BaseValue; R.BitFieldInfo = &Info; - R.Initialize(type, type.getQualifiers()); + R.Initialize(type, type.getQualifiers(), Alignment); return R; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index b26d174180a..fd93fbbdd20 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2166,9 +2166,6 @@ public: llvm::Value* Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers); - LValue EmitLValueForBitfield(llvm::Value* Base, const FieldDecl* Field, - unsigned CVRQualifiers); - LValue EmitCXXConstructLValue(const CXXConstructExpr *E); LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E); LValue EmitLambdaLValue(const LambdaExpr *E); |