summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp37
-rw-r--r--clang/lib/CodeGen/CGObjCRuntime.cpp5
-rw-r--r--clang/lib/CodeGen/CGRecordLayout.h7
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp2
-rw-r--r--clang/lib/CodeGen/CGValue.h6
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
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);
OpenPOWER on IntegriCloud