From 2df2569679237b4979654a8663cd61aea67ab207 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 15 Apr 2010 05:09:32 +0000 Subject: [PATCH] IRgen: Change CGBitFieldInfo to take the AccessInfo as constructor arguments, it is now an immutable object. Also, add some checking of various invariants that should hold on the CGBitFieldInfo access. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101345 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGObjCMac.cpp | 10 ++++---- lib/CodeGen/CGRecordLayout.h | 37 +++++++++++++++++++-------- lib/CodeGen/CGRecordLayoutBuilder.cpp | 11 ++++---- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index a4fb431f8e..a6c2cc9010 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -124,13 +124,9 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, // 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. - CGBitFieldInfo *Info = - new (CGF.CGM.getContext()) CGBitFieldInfo(BitFieldSize, - IvarTy->isSignedIntegerType()); // We always construct a single, possibly unaligned, access for this case. - Info->setNumComponents(1); - CGBitFieldInfo::AccessInfo &AI = Info->getComponent(0); + CGBitFieldInfo::AccessInfo AI; AI.FieldIndex = 0; AI.FieldByteOffset = 0; AI.FieldBitStart = BitOffset; @@ -139,6 +135,10 @@ LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, AI.TargetBitOffset = 0; AI.TargetBitWidth = BitFieldSize; + CGBitFieldInfo *Info = + new (CGF.CGM.getContext()) CGBitFieldInfo(BitFieldSize, 1, &AI, + IvarTy->isSignedIntegerType()); + // 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, *Info, Quals.getCVRQualifiers()); diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h index dd60dbd593..56211b1a3e 100644 --- a/lib/CodeGen/CGRecordLayout.h +++ b/lib/CodeGen/CGRecordLayout.h @@ -94,8 +94,33 @@ private: bool IsSigned : 1; public: - CGBitFieldInfo(unsigned Size, bool IsSigned) - : Size(Size), IsSigned(IsSigned) {} + CGBitFieldInfo(unsigned Size, unsigned NumComponents, AccessInfo *_Components, + bool IsSigned) : Size(Size), NumComponents(NumComponents), + IsSigned(IsSigned) { + assert(NumComponents <= 3 && "invalid number of components!"); + for (unsigned i = 0; i != NumComponents; ++i) + Components[i] = _Components[i]; + + // Check some invariants. + unsigned AccessedSize = 0; + for (unsigned i = 0, e = getNumComponents(); i != e; ++i) { + const AccessInfo &AI = getComponent(i); + AccessedSize += AI.TargetBitWidth; + + // We shouldn't try to load 0 bits. + assert(AI.TargetBitWidth > 0); + + // We can't load more bits than we accessed. + assert(AI.FieldBitStart + AI.TargetBitWidth <= AI.AccessWidth); + + // We shouldn't put any bits outside the result size. + assert(AI.TargetBitWidth + AI.TargetBitOffset <= Size); + } + + // Check that the total number of target bits matches the total bit-field + // size. + assert(AccessedSize == Size && "Total size does not match accessed size!"); + } public: /// \brief Check whether this bit-field access is (i.e., should be sign @@ -109,19 +134,11 @@ public: /// @{ unsigned getNumComponents() const { return NumComponents; } - void setNumComponents(unsigned Value) { - assert(Value < 4 && "Invalid number of components!"); - NumComponents = Value; - } const AccessInfo &getComponent(unsigned Index) const { assert(Index < getNumComponents() && "Invalid access!"); return Components[Index]; } - AccessInfo &getComponent(unsigned Index) { - assert(Index < getNumComponents() && "Invalid access!"); - return Components[Index]; - } /// @} diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index cfdae2445e..28564eb129 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -155,18 +155,19 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, unsigned StartBit = FieldOffset % TypeSizeInBits; bool IsSigned = FD->getType()->isSignedIntegerType(); - CGBitFieldInfo BFI(FieldSize, IsSigned); // The current policy is to always access the bit-field using the source type // of the bit-field. With the C bit-field rules, this implies that we always // use either one or two accesses, and two accesses can only occur with a // packed structure when the bit-field straddles an alignment boundary. + CGBitFieldInfo::AccessInfo Components[2]; + unsigned LowBits = std::min(FieldSize, TypeSizeInBits - StartBit); bool NeedsHighAccess = LowBits != FieldSize; - BFI.setNumComponents(1 + NeedsHighAccess); + unsigned NumComponents = 1 + NeedsHighAccess; // FIXME: This access policy is probably wrong on big-endian systems. - CGBitFieldInfo::AccessInfo &LowAccess = BFI.getComponent(0); + CGBitFieldInfo::AccessInfo &LowAccess = Components[0]; LowAccess.FieldIndex = 0; LowAccess.FieldByteOffset = TypeSizeInBytes * ((FieldOffset / 8) / TypeSizeInBytes); @@ -178,7 +179,7 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, LowAccess.TargetBitWidth = LowBits; if (NeedsHighAccess) { - CGBitFieldInfo::AccessInfo &HighAccess = BFI.getComponent(1); + CGBitFieldInfo::AccessInfo &HighAccess = Components[1]; HighAccess.FieldIndex = 0; HighAccess.FieldByteOffset = LowAccess.FieldByteOffset + TypeSizeInBytes; HighAccess.FieldBitStart = 0; @@ -189,7 +190,7 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, HighAccess.TargetBitWidth = FieldSize - LowBits; } - return BFI; + return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned); } void CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, -- 2.40.0