rjmccall added inline comments.

================
Comment at: lib/CodeGen/CGExprConstant.cpp:1413
+  } else if (!Init->isEvaluatable(CE.CGM.getContext())) {
+    return false;
+  } else if (InitTy->hasPointerRepresentation()) {
----------------
sepavloff wrote:
> rsmith wrote:
> > sepavloff wrote:
> > > rjmccall wrote:
> > > > Aren't the null-pointer and integer-constant-expression checks below 
> > > > already checking this?  Also, `isEvaluatable` actually computes the 
> > > > full value internally (as an `APValue`), so if you're worried about the 
> > > > memory and compile-time effects of producing such a value, you really 
> > > > shouldn't call it.
> > > > 
> > > > You could reasonably move this entire function to be a method on `Expr` 
> > > > that takes an `ASTContext`.
> > > Comment for `EvaluateAsRValue` says that it tries calculate expression 
> > > agressively. Indeed, for the code:
> > > ```
> > >   decltype(nullptr) null();
> > >   int *p = null();
> > > ```
> > > compiler ignores potential side effect of `null()` and removes the call, 
> > > leaving only zero initialization. `isNullPointerConstant` behaves 
> > > similarly.
> > Nonetheless, it looks like this function could evaluate `Init` up to three 
> > times, which seems unreasonable. Instead of the checks based on trying to 
> > evaluate the initializer (`isNullPointerConstant` + 
> > `isIntegerConstantExpr`), how about calling `VarDecl::evaluateValue()` 
> > (which will return a potentially pre-computed and cached initializer value) 
> > and checking if the result is a zero constant?
> > 
> > In fact, `tryEmitPrivateForVarInit` already does most of that for you, and 
> > the right place to make this change is probably in 
> > `tryEmitPrivateForMemory`, where you can test to see if the `APValue` is 
> > zero-initialized and produce a `zeroinitializer` if so. As a side-benefit, 
> > putting the change there will mean we'll also start using `zeroinitializer` 
> > for zero-initialized subobjects of objects that have non-zero pieces.
> An important point in this patch is that CodeGen tries to find out, if the 
> initializer can be replaced with zeroinitializer, *prior* to the evaluation 
> of it. For huge arrays the evaluation consumes huge amount of memory and time 
> and it must be avoided.
> 
> With this patch CodeGen may evaluate parts of the initializer, if it is 
> represented by `InitListExpr`. It may cause redundant calculation, for 
> instance if the check for zero initialization failed but the initializer is 
> constant. To avoid this redundancy we could cache result of evaluation in 
> instances of `Expr` and then use the partial values in the evaluation of the 
> initializer. The simple use case solved by this patch probably is not a 
> sufficient justification for such redesign.
I really think you should have some sort of type restriction in front of this 
so that you don't end up creating a huge APValue only to throw it away because 
it's not an int or a pointer.  It's quite possible to have something like an 
array initializer in a nested position that's not within an InitListExpr , e.g. 
due to compound literals or std::initializer_list.


Repository:
  rC Clang

https://reviews.llvm.org/D46241



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to