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/dwarf2out.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/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 146 |
1 files changed, 1 insertions, 145 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d0dee48..70b3fad 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -20258,150 +20258,6 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p) return tree_add_const_value_attribute_for_decl (die, decl); } -/* Helper function for tree_add_const_value_attribute. Natively encode - initializer INIT into an array. Return true if successful. */ - -static bool -native_encode_initializer (tree init, unsigned char *array, int size) -{ - tree type; - - if (init == NULL_TREE) - return false; - - STRIP_NOPS (init); - switch (TREE_CODE (init)) - { - case STRING_CST: - type = TREE_TYPE (init); - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree enttype = TREE_TYPE (type); - scalar_int_mode mode; - - if (!is_int_mode (TYPE_MODE (enttype), &mode) - || GET_MODE_SIZE (mode) != 1) - return false; - if (int_size_in_bytes (type) != size) - return false; - if (size > TREE_STRING_LENGTH (init)) - { - memcpy (array, TREE_STRING_POINTER (init), - TREE_STRING_LENGTH (init)); - memset (array + TREE_STRING_LENGTH (init), - '\0', size - TREE_STRING_LENGTH (init)); - } - else - memcpy (array, TREE_STRING_POINTER (init), size); - return true; - } - return false; - case CONSTRUCTOR: - type = TREE_TYPE (init); - if (int_size_in_bytes (type) != size) - return false; - if (TREE_CODE (type) == ARRAY_TYPE) - { - HOST_WIDE_INT min_index; - unsigned HOST_WIDE_INT cnt; - int curpos = 0, fieldsize; - constructor_elt *ce; - - if (TYPE_DOMAIN (type) == NULL_TREE - || !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type)))) - return false; - - fieldsize = int_size_in_bytes (TREE_TYPE (type)); - if (fieldsize <= 0) - return false; - - min_index = tree_to_shwi (TYPE_MIN_VALUE (TYPE_DOMAIN (type))); - memset (array, '\0', size); - FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce) - { - tree val = ce->value; - tree index = ce->index; - int pos = curpos; - if (index && TREE_CODE (index) == RANGE_EXPR) - pos = (tree_to_shwi (TREE_OPERAND (index, 0)) - min_index) - * fieldsize; - else if (index) - pos = (tree_to_shwi (index) - min_index) * fieldsize; - - if (val) - { - STRIP_NOPS (val); - if (!native_encode_initializer (val, array + pos, fieldsize)) - return false; - } - curpos = pos + fieldsize; - if (index && TREE_CODE (index) == RANGE_EXPR) - { - int count = tree_to_shwi (TREE_OPERAND (index, 1)) - - tree_to_shwi (TREE_OPERAND (index, 0)); - while (count-- > 0) - { - if (val) - memcpy (array + curpos, array + pos, fieldsize); - curpos += fieldsize; - } - } - gcc_assert (curpos <= size); - } - return true; - } - else if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - { - tree field = NULL_TREE; - unsigned HOST_WIDE_INT cnt; - constructor_elt *ce; - - if (int_size_in_bytes (type) != size) - return false; - - if (TREE_CODE (type) == RECORD_TYPE) - field = TYPE_FIELDS (type); - - FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (init), cnt, ce) - { - tree val = ce->value; - int pos, fieldsize; - - if (ce->index != 0) - field = ce->index; - - if (val) - STRIP_NOPS (val); - - if (field == NULL_TREE || DECL_BIT_FIELD (field)) - return false; - - if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE - && TYPE_DOMAIN (TREE_TYPE (field)) - && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field)))) - return false; - else if (DECL_SIZE_UNIT (field) == NULL_TREE - || !tree_fits_shwi_p (DECL_SIZE_UNIT (field))) - return false; - fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field)); - pos = int_byte_position (field); - gcc_assert (pos + fieldsize <= size); - if (val && fieldsize != 0 - && !native_encode_initializer (val, array + pos, fieldsize)) - return false; - } - return true; - } - return false; - case VIEW_CONVERT_EXPR: - case NON_LVALUE_EXPR: - return native_encode_initializer (TREE_OPERAND (init, 0), array, size); - default: - return native_encode_expr (init, array, size) == size; - } -} - /* Attach a DW_AT_const_value attribute to DIE. The value of the attribute is the const value T. */ @@ -20446,7 +20302,7 @@ tree_add_const_value_attribute (dw_die_ref die, tree t) { unsigned char *array = ggc_cleared_vec_alloc<unsigned char> (size); - if (native_encode_initializer (init, array, size)) + if (native_encode_initializer (init, array, size) == size) { add_AT_vec (die, DW_AT_const_value, size, 1, array); return true; |