@@ -876,11 +876,96 @@ void CIRGenFunction::emitNewArrayInitializer(
876876 unsigned InitListElements = 0 ;
877877
878878 const Expr *Init = E->getInitializer ();
879+ QualType::DestructionKind DtorKind = ElementType.isDestructedType ();
879880 CleanupDeactivationScope deactivation (*this );
880881
882+ CharUnits ElementSize = getContext ().getTypeSizeInChars (ElementType);
883+ CharUnits ElementAlign =
884+ BeginPtr.getAlignment ().alignmentOfArrayElement (ElementSize);
885+
886+ // Attempt to perform zero-initialization using memset.
887+ auto TryMemsetInitialization = [&]() -> bool {
888+ auto Loc = NumElements.getLoc ();
889+
890+ // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
891+ // we can initialize with a memset to -1.
892+ if (!CGM.getTypes ().isZeroInitializable (ElementType))
893+ return false ;
894+
895+ // Optimization: since zero initialization will just set the memory
896+ // to all zeroes, generate a single memset to do it in one shot.
897+
898+ // Subtract out the size of any elements we've already initialized.
899+ auto RemainingSize = AllocSizeWithoutCookie;
900+ if (InitListElements) {
901+ llvm_unreachable (" NYI" );
902+ }
903+
904+ // Create the memset.
905+ auto CastOp =
906+ builder.createPtrBitcast (CurPtr.getPointer (), builder.getVoidTy ());
907+ builder.createMemSet (Loc, CastOp, builder.getUInt8 (0 , Loc), RemainingSize);
908+ return true ;
909+ };
910+
881911 const InitListExpr *ILE = dyn_cast<InitListExpr>(Init);
882- if (ILE) {
883- llvm_unreachable (" NYI" );
912+ const CXXParenListInitExpr *CPLIE = nullptr ;
913+ const StringLiteral *SL = nullptr ;
914+ const ObjCEncodeExpr *OCEE = nullptr ;
915+ const Expr *IgnoreParen = nullptr ;
916+ if (!ILE) {
917+ IgnoreParen = Init->IgnoreParenImpCasts ();
918+ CPLIE = dyn_cast<CXXParenListInitExpr>(IgnoreParen);
919+ SL = dyn_cast<StringLiteral>(IgnoreParen);
920+ OCEE = dyn_cast<ObjCEncodeExpr>(IgnoreParen);
921+ }
922+
923+ // If the initializer is an initializer list, first do the explicit elements.
924+ if (ILE || CPLIE || SL || OCEE) {
925+ // Initializing from a (braced) string literal is a special case; the init
926+ // list element does not initialize a (single) array element.
927+ if ((ILE && ILE->isStringLiteralInit ()) || SL || OCEE) {
928+ llvm_unreachable (" NYI" );
929+ }
930+
931+ ArrayRef<const Expr *> InitExprs =
932+ ILE ? ILE->inits () : CPLIE->getInitExprs ();
933+ InitListElements = InitExprs.size ();
934+
935+ // If this is a multi-dimensional array new, we will initialize multiple
936+ // elements with each init list element.
937+ QualType AllocType = E->getAllocatedType ();
938+ if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
939+ AllocType->getAsArrayTypeUnsafe ())) {
940+ llvm_unreachable (" NYI" );
941+ }
942+
943+ // Enter a partial-destruction Cleanup if necessary.
944+ if (DtorKind) {
945+ llvm_unreachable (" NYI" );
946+ }
947+
948+ CharUnits StartAlign = CurPtr.getAlignment ();
949+ for (const Expr *IE : InitExprs) {
950+ llvm_unreachable (" NYI" );
951+ }
952+
953+ // The remaining elements are filled with the array filler expression.
954+ Init = ILE ? ILE->getArrayFiller () : CPLIE->getArrayFiller ();
955+
956+ // Extract the initializer for the individual array elements by pulling
957+ // out the array filler from all the nested initializer lists. This avoids
958+ // generating a nested loop for the initialization.
959+ while (Init && Init->getType ()->isConstantArrayType ()) {
960+ auto *SubILE = dyn_cast<InitListExpr>(Init);
961+ if (!SubILE)
962+ break ;
963+ assert (SubILE->getNumInits () == 0 && " explicit inits in array filler?" );
964+ Init = SubILE->getArrayFiller ();
965+ }
966+
967+ // Switch back to initializing one base element at a time.
968+ CurPtr = CurPtr.withElementType (BeginPtr.getElementType ());
884969 }
885970
886971 // If all elements have already been initialized, skip any further
@@ -911,6 +996,12 @@ void CIRGenFunction::emitNewArrayInitializer(
911996 llvm_unreachable (" NYI" );
912997 }
913998
999+ // If this is value-initialization, we can usually use memset.
1000+ if (isa<ImplicitValueInitExpr>(Init)) {
1001+ if (TryMemsetInitialization ())
1002+ return ;
1003+ llvm_unreachable (" NYI" );
1004+ }
9141005 llvm_unreachable (" NYI" );
9151006}
9161007
0 commit comments