diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-03-23 19:55:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-03-23 19:55:38 +0100 |
commit | 928af3bfe2bd34a803c3a371436463fd46b31e5d (patch) | |
tree | ab45560fcaf026a391bb8e5afaa07f430e349432 /gcc/cp | |
parent | 61637db3f2f55a1b97e6f466be012a131bede75d (diff) | |
download | gcc-928af3bfe2bd34a803c3a371436463fd46b31e5d.zip gcc-928af3bfe2bd34a803c3a371436463fd46b31e5d.tar.gz gcc-928af3bfe2bd34a803c3a371436463fd46b31e5d.tar.bz2 |
re PR c++/70001 (Infinity compilation time)
PR c++/70001
* constexpr.c (cxx_eval_vec_init_1): Reuse CONSTRUCTOR initializers
for 1..max even for multi-dimensional arrays. Call unshare_expr
on it.
* g++.dg/cpp0x/constexpr-70001-4.C: New test.
* g++.dg/cpp1y/pr70001.C: New test.
From-SVN: r234439
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 39 |
2 files changed, 30 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b7a1f39..42c7054 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2016-03-23 Jakub Jelinek <jakub@redhat.com> + PR c++/70001 + * constexpr.c (cxx_eval_vec_init_1): Reuse CONSTRUCTOR initializers + for 1..max even for multi-dimensional arrays. Call unshare_expr + on it. + PR c++/70323 * constexpr.c (cxx_eval_constant_expression): Diagnose overflow on TREE_OVERFLOW constants. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4baf114..8427513 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2362,7 +2362,6 @@ 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 @@ -2392,6 +2391,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, { tree idx = build_int_cst (size_type_node, i); tree eltinit; + bool reuse = false; constexpr_ctx new_ctx; init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype); if (new_ctx.ctor != ctx->ctor) @@ -2400,7 +2400,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, { /* A multidimensional array; recurse. */ if (value_init || init == NULL_TREE) - eltinit = NULL_TREE; + { + eltinit = NULL_TREE; + reuse = i == 0; + } else eltinit = cp_build_array_ref (input_location, init, idx, tf_warning_or_error); @@ -2412,18 +2415,9 @@ 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. */ - 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; - /* Don't reuse the result of cxx_eval_constant_expression - call if it isn't a constant initializer or if it requires - relocations. */ - if (initializer_constant_valid_p (pre_init_elt, - TREE_TYPE (pre_init_elt)) - != null_pointer_node) - pre_init_elt = NULL_TREE; + eltinit = cxx_eval_constant_expression (&new_ctx, init, lval, + non_constant_p, overflow_p); + reuse = i == 0; } else { @@ -2449,6 +2443,23 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init, } else CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit); + /* Reuse the result of cxx_eval_constant_expression call + from the first iteration to all others if it is a constant + initializer that doesn't require relocations. */ + if (reuse + && max > 1 + && (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit)) + == null_pointer_node)) + { + 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_expr (eltinit)); + } + break; + } } if (!*non_constant_p) |