diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-20 23:58:33 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-20 23:58:33 +0000 |
commit | 6d00c993f517196e916b5b5585a60e362dfef6a9 (patch) | |
tree | dfb463e6fec877548de11ba743264eaf9e55fa6c /clang/lib/Sema/SemaInit.cpp | |
parent | a792bad8248a8c7f5f91a713cc61b87d18b771e0 (diff) | |
download | bcm5719-llvm-6d00c993f517196e916b5b5585a60e362dfef6a9.tar.gz bcm5719-llvm-6d00c993f517196e916b5b5585a60e362dfef6a9.zip |
When building the structured initializer list, pre-allocate storage in
its vectors based on the subobject type we're initializing and the
(unstructured) initializer list. This eliminates some malloc thrashing
when parsing initializers (from 117 vector reallocations down to 0
when parsing Cocoa.h). We can't always pre-allocate the right amount
of storage, since designated initializers can cause us to initialize
in non-predictable patterns.
llvm-svn: 67421
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 8a5e2c87d34..33641329108 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1450,6 +1450,32 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, Result->setType(CurrentObjectType); + // Pre-allocate storage for the structured initializer list. + unsigned NumElements = 0; + if (const ArrayType *AType + = SemaRef.Context.getAsArrayType(CurrentObjectType)) { + if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) { + NumElements = CAType->getSize().getZExtValue(); + // Simple heuristic so that we don't allocate a very large + // initializer with many empty entries at the end. + if (IList && NumElements > IList->getNumInits()) + NumElements = 0; + } + } else if (const VectorType *VType = CurrentObjectType->getAsVectorType()) + NumElements = VType->getNumElements(); + else if (const RecordType *RType = CurrentObjectType->getAsRecordType()) { + RecordDecl *RDecl = RType->getDecl(); + if (RDecl->isUnion()) + NumElements = 1; + else + NumElements = std::distance(RDecl->field_begin(), RDecl->field_end()); + } + + if (IList && NumElements < IList->getNumInits()) + NumElements = IList->getNumInits(); + + Result->reserveInits(NumElements); + // Link this new initializer list into the structured initializer // lists. if (StructuredList) |