Re: [PATCH][C++] Fix PR84281
On Fri, 9 Feb 2018, Jason Merrill wrote: > OK. Failed to notice that vec_safe_reserve reserves additional space so applied as follows restricting it to the very first iteration. Richard. 2018-02-12 Richard BienerPR c++/84281 * constexpr.c (cxx_eval_vec_init_1): Use a RANGE_EXPR to compact uniform constructors and delay allocating them fully. Index: gcc/cp/constexpr.c === --- gcc/cp/constexpr.c (revision 257525) +++ gcc/cp/constexpr.c (working copy) @@ -2885,7 +2885,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype)); verify_ctor_sanity (ctx, atype); vec **p = _ELTS (ctx->ctor); - vec_alloc (*p, max + 1); bool pre_init = false; unsigned HOST_WIDE_INT i; @@ -2978,13 +2977,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; - for (i = 1; i < max; ++i) - { - idx = build_int_cst (size_type_node, i); - CONSTRUCTOR_APPEND_ELT (*p, idx, unshare_constructor (eltinit)); - } + tree range = build2 (RANGE_EXPR, size_type_node, + build_int_cst (size_type_node, 1), + build_int_cst (size_type_node, max - 1)); + CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit)); break; } + else if (i == 0) + vec_safe_reserve (*p, max); } if (!*non_constant_p)
Re: [PATCH][C++] Fix PR84281
OK. On Fri, Feb 9, 2018 at 7:44 AM, Richard Bienerwrote: > > The following patch optimizes the equal element case of > cxx_eval_vec_init_1 to use a RANGE_EXPR in the built CONSTRUCTOR > instead of repeating the same element over and over. This > cuts down memory use of the invalid testcase in the PR from > tens of GB to nothing and makes us rejct it instantanously > instead of by going OOM. > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > Ok for trunk? > > Thanks, > Richard. > > 2018-02-09 Richard Biener > > PR c++/84281 > * constexpr.c (cxx_eval_vec_init_1): Use a RANGE_EXPR to compact > uniform constructors and delay allocating them fully. > > Index: gcc/cp/constexpr.c > === > --- gcc/cp/constexpr.c (revision 257491) > +++ gcc/cp/constexpr.c (working copy) > @@ -2885,7 +2885,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx >unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype)); >verify_ctor_sanity (ctx, atype); >vec **p = _ELTS (ctx->ctor); > - vec_alloc (*p, max + 1); >bool pre_init = false; >unsigned HOST_WIDE_INT i; > > @@ -2978,13 +2977,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx > { > if (new_ctx.ctor != ctx->ctor) > eltinit = new_ctx.ctor; > - for (i = 1; i < max; ++i) > - { > - idx = build_int_cst (size_type_node, i); > - CONSTRUCTOR_APPEND_ELT (*p, idx, unshare_constructor (eltinit)); > - } > + tree range = build2 (RANGE_EXPR, size_type_node, > + build_int_cst (size_type_node, 1), > + build_int_cst (size_type_node, max - 1)); > + CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit)); > break; > } > + else > + vec_safe_reserve (*p, max + 1); > } > >if (!*non_constant_p)
[PATCH][C++] Fix PR84281
The following patch optimizes the equal element case of cxx_eval_vec_init_1 to use a RANGE_EXPR in the built CONSTRUCTOR instead of repeating the same element over and over. This cuts down memory use of the invalid testcase in the PR from tens of GB to nothing and makes us rejct it instantanously instead of by going OOM. Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok for trunk? Thanks, Richard. 2018-02-09 Richard BienerPR c++/84281 * constexpr.c (cxx_eval_vec_init_1): Use a RANGE_EXPR to compact uniform constructors and delay allocating them fully. Index: gcc/cp/constexpr.c === --- gcc/cp/constexpr.c (revision 257491) +++ gcc/cp/constexpr.c (working copy) @@ -2885,7 +2885,6 @@ cxx_eval_vec_init_1 (const constexpr_ctx unsigned HOST_WIDE_INT max = tree_to_uhwi (array_type_nelts_top (atype)); verify_ctor_sanity (ctx, atype); vec **p = _ELTS (ctx->ctor); - vec_alloc (*p, max + 1); bool pre_init = false; unsigned HOST_WIDE_INT i; @@ -2978,13 +2977,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx { if (new_ctx.ctor != ctx->ctor) eltinit = new_ctx.ctor; - for (i = 1; i < max; ++i) - { - idx = build_int_cst (size_type_node, i); - CONSTRUCTOR_APPEND_ELT (*p, idx, unshare_constructor (eltinit)); - } + tree range = build2 (RANGE_EXPR, size_type_node, + build_int_cst (size_type_node, 1), + build_int_cst (size_type_node, max - 1)); + CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit)); break; } + else + vec_safe_reserve (*p, max + 1); } if (!*non_constant_p)