aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGRecordLayoutBuilder.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-04-13 20:58:55 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-04-13 20:58:55 +0000
commitab970f90ce31a53fe7e6375a37536bf0832fd922 (patch)
treedca72794ebe2bac936e3a1516ad07fc54112d899 /lib/CodeGen/CGRecordLayoutBuilder.cpp
parent4895a8ca41352b9ce572cd64ffa93208898e7546 (diff)
IRgen: Enhance CGBitFieldInfo with enough information to fully describe the "policy" with which a bit-field should be accessed.
- For now, these policies are computed to match the current IRgen strategy, although the new information isn't being used yet (except in -fdump-record-layouts). - Design comments appreciated. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101178 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp70
1 files changed, 65 insertions, 5 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index ac6aae8bdc..45acb03450 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -150,12 +150,45 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types,
uint64_t FieldOffset,
uint64_t FieldSize) {
const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType());
- uint64_t TypeSizeInBits = Types.getTargetData().getTypeAllocSize(Ty) * 8;
+ uint64_t TypeSizeInBytes = Types.getTargetData().getTypeAllocSize(Ty);
+ uint64_t TypeSizeInBits = TypeSizeInBytes * 8;
bool IsSigned = FD->getType()->isSignedIntegerType();
CGBitFieldInfo BFI(Ty, FieldOffset / TypeSizeInBits,
FieldOffset % TypeSizeInBits, 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.
+ unsigned LowBits = std::min(FieldSize, TypeSizeInBits - BFI.Start);
+ bool NeedsHighAccess = LowBits != FieldSize;
+ BFI.setNumComponents(1 + NeedsHighAccess);
+
+ // FIXME: This access policy is probably wrong on big-endian systems.
+ CGBitFieldInfo::AccessInfo &LowAccess = BFI.getComponent(0);
+ LowAccess.FieldIndex = 0;
+ LowAccess.FieldByteOffset =
+ TypeSizeInBytes * ((FieldOffset / 8) / TypeSizeInBytes);
+ LowAccess.FieldBitStart = BFI.Start;
+ LowAccess.AccessWidth = TypeSizeInBits;
+ // FIXME: This might be wrong!
+ LowAccess.AccessAlignment = 0;
+ LowAccess.TargetBitOffset = 0;
+ LowAccess.TargetBitWidth = LowBits;
+
+ if (NeedsHighAccess) {
+ CGBitFieldInfo::AccessInfo &HighAccess = BFI.getComponent(1);
+ HighAccess.FieldIndex = 0;
+ HighAccess.FieldByteOffset = LowAccess.FieldByteOffset + TypeSizeInBytes;
+ HighAccess.FieldBitStart = 0;
+ HighAccess.AccessWidth = TypeSizeInBits;
+ // FIXME: This might be wrong!
+ HighAccess.AccessAlignment = 0;
+ HighAccess.TargetBitOffset = LowBits;
+ HighAccess.TargetBitWidth = FieldSize - LowBits;
+ }
+
return BFI;
}
@@ -500,8 +533,13 @@ CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i)
RL->BitFields.insert(Builder.LLVMBitFields[i]);
- if (getContext().getLangOptions().DumpRecordLayouts)
+ if (getContext().getLangOptions().DumpRecordLayouts) {
+ llvm::errs() << "\n*** Dumping Record Layout\n";
+ llvm::errs() << "Record: ";
+ D->dump();
+ llvm::errs() << "\nLayout: ";
RL->dump();
+ }
return RL;
}
@@ -514,7 +552,7 @@ void CGRecordLayout::print(llvm::raw_ostream &OS) const {
for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator
it = BitFields.begin(), ie = BitFields.end();
it != ie; ++it) {
- OS << " ";
+ OS.indent(4);
it->second.print(OS);
OS << "\n";
}
@@ -531,8 +569,30 @@ void CGBitFieldInfo::print(llvm::raw_ostream &OS) const {
OS << " FieldNo:" << FieldNo;
OS << " Start:" << Start;
OS << " Size:" << Size;
- OS << " IsSigned:" << IsSigned;
- OS << ">";
+ OS << " IsSigned:" << IsSigned << "\n";
+
+ OS.indent(4 + strlen("<CGBitFieldInfo"));
+ OS << " NumComponents:" << getNumComponents();
+ OS << " Components: [";
+ if (getNumComponents()) {
+ OS << "\n";
+ for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
+ const AccessInfo &AI = getComponent(i);
+ OS.indent(8);
+ OS << "<AccessInfo"
+ << " FieldIndex:" << AI.FieldIndex
+ << " FieldByteOffset:" << AI.FieldByteOffset
+ << " FieldBitStart:" << AI.FieldBitStart
+ << " AccessWidth:" << AI.AccessWidth << "\n";
+ OS.indent(8 + strlen("<AccessInfo"));
+ OS << " AccessAlignment:" << AI.AccessAlignment
+ << " TargetBitOffset:" << AI.TargetBitOffset
+ << " TargetBitWidth:" << AI.TargetBitWidth
+ << ">\n";
+ }
+ OS.indent(4);
+ }
+ OS << "]>";
}
void CGBitFieldInfo::dump() const {