[cfe-commits] r67421 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/Sema/SemaInit.cpp

Douglas Gregor dgregor at apple.com
Fri Mar 20 16:58:37 PDT 2009


Author: dgregor
Date: Fri Mar 20 18:58:33 2009
New Revision: 67421

URL: http://llvm.org/viewvc/llvm-project?rev=67421&view=rev
Log:
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.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=67421&r1=67420&r2=67421&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Mar 20 18:58:33 2009
@@ -1757,6 +1757,9 @@
     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

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=67421&r1=67420&r2=67421&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Mar 20 18:58:33 2009
@@ -338,6 +338,11 @@
   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)

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=67421&r1=67420&r2=67421&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Mar 20 18:58:33 2009
@@ -1450,6 +1450,32 @@
 
   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)





More information about the cfe-commits mailing list