Re: r332847 - [CodeGen] Recognize more cases of zero initialization
Reverted in r332886; I added a testcase for the miscompile below to test/CodeGenCXX/reference-init.cpp On 21 May 2018 at 13:28, Richard Smithwrote: > On 21 May 2018 at 13:22, Richard Smith wrote: > >> On 21 May 2018 at 09:09, Serge Pavlov via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: sepavloff >>> Date: Mon May 21 09:09:54 2018 >>> New Revision: 332847 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=332847=rev >>> Log: >>> [CodeGen] Recognize more cases of zero initialization >>> >>> If a variable has an initializer, codegen tries to build its value. If >>> the variable is large in size, building its value requires substantial >>> resources. It causes strange behavior from user viewpoint: compilation >>> of huge zero initialized arrays like: >>> >>> char data_1[2147483648u] = { 0 }; >>> >>> consumes enormous amount of time and memory. >>> >>> With this change codegen tries to determine if variable initializer is >>> equivalent to zero initializer. In this case variable value is not >>> constructed. >>> >>> This change fixes PR18978. >>> >>> Differential Revision: https://reviews.llvm.org/D46241 >>> >>> Removed: >>> cfe/trunk/test/SemaCXX/large-array-init.cpp >>> Modified: >>> cfe/trunk/include/clang/AST/Expr.h >>> cfe/trunk/lib/AST/ExprConstant.cpp >>> cfe/trunk/lib/CodeGen/CGExprConstant.cpp >>> cfe/trunk/test/CodeGen/const-init.c >>> cfe/trunk/test/CodeGen/designated-initializers.c >>> cfe/trunk/test/CodeGen/union-init2.c >>> cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp >>> cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp >>> >>> Modified: cfe/trunk/include/clang/AST/Expr.h >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ >>> AST/Expr.h?rev=332847=332846=332847=diff >>> >>> == >>> --- cfe/trunk/include/clang/AST/Expr.h (original) >>> +++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 09:09:54 2018 >>> @@ -537,6 +537,13 @@ public: >>>bool isConstantInitializer(ASTContext , bool ForRef, >>> const Expr **Culprit = nullptr) const; >>> >>> + enum SideEffectsKind { >>> +SE_NoSideEffects, ///< Strictly evaluate the expression. >>> +SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, >>> but not >>> + ///< arbitrary unmodeled side effects. >>> +SE_AllowSideEffects///< Allow any unmodeled side effect. >>> + }; >>> + >>>/// EvalStatus is a struct with detailed info about an evaluation in >>> progress. >>>struct EvalStatus { >>> /// Whether the evaluated expression has side effects. >>> @@ -565,6 +572,11 @@ public: >>> bool hasSideEffects() const { >>>return HasSideEffects; >>> } >>> + >>> +bool hasUnacceptableSideEffect(SideEffectsKind SEK) { >>> + return (SEK < SE_AllowSideEffects && HasSideEffects) || >>> + (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior); >>> +} >>>}; >>> >>>/// EvalResult is a struct with detailed info about an evaluated >>> expression. >>> @@ -591,13 +603,6 @@ public: >>>/// side-effects. >>>bool EvaluateAsBooleanCondition(bool , const ASTContext ) >>> const; >>> >>> - enum SideEffectsKind { >>> -SE_NoSideEffects, ///< Strictly evaluate the expression. >>> -SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, >>> but not >>> - ///< arbitrary unmodeled side effects. >>> -SE_AllowSideEffects///< Allow any unmodeled side effect. >>> - }; >>> - >>>/// EvaluateAsInt - Return true if this is a constant which we can >>> fold and >>>/// convert to an integer, using any crazy technique that we want to. >>>bool EvaluateAsInt(llvm::APSInt , const ASTContext , >>> >>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCo >>> nstant.cpp?rev=332847=332846=332847=diff >>> >>> == >>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 09:09:54 2018 >>> @@ -10312,12 +10312,6 @@ bool Expr::EvaluateAsBooleanCondition(bo >>> HandleConversionToBool(Scratch.Val, Result); >>> } >>> >>> -static bool hasUnacceptableSideEffect(Expr::EvalStatus , >>> - Expr::SideEffectsKind SEK) { >>> - return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || >>> - (SEK < Expr::SE_AllowUndefinedBehavior && >>> Result.HasUndefinedBehavior); >>> -} >>> - >>> bool Expr::EvaluateAsInt(APSInt , const ASTContext , >>> SideEffectsKind AllowSideEffects) const { >>>if (!getType()->isIntegralOrEnumerationType()) >>> @@ -10325,7 +10319,7 @@ bool
Re: r332847 - [CodeGen] Recognize more cases of zero initialization
On 21 May 2018 at 13:22, Richard Smithwrote: > On 21 May 2018 at 09:09, Serge Pavlov via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> Author: sepavloff >> Date: Mon May 21 09:09:54 2018 >> New Revision: 332847 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=332847=rev >> Log: >> [CodeGen] Recognize more cases of zero initialization >> >> If a variable has an initializer, codegen tries to build its value. If >> the variable is large in size, building its value requires substantial >> resources. It causes strange behavior from user viewpoint: compilation >> of huge zero initialized arrays like: >> >> char data_1[2147483648u] = { 0 }; >> >> consumes enormous amount of time and memory. >> >> With this change codegen tries to determine if variable initializer is >> equivalent to zero initializer. In this case variable value is not >> constructed. >> >> This change fixes PR18978. >> >> Differential Revision: https://reviews.llvm.org/D46241 >> >> Removed: >> cfe/trunk/test/SemaCXX/large-array-init.cpp >> Modified: >> cfe/trunk/include/clang/AST/Expr.h >> cfe/trunk/lib/AST/ExprConstant.cpp >> cfe/trunk/lib/CodeGen/CGExprConstant.cpp >> cfe/trunk/test/CodeGen/const-init.c >> cfe/trunk/test/CodeGen/designated-initializers.c >> cfe/trunk/test/CodeGen/union-init2.c >> cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp >> cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp >> >> Modified: cfe/trunk/include/clang/AST/Expr.h >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ >> AST/Expr.h?rev=332847=332846=332847=diff >> >> == >> --- cfe/trunk/include/clang/AST/Expr.h (original) >> +++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 09:09:54 2018 >> @@ -537,6 +537,13 @@ public: >>bool isConstantInitializer(ASTContext , bool ForRef, >> const Expr **Culprit = nullptr) const; >> >> + enum SideEffectsKind { >> +SE_NoSideEffects, ///< Strictly evaluate the expression. >> +SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, >> but not >> + ///< arbitrary unmodeled side effects. >> +SE_AllowSideEffects///< Allow any unmodeled side effect. >> + }; >> + >>/// EvalStatus is a struct with detailed info about an evaluation in >> progress. >>struct EvalStatus { >> /// Whether the evaluated expression has side effects. >> @@ -565,6 +572,11 @@ public: >> bool hasSideEffects() const { >>return HasSideEffects; >> } >> + >> +bool hasUnacceptableSideEffect(SideEffectsKind SEK) { >> + return (SEK < SE_AllowSideEffects && HasSideEffects) || >> + (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior); >> +} >>}; >> >>/// EvalResult is a struct with detailed info about an evaluated >> expression. >> @@ -591,13 +603,6 @@ public: >>/// side-effects. >>bool EvaluateAsBooleanCondition(bool , const ASTContext ) >> const; >> >> - enum SideEffectsKind { >> -SE_NoSideEffects, ///< Strictly evaluate the expression. >> -SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, >> but not >> - ///< arbitrary unmodeled side effects. >> -SE_AllowSideEffects///< Allow any unmodeled side effect. >> - }; >> - >>/// EvaluateAsInt - Return true if this is a constant which we can >> fold and >>/// convert to an integer, using any crazy technique that we want to. >>bool EvaluateAsInt(llvm::APSInt , const ASTContext , >> >> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCo >> nstant.cpp?rev=332847=332846=332847=diff >> >> == >> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 09:09:54 2018 >> @@ -10312,12 +10312,6 @@ bool Expr::EvaluateAsBooleanCondition(bo >> HandleConversionToBool(Scratch.Val, Result); >> } >> >> -static bool hasUnacceptableSideEffect(Expr::EvalStatus , >> - Expr::SideEffectsKind SEK) { >> - return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || >> - (SEK < Expr::SE_AllowUndefinedBehavior && >> Result.HasUndefinedBehavior); >> -} >> - >> bool Expr::EvaluateAsInt(APSInt , const ASTContext , >> SideEffectsKind AllowSideEffects) const { >>if (!getType()->isIntegralOrEnumerationType()) >> @@ -10325,7 +10319,7 @@ bool Expr::EvaluateAsInt(APSInt , >> >>EvalResult ExprResult; >>if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() || >> - hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) >> + ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) >> return false; >> >>
Re: r332847 - [CodeGen] Recognize more cases of zero initialization
On 21 May 2018 at 09:09, Serge Pavlov via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: sepavloff > Date: Mon May 21 09:09:54 2018 > New Revision: 332847 > > URL: http://llvm.org/viewvc/llvm-project?rev=332847=rev > Log: > [CodeGen] Recognize more cases of zero initialization > > If a variable has an initializer, codegen tries to build its value. If > the variable is large in size, building its value requires substantial > resources. It causes strange behavior from user viewpoint: compilation > of huge zero initialized arrays like: > > char data_1[2147483648u] = { 0 }; > > consumes enormous amount of time and memory. > > With this change codegen tries to determine if variable initializer is > equivalent to zero initializer. In this case variable value is not > constructed. > > This change fixes PR18978. > > Differential Revision: https://reviews.llvm.org/D46241 > > Removed: > cfe/trunk/test/SemaCXX/large-array-init.cpp > Modified: > cfe/trunk/include/clang/AST/Expr.h > cfe/trunk/lib/AST/ExprConstant.cpp > cfe/trunk/lib/CodeGen/CGExprConstant.cpp > cfe/trunk/test/CodeGen/const-init.c > cfe/trunk/test/CodeGen/designated-initializers.c > cfe/trunk/test/CodeGen/union-init2.c > cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp > cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp > > Modified: cfe/trunk/include/clang/AST/Expr.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/AST/Expr.h?rev=332847=332846=332847=diff > > == > --- cfe/trunk/include/clang/AST/Expr.h (original) > +++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 09:09:54 2018 > @@ -537,6 +537,13 @@ public: >bool isConstantInitializer(ASTContext , bool ForRef, > const Expr **Culprit = nullptr) const; > > + enum SideEffectsKind { > +SE_NoSideEffects, ///< Strictly evaluate the expression. > +SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, > but not > + ///< arbitrary unmodeled side effects. > +SE_AllowSideEffects///< Allow any unmodeled side effect. > + }; > + >/// EvalStatus is a struct with detailed info about an evaluation in > progress. >struct EvalStatus { > /// Whether the evaluated expression has side effects. > @@ -565,6 +572,11 @@ public: > bool hasSideEffects() const { >return HasSideEffects; > } > + > +bool hasUnacceptableSideEffect(SideEffectsKind SEK) { > + return (SEK < SE_AllowSideEffects && HasSideEffects) || > + (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior); > +} >}; > >/// EvalResult is a struct with detailed info about an evaluated > expression. > @@ -591,13 +603,6 @@ public: >/// side-effects. >bool EvaluateAsBooleanCondition(bool , const ASTContext ) > const; > > - enum SideEffectsKind { > -SE_NoSideEffects, ///< Strictly evaluate the expression. > -SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, > but not > - ///< arbitrary unmodeled side effects. > -SE_AllowSideEffects///< Allow any unmodeled side effect. > - }; > - >/// EvaluateAsInt - Return true if this is a constant which we can fold > and >/// convert to an integer, using any crazy technique that we want to. >bool EvaluateAsInt(llvm::APSInt , const ASTContext , > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > ExprConstant.cpp?rev=332847=332846=332847=diff > > == > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 09:09:54 2018 > @@ -10312,12 +10312,6 @@ bool Expr::EvaluateAsBooleanCondition(bo > HandleConversionToBool(Scratch.Val, Result); > } > > -static bool hasUnacceptableSideEffect(Expr::EvalStatus , > - Expr::SideEffectsKind SEK) { > - return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || > - (SEK < Expr::SE_AllowUndefinedBehavior && > Result.HasUndefinedBehavior); > -} > - > bool Expr::EvaluateAsInt(APSInt , const ASTContext , > SideEffectsKind AllowSideEffects) const { >if (!getType()->isIntegralOrEnumerationType()) > @@ -10325,7 +10319,7 @@ bool Expr::EvaluateAsInt(APSInt , > >EvalResult ExprResult; >if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() || > - hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) > + ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) > return false; > >Result = ExprResult.Val.getInt(); > @@ -10339,7 +10333,7 @@ bool Expr::EvaluateAsFloat(APFloat > >EvalResult ExprResult; >if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat()
r332847 - [CodeGen] Recognize more cases of zero initialization
Author: sepavloff Date: Mon May 21 09:09:54 2018 New Revision: 332847 URL: http://llvm.org/viewvc/llvm-project?rev=332847=rev Log: [CodeGen] Recognize more cases of zero initialization If a variable has an initializer, codegen tries to build its value. If the variable is large in size, building its value requires substantial resources. It causes strange behavior from user viewpoint: compilation of huge zero initialized arrays like: char data_1[2147483648u] = { 0 }; consumes enormous amount of time and memory. With this change codegen tries to determine if variable initializer is equivalent to zero initializer. In this case variable value is not constructed. This change fixes PR18978. Differential Revision: https://reviews.llvm.org/D46241 Removed: cfe/trunk/test/SemaCXX/large-array-init.cpp Modified: cfe/trunk/include/clang/AST/Expr.h cfe/trunk/lib/AST/ExprConstant.cpp cfe/trunk/lib/CodeGen/CGExprConstant.cpp cfe/trunk/test/CodeGen/const-init.c cfe/trunk/test/CodeGen/designated-initializers.c cfe/trunk/test/CodeGen/union-init2.c cfe/trunk/test/CodeGenCXX/cxx11-initializer-aggregate.cpp cfe/trunk/test/CodeGenCXX/cxx1z-initializer-aggregate.cpp Modified: cfe/trunk/include/clang/AST/Expr.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=332847=332846=332847=diff == --- cfe/trunk/include/clang/AST/Expr.h (original) +++ cfe/trunk/include/clang/AST/Expr.h Mon May 21 09:09:54 2018 @@ -537,6 +537,13 @@ public: bool isConstantInitializer(ASTContext , bool ForRef, const Expr **Culprit = nullptr) const; + enum SideEffectsKind { +SE_NoSideEffects, ///< Strictly evaluate the expression. +SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not + ///< arbitrary unmodeled side effects. +SE_AllowSideEffects///< Allow any unmodeled side effect. + }; + /// EvalStatus is a struct with detailed info about an evaluation in progress. struct EvalStatus { /// Whether the evaluated expression has side effects. @@ -565,6 +572,11 @@ public: bool hasSideEffects() const { return HasSideEffects; } + +bool hasUnacceptableSideEffect(SideEffectsKind SEK) { + return (SEK < SE_AllowSideEffects && HasSideEffects) || + (SEK < SE_AllowUndefinedBehavior && HasUndefinedBehavior); +} }; /// EvalResult is a struct with detailed info about an evaluated expression. @@ -591,13 +603,6 @@ public: /// side-effects. bool EvaluateAsBooleanCondition(bool , const ASTContext ) const; - enum SideEffectsKind { -SE_NoSideEffects, ///< Strictly evaluate the expression. -SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not - ///< arbitrary unmodeled side effects. -SE_AllowSideEffects///< Allow any unmodeled side effect. - }; - /// EvaluateAsInt - Return true if this is a constant which we can fold and /// convert to an integer, using any crazy technique that we want to. bool EvaluateAsInt(llvm::APSInt , const ASTContext , Modified: cfe/trunk/lib/AST/ExprConstant.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=332847=332846=332847=diff == --- cfe/trunk/lib/AST/ExprConstant.cpp (original) +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May 21 09:09:54 2018 @@ -10312,12 +10312,6 @@ bool Expr::EvaluateAsBooleanCondition(bo HandleConversionToBool(Scratch.Val, Result); } -static bool hasUnacceptableSideEffect(Expr::EvalStatus , - Expr::SideEffectsKind SEK) { - return (SEK < Expr::SE_AllowSideEffects && Result.HasSideEffects) || - (SEK < Expr::SE_AllowUndefinedBehavior && Result.HasUndefinedBehavior); -} - bool Expr::EvaluateAsInt(APSInt , const ASTContext , SideEffectsKind AllowSideEffects) const { if (!getType()->isIntegralOrEnumerationType()) @@ -10325,7 +10319,7 @@ bool Expr::EvaluateAsInt(APSInt , EvalResult ExprResult; if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isInt() || - hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) + ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) return false; Result = ExprResult.Val.getInt(); @@ -10339,7 +10333,7 @@ bool Expr::EvaluateAsFloat(APFloat EvalResult ExprResult; if (!EvaluateAsRValue(ExprResult, Ctx) || !ExprResult.Val.isFloat() || - hasUnacceptableSideEffect(ExprResult, AllowSideEffects)) + ExprResult.hasUnacceptableSideEffect(AllowSideEffects)) return false; Result = ExprResult.Val.getFloat(); @@ -10417,7 +10411,7 @@ bool Expr::EvaluateAsInitializer(APValue bool Expr::isEvaluatable(const ASTContext , SideEffectsKind