tbaeder updated this revision to Diff 449182. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D130791/new/
https://reviews.llvm.org/D130791 Files: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10833,6 +10833,9 @@ if (FinalSize == 0) return true; + bool HasTrivialConstructor = CheckTrivialDefaultConstructor( + Info, E->getExprLoc(), E->getConstructor(), + E->requiresZeroInitialization()); LValue ArrayElt = Subobject; ArrayElt.addArray(Info, E, CAT); // We do the whole initialization in two passes, first for just one element, @@ -10856,19 +10859,26 @@ for (unsigned I = OldElts; I < N; ++I) Value->getArrayInitializedElt(I) = Filler; - // Initialize the elements. - for (unsigned I = OldElts; I < N; ++I) { - if (!VisitCXXConstructExpr(E, ArrayElt, - &Value->getArrayInitializedElt(I), - CAT->getElementType()) || - !HandleLValueArrayAdjustment(Info, E, ArrayElt, - CAT->getElementType(), 1)) - return false; - // When checking for const initilization any diagnostic is considered - // an error. - if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && - !Info.keepEvaluatingAfterFailure()) - return false; + if (HasTrivialConstructor && N == FinalSize) { + // If we have a trivial constructor, only evaluate it once and copy + // the result into all the array elements. + APValue &FirstResult = Value->getArrayInitializedElt(0); + for (unsigned I = OldElts; I < FinalSize; ++I) + Value->getArrayInitializedElt(I) = FirstResult; + } else { + for (unsigned I = OldElts; I < N; ++I) { + if (!VisitCXXConstructExpr(E, ArrayElt, + &Value->getArrayInitializedElt(I), + CAT->getElementType()) || + !HandleLValueArrayAdjustment(Info, E, ArrayElt, + CAT->getElementType(), 1)) + return false; + // When checking for const initilization any diagnostic is considered + // an error. + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + !Info.keepEvaluatingAfterFailure()) + return false; + } } } Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -55,6 +55,9 @@ - Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function specifier on something other than a function declaration. This fixes `Issue 56800 <https://github.com/llvm/llvm-project/issues/56800>`_. +- Improve compile-times with large dynamic array allocations with trivial + constructors. This fixes + `Issue 56774<https://github.com/llvm/llvm-project/issues/56774>`_. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -10833,6 +10833,9 @@ if (FinalSize == 0) return true; + bool HasTrivialConstructor = CheckTrivialDefaultConstructor( + Info, E->getExprLoc(), E->getConstructor(), + E->requiresZeroInitialization()); LValue ArrayElt = Subobject; ArrayElt.addArray(Info, E, CAT); // We do the whole initialization in two passes, first for just one element, @@ -10856,19 +10859,26 @@ for (unsigned I = OldElts; I < N; ++I) Value->getArrayInitializedElt(I) = Filler; - // Initialize the elements. - for (unsigned I = OldElts; I < N; ++I) { - if (!VisitCXXConstructExpr(E, ArrayElt, - &Value->getArrayInitializedElt(I), - CAT->getElementType()) || - !HandleLValueArrayAdjustment(Info, E, ArrayElt, - CAT->getElementType(), 1)) - return false; - // When checking for const initilization any diagnostic is considered - // an error. - if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && - !Info.keepEvaluatingAfterFailure()) - return false; + if (HasTrivialConstructor && N == FinalSize) { + // If we have a trivial constructor, only evaluate it once and copy + // the result into all the array elements. + APValue &FirstResult = Value->getArrayInitializedElt(0); + for (unsigned I = OldElts; I < FinalSize; ++I) + Value->getArrayInitializedElt(I) = FirstResult; + } else { + for (unsigned I = OldElts; I < N; ++I) { + if (!VisitCXXConstructExpr(E, ArrayElt, + &Value->getArrayInitializedElt(I), + CAT->getElementType()) || + !HandleLValueArrayAdjustment(Info, E, ArrayElt, + CAT->getElementType(), 1)) + return false; + // When checking for const initilization any diagnostic is considered + // an error. + if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() && + !Info.keepEvaluatingAfterFailure()) + return false; + } } } Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -55,6 +55,9 @@ - Fixes an accepts-invalid bug in C when using a ``_Noreturn`` function specifier on something other than a function declaration. This fixes `Issue 56800 <https://github.com/llvm/llvm-project/issues/56800>`_. +- Improve compile-times with large dynamic array allocations with trivial + constructors. This fixes + `Issue 56774<https://github.com/llvm/llvm-project/issues/56774>`_. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits