[cfe-commits] r66836 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Fariborz Jahanian
fjahanian at apple.com
Thu Mar 12 15:50:49 PDT 2009
Author: fjahanian
Date: Thu Mar 12 17:50:49 2009
New Revision: 66836
URL: http://llvm.org/viewvc/llvm-project?rev=66836&view=rev
Log:
More objc2's ivar layout bitmap.
bitmap generation for basic ivars seem to
work now. This is work in progress.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=66836&r1=66835&r2=66836&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Thu Mar 12 17:50:49 2009
@@ -424,16 +424,16 @@
/// BuildIvarLayout - Builds ivar layout bitmap for the class
/// implementation for the __strong or __weak case.
///
- llvm::Constant *BuildIvarLayout(ObjCImplementationDecl *OI,
- bool ForStrongLayout,
- const ObjCCommonTypesHelper &ObjCTypes);
+ llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
+ bool ForStrongLayout);
- void BuildAggrIvarLayout(const llvm::StructLayout *Layout,
+ void BuildAggrIvarLayout(const ObjCInterfaceDecl *OI,
+ const llvm::StructLayout *Layout,
const RecordDecl *RD,
const std::vector<FieldDecl*>& RecFields,
unsigned int BytePos, bool ForStrongLayout,
int &Index, int &SkIndex, bool &HasUnion);
-
+
/// GetIvarLayoutName - Returns a unique constant for the given
/// ivar layout bitmap.
llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
@@ -458,6 +458,11 @@
uint64_t GetIvarBaseOffset(const llvm::StructLayout *Layout,
FieldDecl *Field);
+ /// GetFieldBaseOffset - return's field byt offset.
+ uint64_t GetFieldBaseOffset(const ObjCInterfaceDecl *OI,
+ const llvm::StructLayout *Layout,
+ FieldDecl *Field);
+
/// CreateMetadataVar - Create a global variable with internal
/// linkage for use by the Objective-C runtime.
///
@@ -1834,6 +1839,17 @@
return offset;
}
+/// GetFieldBaseOffset - return's field byt offset.
+uint64_t CGObjCCommonMac::GetFieldBaseOffset(const ObjCInterfaceDecl *OI,
+ const llvm::StructLayout *Layout,
+ FieldDecl *Field) {
+ const ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
+ Field = const_cast<ObjCInterfaceDecl*>(OI)->lookupFieldDeclForIvar(
+ CGM.getContext(), Ivar);
+ uint64_t Offset = GetIvarBaseOffset(Layout, Field);
+ return Offset;
+}
+
llvm::GlobalVariable *
CGObjCCommonMac::CreateMetadataVar(const std::string &Name,
llvm::Constant *Init,
@@ -2480,7 +2496,8 @@
return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
}
-void CGObjCCommonMac::BuildAggrIvarLayout(const llvm::StructLayout *Layout,
+void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI,
+ const llvm::StructLayout *Layout,
const RecordDecl *RD,
const std::vector<FieldDecl*>& RecFields,
unsigned int BytePos, bool ForStrongLayout,
@@ -2494,8 +2511,11 @@
if (RecFields.empty())
return;
if (IsUnion)
- base = BytePos + GetIvarBaseOffset(Layout, RecFields[0]);
-
+ base = BytePos + GetFieldBaseOffset(OI, Layout, RecFields[0]);
+ unsigned WordSizeInBits = CGM.getContext().getTypeSize(
+ CGM.getContext().VoidPtrTy);
+ unsigned ByteSizeInBits = CGM.getContext().getTypeSize(
+ CGM.getContext().CharTy);
for (unsigned i = 0; i < RecFields.size(); i++) {
FieldDecl *Field = RecFields[i];
// Skip over unnamed or bitfields
@@ -2518,8 +2538,8 @@
e = RD->field_end(); i != e; ++i)
NestedRecFields[j++] = (*i);
// FIXME - Is Layout correct?
- BuildAggrIvarLayout(Layout, RD, NestedRecFields,
- BytePos + GetIvarBaseOffset(Layout, Field),
+ BuildAggrIvarLayout(OI, Layout, RD, NestedRecFields,
+ BytePos + GetFieldBaseOffset(OI, Layout, Field),
ForStrongLayout, Index, SkIndex,
HasUnion);
continue;
@@ -2545,9 +2565,9 @@
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i)
ElementRecFields[j++] = (*i);
- BuildAggrIvarLayout(Layout, RD,
+ BuildAggrIvarLayout(OI, Layout, RD,
ElementRecFields,
- BytePos + GetIvarBaseOffset(Layout, Field),
+ BytePos + GetFieldBaseOffset(OI, Layout, Field),
ForStrongLayout, Index, SkIndex,
HasUnion);
// Replicate layout information for each array element. Note that
@@ -2555,19 +2575,21 @@
uint64_t ElIx = 1;
for (int FirstIndex = Index, FirstSkIndex = SkIndex;
ElIx < ElCount; ElIx++) {
- uint64_t Size = CGM.getContext().getTypeSize(RT);
+ uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
for (int i = OldIndex+1; i <= FirstIndex; ++i)
{
- IvarsInfo[++Index].ivar_bytepos =
- IvarsInfo[i].ivar_bytepos + Size*ElIx;
- IvarsInfo[Index].ivar_size = IvarsInfo[i].ivar_size;
+ GC_IVAR gcivar;
+ gcivar.ivar_bytepos = IvarsInfo[i].ivar_bytepos + Size*ElIx;
+ gcivar.ivar_size = IvarsInfo[i].ivar_size;
+ IvarsInfo.push_back(gcivar); ++Index;
}
for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
{
- SkipIvars[++SkIndex].ivar_bytepos =
- SkipIvars[i].ivar_bytepos + Size*ElIx;
- SkipIvars[SkIndex].ivar_size = SkipIvars[i].ivar_size;
+ GC_IVAR skivar;
+ skivar.ivar_bytepos = SkipIvars[i].ivar_bytepos + Size*ElIx;
+ skivar.ivar_size = SkipIvars[i].ivar_size;
+ SkipIvars.push_back(skivar); ++SkIndex;
}
}
continue;
@@ -2581,7 +2603,7 @@
GCAttr = FQT.isObjCGCStrong() ? QualType::Strong : QualType::Weak;
break;
}
- else if (FQT->hasObjCPointerRepresentation()) {
+ else if (CGM.getContext().isObjCObjectPointerType(FQT)) {
GCAttr = QualType::Strong;
break;
}
@@ -2596,7 +2618,8 @@
|| (!ForStrongLayout && GCAttr == QualType::Weak)) {
if (IsUnion)
{
- uint64_t UnionIvarSize = CGM.getContext().getTypeSize(Field->getType());
+ uint64_t UnionIvarSize = CGM.getContext().getTypeSize(Field->getType())
+ / WordSizeInBits;
if (UnionIvarSize > MaxUnionIvarSize)
{
MaxUnionIvarSize = UnionIvarSize;
@@ -2605,10 +2628,11 @@
}
else
{
- IvarsInfo[++Index].ivar_bytepos =
- BytePos + GetIvarBaseOffset(Layout, Field);
- IvarsInfo[Index].ivar_size =
- CGM.getContext().getTypeSize(Field->getType());
+ GC_IVAR gcivar;
+ gcivar.ivar_bytepos = BytePos + GetFieldBaseOffset(OI, Layout, Field);
+ gcivar.ivar_size = CGM.getContext().getTypeSize(Field->getType()) /
+ WordSizeInBits;
+ IvarsInfo.push_back(gcivar); ++Index;
}
}
else if ((ForStrongLayout &&
@@ -2625,24 +2649,28 @@
}
else
{
- SkipIvars[++SkIndex].ivar_bytepos =
- BytePos + GetIvarBaseOffset(Layout, Field);
- SkipIvars[SkIndex].ivar_size =
- CGM.getContext().getTypeSize(Field->getType());
+ GC_IVAR skivar;
+ skivar.ivar_bytepos = BytePos + GetFieldBaseOffset(OI, Layout, Field);
+ skivar.ivar_size = CGM.getContext().getTypeSize(Field->getType()) /
+ WordSizeInBits;
+ SkipIvars.push_back(skivar); ++SkIndex;
}
}
}
if (MaxField)
{
- IvarsInfo[++Index].ivar_bytepos =
- BytePos + GetIvarBaseOffset(Layout, MaxField);
- IvarsInfo[Index].ivar_size = MaxUnionIvarSize;
+ GC_IVAR gcivar;
+ gcivar.ivar_bytepos = BytePos + GetFieldBaseOffset(OI, Layout, MaxField);
+ gcivar.ivar_size = MaxUnionIvarSize;
+ IvarsInfo.push_back(gcivar); ++Index;
}
if (MaxSkippedField)
{
- SkipIvars[++SkIndex].ivar_bytepos =
- BytePos + GetIvarBaseOffset(Layout, MaxSkippedField);
- SkipIvars[SkIndex].ivar_size = MaxSkippedUnionIvarSize;
+ GC_IVAR skivar;
+ skivar.ivar_bytepos = BytePos +
+ GetFieldBaseOffset(OI, Layout, MaxSkippedField);
+ skivar.ivar_size = MaxSkippedUnionIvarSize;
+ SkipIvars.push_back(skivar); ++SkIndex;
}
return;
}
@@ -2677,39 +2705,43 @@
/// - __weak anything
///
llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
- ObjCImplementationDecl *OMD,
- bool ForStrongLayout,
- const ObjCCommonTypesHelper &ObjCTypes) {
+ const ObjCImplementationDecl *OMD,
+ bool ForStrongLayout) {
int Index = -1;
int SkIndex = -1;
bool hasUnion = false;
int SkipScan;
unsigned int WordsToScan, WordsToSkip;
+ const llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+ if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
+ return llvm::Constant::getNullValue(PtrTy);
std::vector<FieldDecl*> RecFields;
- ObjCInterfaceDecl *OI = OMD->getClassInterface();
+ const ObjCInterfaceDecl *OI = OMD->getClassInterface();
CGM.getContext().CollectObjCIvars(OI, RecFields);
if (RecFields.empty())
- return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+ return llvm::Constant::getNullValue(PtrTy);
+ SkipIvars.clear();
+ IvarsInfo.clear();
const llvm::StructLayout *Layout = GetInterfaceDeclStructLayout(OI);
- BuildAggrIvarLayout (Layout, 0, RecFields, 0, ForStrongLayout,
+ BuildAggrIvarLayout (OI, Layout, 0, RecFields, 0, ForStrongLayout,
Index, SkIndex, hasUnion);
if (Index == -1)
- return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
+ return llvm::Constant::getNullValue(PtrTy);
// Sort on byte position in case we encounterred a union nested in
// the ivar list.
- if (hasUnion && Index > 0)
- // FIXME - Is this correct?
- qsort(&IvarsInfo[0], Index+1, sizeof(GC_IVAR), IvarBytePosCompare);
- if (hasUnion && SkIndex > 0)
+ if (hasUnion && !IvarsInfo.empty())
+ qsort(&IvarsInfo[0], Index+1, sizeof(GC_IVAR), IvarBytePosCompare);
+ if (hasUnion && !SkipIvars.empty())
qsort(&SkipIvars[0], Index+1, sizeof(GC_IVAR), IvarBytePosCompare);
// Build the string of skip/scan nibbles
SkipScan = -1;
+ SkipScanIvars.clear();
unsigned int WordSize =
- CGM.getTypes().getTargetData().getTypePaddedSize(ObjCTypes.Int8PtrTy);
+ CGM.getTypes().getTargetData().getTypePaddedSize(PtrTy);
if (IvarsInfo[0].ivar_bytepos == 0) {
WordsToSkip = 0;
WordsToScan = IvarsInfo[0].ivar_size;
@@ -2718,7 +2750,7 @@
WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
WordsToScan = IvarsInfo[0].ivar_size;
}
- for (int i=1; i <= Index; i++)
+ for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++)
{
unsigned int TailPrevGCObjC =
IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
@@ -2734,24 +2766,29 @@
continue;
// Must skip over 1 or more words. We save current skip/scan values
// and start a new pair.
- SkipScanIvars[++SkipScan].skip = WordsToSkip;
- SkipScanIvars[SkipScan].scan = WordsToScan;
+ SKIP_SCAN SkScan;
+ SkScan.skip = WordsToSkip;
+ SkScan.scan = WordsToScan;
+ SkipScanIvars.push_back(SkScan); ++SkipScan;
+
// Skip the hole.
- SkipScanIvars[++SkipScan].skip =
- (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
- SkipScanIvars[SkipScan].scan = 0;
+ SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
+ SkScan.scan = 0;
+ SkipScanIvars.push_back(SkScan); ++SkipScan;
WordsToSkip = 0;
WordsToScan = IvarsInfo[i].ivar_size;
}
}
if (WordsToScan > 0)
{
- SkipScanIvars[++SkipScan].skip = WordsToSkip;
- SkipScanIvars[SkipScan].scan = WordsToScan;
+ SKIP_SCAN SkScan;
+ SkScan.skip = WordsToSkip;
+ SkScan.scan = WordsToScan;
+ SkipScanIvars.push_back(SkScan); ++SkipScan;
}
bool BytesSkipped = false;
- if (SkIndex >= 0)
+ if (!SkipIvars.empty())
{
int LastByteSkipped =
SkipIvars[SkIndex].ivar_bytepos + SkipIvars[SkIndex].ivar_size;
@@ -2762,8 +2799,10 @@
if (BytesSkipped)
{
unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
- SkipScanIvars[++SkipScan].skip = TotalWords - (LastByteScanned/WordSize);
- SkipScanIvars[SkipScan].scan = 0;
+ SKIP_SCAN SkScan;
+ SkScan.skip = TotalWords - (LastByteScanned/WordSize);
+ SkScan.scan = 0;
+ SkipScanIvars.push_back(SkScan); ++SkipScan;
}
}
// Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
@@ -2827,9 +2866,12 @@
// if ivar_layout bitmap is all 1 bits (nothing skipped) then use NULL as
// final layout.
if (ForStrongLayout && !BytesSkipped)
- return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
-
- return llvm::ConstantArray::get(BitMap);
+ return llvm::Constant::getNullValue(PtrTy);
+ llvm::GlobalVariable * Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+ llvm::ConstantArray::get(BitMap.c_str()),
+ "__TEXT,__cstring,cstring_literals",
+ 0, true);
+ return getConstantGEP(Entry, 0, 0);
}
llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
@@ -3999,7 +4041,7 @@
else
Values[ 7] = EmitIvarList(ID);
// FIXME. weakIvarLayout is currently null.
- Values[ 8] = GetIvarLayoutName(0, ObjCTypes);
+ Values[ 8] = GetIvarLayoutName(0, ObjCTypes);
if (flags & CLS_META)
Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
else
More information about the cfe-commits
mailing list