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.