Author: Timm Bäder Date: 2022-08-03T10:38:15+02:00 New Revision: 11e52ecf74e942b738fa8496960bbb2f0a7373de
URL: https://github.com/llvm/llvm-project/commit/11e52ecf74e942b738fa8496960bbb2f0a7373de DIFF: https://github.com/llvm/llvm-project/commit/11e52ecf74e942b738fa8496960bbb2f0a7373de.diff LOG: [clang] Short-circuit trivial constructors when evaluating arrays VisitCXXConstructExpr() will later do something similar, but for large arrays, we should try to do it once an not for every element. Fixes #56774 Differential Revision: https://reviews.llvm.org/D130791 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/ExprConstant.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 9dc08639dafb4..2c439a01d7216 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -54,6 +54,9 @@ Bug Fixes `Issue 56800 <https://github.com/llvm/llvm-project/issues/56800>`_. - Fix `#56772 <https://github.com/llvm/llvm-project/issues/56772>`_ - invalid destructor names were incorrectly accepted on template classes. +- 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 32a04ca9e3de3..efaccf52132b3 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10833,6 +10833,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, 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 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, 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; + } } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits