зеркало из https://github.com/microsoft/clang-1.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67421 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
9f9768c1ee
Коммит
fa2192042f
|
@ -1757,6 +1757,9 @@ public:
|
|||
InitExprs[Init] = expr;
|
||||
}
|
||||
|
||||
/// \brief Reserve space for some number of initializers.
|
||||
void reserveInits(unsigned NumInits);
|
||||
|
||||
/// @brief Specify the number of initializers
|
||||
///
|
||||
/// If there are more than @p NumInits initializers, the remaining
|
||||
|
|
|
@ -338,6 +338,11 @@ InitListExpr::InitListExpr(SourceLocation lbraceloc,
|
|||
InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
|
||||
}
|
||||
|
||||
void InitListExpr::reserveInits(unsigned NumInits) {
|
||||
if (NumInits > InitExprs.size())
|
||||
InitExprs.reserve(NumInits);
|
||||
}
|
||||
|
||||
void InitListExpr::resizeInits(ASTContext &Context, unsigned NumInits) {
|
||||
for (unsigned Idx = NumInits, LastIdx = InitExprs.size();
|
||||
Idx < LastIdx; ++Idx)
|
||||
|
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче