diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-01-10 22:18:22 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2020-01-10 22:18:22 +0100 |
commit | ea69031c5facc70e4a96df83cd58702900fd54b6 (patch) | |
tree | 879c6e151d192e9ac99c83999572027edc8d0517 /gcc/gimple-fold.c | |
parent | 974bb8a4dcbf51a153ab72da91a7256a296e7fa1 (diff) | |
download | gcc-ea69031c5facc70e4a96df83cd58702900fd54b6.zip gcc-ea69031c5facc70e4a96df83cd58702900fd54b6.tar.gz gcc-ea69031c5facc70e4a96df83cd58702900fd54b6.tar.bz2 |
re PR tree-optimization/93210 (Sub-optimal code optimization on struct/combound constexpr (gcc vs. clang))
PR tree-optimization/93210
* fold-const.h (native_encode_initializer,
can_native_interpret_type_p): Declare.
* fold-const.c (native_encode_string): Fix up handling with off != -1,
simplify.
(native_encode_initializer): New function, moved from dwarf2out.c.
Adjust to native_encode_expr compatible arguments, including dry-run
and partial extraction modes. Don't handle STRING_CST.
(can_native_interpret_type_p): No longer static.
* gimple-fold.c (fold_ctor_reference): For native_encode_expr, verify
offset / BITS_PER_UNIT fits into int and don't call it if
can_native_interpret_type_p fails. If suboff is NULL and for
CONSTRUCTOR fold_{,non}array_ctor_reference returns NULL, retry with
native_encode_initializer.
(fold_const_aggregate_ref_1): Formatting fix.
* dwarf2out.c (native_encode_initializer): Moved to fold-const.c.
(tree_add_const_value_attribute): Adjust caller.
* gcc.dg/pr93210.c: New test.
* g++.dg/opt/pr93210.C: New test.
From-SVN: r280141
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r-- | gcc/gimple-fold.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index d7c5097..569f91e 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -6919,8 +6919,10 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset, if (CONSTANT_CLASS_P (ctor) && BITS_PER_UNIT == 8 && offset % BITS_PER_UNIT == 0 + && offset / BITS_PER_UNIT <= INT_MAX && size % BITS_PER_UNIT == 0 - && size <= MAX_BITSIZE_MODE_ANY_MODE) + && size <= MAX_BITSIZE_MODE_ANY_MODE + && can_native_interpret_type_p (type)) { unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT]; int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT, @@ -6934,13 +6936,35 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset, if (!suboff) suboff = &dummy; + tree ret; if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE) - return fold_array_ctor_reference (type, ctor, offset, size, - from_decl, suboff); + ret = fold_array_ctor_reference (type, ctor, offset, size, + from_decl, suboff); + else + ret = fold_nonarray_ctor_reference (type, ctor, offset, size, + from_decl, suboff); + + /* Fall back to native_encode_initializer. Needs to be done + only in the outermost fold_ctor_reference call (because it itself + recurses into CONSTRUCTORs) and doesn't update suboff. */ + if (ret == NULL_TREE + && suboff == &dummy + && BITS_PER_UNIT == 8 + && offset % BITS_PER_UNIT == 0 + && offset / BITS_PER_UNIT <= INT_MAX + && size % BITS_PER_UNIT == 0 + && size <= MAX_BITSIZE_MODE_ANY_MODE + && can_native_interpret_type_p (type)) + { + unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT]; + int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT, + offset / BITS_PER_UNIT); + if (len > 0) + return native_interpret_expr (type, buf, len); + } - return fold_nonarray_ctor_reference (type, ctor, offset, size, - from_decl, suboff); + return ret; } return NULL_TREE; @@ -7049,7 +7073,7 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree)) tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize); if (c && TREE_CODE (c) == COMPLEX_CST) return fold_build1_loc (EXPR_LOCATION (t), - TREE_CODE (t), TREE_TYPE (t), c); + TREE_CODE (t), TREE_TYPE (t), c); break; } |