aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-04-15 05:09:32 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-04-15 05:09:32 +0000
commit2df2569679237b4979654a8663cd61aea67ab207 (patch)
treec2a48d8f611462b90df65df8f1d1ef93c40723db
parent7fb619500404129322af972aab66c369949a2a74 (diff)
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
-rw-r--r--lib/CodeGen/CGObjCMac.cpp10
-rw-r--r--lib/CodeGen/CGRecordLayout.h37
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp11
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,