fill in temporary smallvectors instead of vectors for performance.
Fix BuildAggrIvarLayout to not access vectors out of range.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68101 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 8bbd1b4..05d81ea 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -430,7 +430,7 @@
   void BuildAggrIvarLayout(const ObjCInterfaceDecl *OI,
                            const llvm::StructLayout *Layout,
                            const RecordDecl *RD,
-                           const std::vector<FieldDecl*>& RecFields,
+                           const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
                            unsigned int BytePos, bool ForStrongLayout,
                            int &Index, int &SkIndex, bool &HasUnion);
 
@@ -2530,7 +2530,7 @@
 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI,
                               const llvm::StructLayout *Layout,
                               const RecordDecl *RD,
-                              const std::vector<FieldDecl*>& RecFields,
+                             const llvm::SmallVectorImpl<FieldDecl*> &RecFields,
                               unsigned int BytePos, bool ForStrongLayout,
                               int &Index, int &SkIndex, bool &HasUnion) {
   bool IsUnion = (RD && RD->isUnion());
@@ -2538,23 +2538,23 @@
   uint64_t MaxSkippedUnionIvarSize = 0;
   FieldDecl *MaxField = 0;
   FieldDecl *MaxSkippedField = 0;
-  unsigned int base = 0;
+  unsigned base = 0;
   if (RecFields.empty())
     return;
   if (IsUnion)
     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++) {
+  unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0);
+  unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth();
+
+  llvm::SmallVector<FieldDecl*, 16> TmpRecFields;
+
+  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
     FieldDecl *Field = RecFields[i];
     // Skip over unnamed or bitfields
     if (!Field->getIdentifier() || Field->isBitField())
       continue;
     QualType FQT = Field->getType();
     if (FQT->isRecordType() || FQT->isUnionType()) {
-      std::vector<FieldDecl*> NestedRecFields;
       if (FQT->isUnionType())
         HasUnion = true;
       else
@@ -2564,18 +2564,17 @@
       const RecordType *RT = FQT->getAsRecordType();
       const RecordDecl *RD = RT->getDecl();
       // FIXME - Find a more efficiant way of passing records down.
-      unsigned j = 0;
-      for (RecordDecl::field_iterator i = RD->field_begin(),
-           e = RD->field_end(); i != e; ++i)
-        NestedRecFields[j++] = (*i);
+      TmpRecFields.append(RD->field_begin(), RD->field_end());
       // FIXME - Is Layout correct?
-      BuildAggrIvarLayout(OI, Layout, RD, NestedRecFields,
+      BuildAggrIvarLayout(OI, Layout, RD, TmpRecFields,
                           BytePos + GetFieldBaseOffset(OI, Layout, Field),
                           ForStrongLayout, Index, SkIndex,
                           HasUnion);
+      TmpRecFields.clear();
       continue;
     }
-    else if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
+    
+    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
       const ConstantArrayType *CArray = 
                                  dyn_cast_or_null<ConstantArrayType>(Array);
       assert(CArray && "only array with know element size is supported");
@@ -2593,20 +2592,19 @@
         int OldIndex = Index;
         int OldSkIndex = SkIndex;
         
-        std::vector<FieldDecl*> ElementRecFields;
         // FIXME - Use a common routine with the above!
         const RecordType *RT = FQT->getAsRecordType();
         const RecordDecl *RD = RT->getDecl();
         // FIXME - Find a more efficiant way of passing records down.
-        unsigned j = 0;
-        for (RecordDecl::field_iterator i = RD->field_begin(),
-             e = RD->field_end(); i != e; ++i)
-          ElementRecFields[j++] = (*i);
+        TmpRecFields.append(RD->field_begin(), RD->field_end());
+        
         BuildAggrIvarLayout(OI, Layout, RD,
-                            ElementRecFields,
+                            TmpRecFields,
                             BytePos + GetFieldBaseOffset(OI, Layout, Field),
                             ForStrongLayout, Index, SkIndex,
                             HasUnion);
+        TmpRecFields.clear();
+
         // Replicate layout information for each array element. Note that
         // one element is already done.
         uint64_t ElIx = 1;
@@ -2621,8 +2619,7 @@
             IvarsInfo.push_back(gcivar); ++Index;
           }
           
-          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
-          {
+          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) {
             GC_IVAR skivar;
             skivar.ivar_bytepos = SkipIvars[i].ivar_bytepos + Size*ElIx;
             skivar.ivar_size = SkipIvars[i].ivar_size;
@@ -2651,6 +2648,7 @@
         break;
       }
     } while (true);
+    
     if ((ForStrongLayout && GCAttr == QualType::Strong)
         || (!ForStrongLayout && GCAttr == QualType::Weak)) {
       if (IsUnion)
@@ -2694,26 +2692,24 @@
       }
     }
   }
-  if (MaxField)
-  {
+  if (MaxField) {
     GC_IVAR gcivar;
     gcivar.ivar_bytepos = BytePos + GetFieldBaseOffset(OI, Layout, MaxField);
     gcivar.ivar_size = MaxUnionIvarSize;
     IvarsInfo.push_back(gcivar); ++Index;
   }
-  if (MaxSkippedField)
-  {
+  
+  if (MaxSkippedField) {
     GC_IVAR skivar;
     skivar.ivar_bytepos = BytePos + 
                           GetFieldBaseOffset(OI, Layout, MaxSkippedField);
     skivar.ivar_size = MaxSkippedUnionIvarSize;
     SkipIvars.push_back(skivar); ++SkIndex;
   }
-  return;
 }
 
 static int
-IvarBytePosCompare (const void *a, const void *b)
+IvarBytePosCompare(const void *a, const void *b)
 {
   unsigned int sa = ((CGObjCCommonMac::GC_IVAR *)a)->ivar_bytepos;
   unsigned int sb = ((CGObjCCommonMac::GC_IVAR *)b)->ivar_bytepos;
@@ -2753,17 +2749,18 @@
   if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
     return llvm::Constant::getNullValue(PtrTy);
   
-  std::vector<FieldDecl*> RecFields;
+  llvm::SmallVector<FieldDecl*, 32> RecFields;
   const ObjCInterfaceDecl *OI = OMD->getClassInterface();
   CGM.getContext().CollectObjCIvars(OI, RecFields);
   if (RecFields.empty())
     return llvm::Constant::getNullValue(PtrTy);
+  
   SkipIvars.clear(); 
   IvarsInfo.clear();
   
   const llvm::StructLayout *Layout = GetInterfaceDeclStructLayout(OI);
-  BuildAggrIvarLayout (OI, Layout, 0, RecFields, 0, ForStrongLayout, 
-                       Index, SkIndex, hasUnion);
+  BuildAggrIvarLayout(OI, Layout, 0, RecFields, 0, ForStrongLayout, 
+                      Index, SkIndex, hasUnion);
   if (Index == -1)
     return llvm::Constant::getNullValue(PtrTy);