Message ID | alpine.LSU.2.20.1802091341270.18265@zhemvz.fhfr.qr |
---|---|
State | New |
Headers | show |
Series | [C++] Fix PR84281 | expand |
OK. On Fri, Feb 9, 2018 at 7:44 AM, Richard Biener <rguenther@suse.de> wrote: > > 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 <rguenther@suse.de> > > 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<constructor_elt, va_gc> **p = &CONSTRUCTOR_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)
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 Biener <rguenther@suse.de>
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 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<constructor_elt, va_gc> **p = &CONSTRUCTOR_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)
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<constructor_elt, va_gc> **p = &CONSTRUCTOR_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)