[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