diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-12-14 20:37:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-12-14 20:37:38 +0100 |
commit | 0fca07e31dc85bea3b1d669d7cc1d51d22192335 (patch) | |
tree | 662864e452bc122b8f1cff2569205e4a587d86c0 /gcc/gimplify.c | |
parent | faa9232da39587b27b46341667d6d415d2af9280 (diff) | |
download | gcc-0fca07e31dc85bea3b1d669d7cc1d51d22192335.zip gcc-0fca07e31dc85bea3b1d669d7cc1d51d22192335.tar.gz gcc-0fca07e31dc85bea3b1d669d7cc1d51d22192335.tar.bz2 |
re PR c++/82294 (Array of objects with constexpr constructors initialized from space-inefficient memory image)
PR c++/82294
PR c++/87436
* expr.h (categorize_ctor_elements): Add p_unique_nz_elts argument.
* expr.c (categorize_ctor_elements_1): Likewise. Compute it like
p_nz_elts, except don't multiply it by mult. Adjust recursive call.
Fix up COMPLEX_CST handling.
(categorize_ctor_elements): Add p_unique_nz_elts argument, initialize
it and pass it through to categorize_ctor_elements_1.
(mostly_zeros_p, all_zeros_p): Adjust categorize_ctor_elements callers.
* gimplify.c (gimplify_init_constructor): Likewise. Don't force
ctor into readonly data section if num_unique_nonzero_elements is
smaller or equal to 1/8 of num_nonzero_elements and size is >= 64
bytes.
* g++.dg/tree-ssa/pr82294.C: New test.
* g++.dg/tree-ssa/pr87436.C: New test.
From-SVN: r267143
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 9022ef8..465d138 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4778,7 +4778,15 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, { struct gimplify_init_ctor_preeval_data preeval_data; HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; + HOST_WIDE_INT num_unique_nonzero_elements; bool cleared, complete_p, valid_const_initializer; + /* Use readonly data for initializers of this or smaller size + regardless of the num_nonzero_elements / num_unique_nonzero_elements + ratio. */ + const HOST_WIDE_INT min_unique_size = 64; + /* If num_nonzero_elements / num_unique_nonzero_elements ratio + is smaller than this, use readonly data. */ + const int unique_nonzero_ratio = 8; /* Aggregate types must lower constructors to initialization of individual elements. The exception is that a CONSTRUCTOR node @@ -4795,6 +4803,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, can only do so if it known to be a valid constant initializer. */ valid_const_initializer = categorize_ctor_elements (ctor, &num_nonzero_elements, + &num_unique_nonzero_elements, &num_ctor_elements, &complete_p); /* If a const aggregate variable is being initialized, then it @@ -4803,7 +4812,15 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && num_nonzero_elements > 1 && TREE_READONLY (object) && VAR_P (object) - && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))) + && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)) + /* For ctors that have many repeated nonzero elements + represented through RANGE_EXPRs, prefer initializing + those through runtime loops over copies of large amounts + of data from readonly data section. */ + && (num_unique_nonzero_elements + > num_nonzero_elements / unique_nonzero_ratio + || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) + <= (unsigned HOST_WIDE_INT) min_unique_size))) { if (notify_temp_creation) return GS_ERROR; @@ -4896,6 +4913,13 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, is so large as to make individual moves inefficient. */ if (size > 0 && num_nonzero_elements > 1 + /* For ctors that have many repeated nonzero elements + represented through RANGE_EXPRs, prefer initializing + those through runtime loops over copies of large amounts + of data from readonly data section. */ + && (num_unique_nonzero_elements + > num_nonzero_elements / unique_nonzero_ratio + || size <= min_unique_size) && (size < num_nonzero_elements || !can_move_by_pieces (size, align))) { |