From: Chris Lattner Date: Tue, 31 Mar 2009 08:48:01 +0000 (+0000) Subject: fill in temporary smallvectors instead of vectors for performance. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f1690858344968358131f8d5690d9ee458883000;p=clang 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/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index b270ddca67..9ce61aab64 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -492,7 +492,7 @@ public: const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D); const RecordDecl *addRecordToClass(const ObjCInterfaceDecl *D); void CollectObjCIvars(const ObjCInterfaceDecl *OI, - std::vector &Fields) const; + llvm::SmallVectorImpl &Fields) const; const FieldDecl *getFieldDecl(const ObjCIvarRefExpr *MRef) { llvm::DenseMap::iterator I = ASTFieldForIvarRef.find(MRef); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 2e350c8502..25a9579258 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -598,21 +598,20 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, } void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, - std::vector &Fields) const { + llvm::SmallVectorImpl &Fields) const { const ObjCInterfaceDecl *SuperClass = OI->getSuperClass(); if (SuperClass) CollectObjCIvars(SuperClass, Fields); for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), E = OI->ivar_end(); I != E; ++I) { - ObjCIvarDecl *IVDecl = (*I); + ObjCIvarDecl *IVDecl = *I; if (!IVDecl->isInvalidDecl()) Fields.push_back(cast(IVDecl)); } // look into properties. for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(), E = OI->prop_end(); I != E; ++I) { - ObjCPropertyDecl *PDecl = (*I); - if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) + if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl()) Fields.push_back(cast(IV)); } } @@ -620,12 +619,12 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, /// addRecordToClass - produces record info. for the class for its /// ivars and all those inherited. /// -const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D) -{ +const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D) { const RecordDecl *&RD = ASTRecordForInterface[D]; if (RD) return RD; - std::vector RecFields; + + llvm::SmallVector RecFields; CollectObjCIvars(D, RecFields); RecordDecl *NewRD = RecordDecl::Create(*this, TagDecl::TK_struct, 0, D->getLocation(), @@ -633,13 +632,13 @@ const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D) /// FIXME! Can do collection of ivars and adding to the record while /// doing it. for (unsigned int i = 0; i != RecFields.size(); i++) { - FieldDecl *Field = FieldDecl::Create(*this, NewRD, - RecFields[i]->getLocation(), - RecFields[i]->getIdentifier(), - RecFields[i]->getType(), - RecFields[i]->getBitWidth(), false); - NewRD->addDecl(Field); + NewRD->addDecl(FieldDecl::Create(*this, NewRD, + RecFields[i]->getLocation(), + RecFields[i]->getIdentifier(), + RecFields[i]->getType(), + RecFields[i]->getBitWidth(), false)); } + NewRD->completeDefinition(*this); RD = NewRD; return RD; @@ -2401,9 +2400,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const IdentifierInfo *II = OI->getIdentifier(); S += II->getName(); S += '='; - std::vector RecFields; + llvm::SmallVector RecFields; CollectObjCIvars(OI, RecFields); - for (unsigned int i = 0; i != RecFields.size(); i++) { + for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { if (RecFields[i]->isBitField()) getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true, RecFields[i]); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 8bbd1b4caf..05d81eaf0f 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -430,7 +430,7 @@ protected: void BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, const llvm::StructLayout *Layout, const RecordDecl *RD, - const std::vector& RecFields, + const llvm::SmallVectorImpl &RecFields, unsigned int BytePos, bool ForStrongLayout, int &Index, int &SkIndex, bool &HasUnion); @@ -2530,7 +2530,7 @@ llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, const llvm::StructLayout *Layout, const RecordDecl *RD, - const std::vector& RecFields, + const llvm::SmallVectorImpl &RecFields, unsigned int BytePos, bool ForStrongLayout, int &Index, int &SkIndex, bool &HasUnion) { bool IsUnion = (RD && RD->isUnion()); @@ -2538,23 +2538,23 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, 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 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 NestedRecFields; if (FQT->isUnionType()) HasUnion = true; else @@ -2564,18 +2564,17 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, 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(Array); assert(CArray && "only array with know element size is supported"); @@ -2593,20 +2592,19 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, int OldIndex = Index; int OldSkIndex = SkIndex; - std::vector 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 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, 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 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, break; } } while (true); + if ((ForStrongLayout && GCAttr == QualType::Strong) || (!ForStrongLayout && GCAttr == QualType::Weak)) { if (IsUnion) @@ -2694,26 +2692,24 @@ void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCInterfaceDecl *OI, } } } - 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 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout( if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) return llvm::Constant::getNullValue(PtrTy); - std::vector RecFields; + llvm::SmallVector 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);