https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70001

--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> ---
(In reply to Patrick Palka from comment #6)
> struct X
> {
>   int a;
> 
>   constexpr X () : a (0) { }
> };
> 
> const int N = 1 << 19;
> 
> struct A
> {
>   X elems[N];
> } F;
> 
> 
> Just playing around, but naively sharing the constructor of each array
> element in the case of default- or value-initialization lowers compile time
> of the original test case down to a few seconds.
> 
> diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
> index d3b04b1..2ce44a5 100644
> --- a/gcc/cp/constexpr.c
> +++ b/gcc/cp/constexpr.c
> @@ -2328,6 +2328,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree
> atype, tree init,
>    vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
>    vec_alloc (*p, max + 1);
>    bool pre_init = false;
> +  tree pre_init_elt = NULL_TREE;
>    unsigned HOST_WIDE_INT i;
>  
>    /* For the default constructor, build up a call to the default
> @@ -2377,9 +2378,12 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree
> atype, tree init,
>         {
>           /* Initializing an element using value or default initialization
>              we just pre-built above.  */
> -         eltinit = (cxx_eval_constant_expression
> -                    (&new_ctx, init,
> -                     lval, non_constant_p, overflow_p));
> +         if (pre_init_elt == NULL_TREE)
> +           pre_init_elt = (cxx_eval_constant_expression
> +                           (&new_ctx, init,
> +                            lval, non_constant_p, overflow_p));
> +
> +          eltinit = pre_init_elt;
>         }
>        else
>         {

That won't work in all cases (a constructor could depend on the value of
'this'), but perhaps we could use initializer_constant_valid_p to test for that
case and avoid re-using the initializer if it returns something other than
null_pointer_node.

Reply via email to