Re: r332847 - [CodeGen] Recognize more cases of zero initialization

2018-05-21 Thread Richard Smith via cfe-commits
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 Smith  wrote:

> 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

2018-05-21 Thread Richard Smith via cfe-commits
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 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

2018-05-21 Thread Richard Smith via cfe-commits
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

2018-05-21 Thread Serge Pavlov via cfe-commits
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