@@ -876,11 +876,96 @@ void CIRGenFunction::emitNewArrayInitializer(
876
876
unsigned InitListElements = 0 ;
877
877
878
878
const Expr *Init = E->getInitializer ();
879
+ QualType::DestructionKind DtorKind = ElementType.isDestructedType ();
879
880
CleanupDeactivationScope deactivation (*this );
880
881
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
+
881
911
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 ());
884
969
}
885
970
886
971
// If all elements have already been initialized, skip any further
@@ -911,6 +996,12 @@ void CIRGenFunction::emitNewArrayInitializer(
911
996
llvm_unreachable (" NYI" );
912
997
}
913
998
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
+ }
914
1005
llvm_unreachable (" NYI" );
915
1006
}
916
1007
0 commit comments