diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20f20df5238..8d8bb3a1571 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2010-10-12 Jakub Jelinek <jakub@redhat.com> + * expr.c (store_expr): Share code for STRING_CST and + MEM_REF of &STRING_CST cases. Don't require BLKmode, instead + check if target is a MEM. + * rtl.h: Include hashtab.h. (iterative_hash_rtx): New prototype. * rtl.c (iterative_hash_rtx): New function. diff --git a/gcc/expr.c b/gcc/expr.c index 291b79f4bd2..b0c160f9367 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4636,62 +4636,26 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) return NULL_RTX; } - else if (TREE_CODE (exp) == STRING_CST + else if ((TREE_CODE (exp) == STRING_CST + || (TREE_CODE (exp) == MEM_REF + && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) + == STRING_CST + && integer_zerop (TREE_OPERAND (exp, 1)))) && !nontemporal && !call_param_p - && TREE_STRING_LENGTH (exp) > 0 - && TYPE_MODE (TREE_TYPE (exp)) == BLKmode) + && MEM_P (target)) { /* Optimize initialization of an array with a STRING_CST. */ HOST_WIDE_INT exp_len, str_copy_len; rtx dest_mem; + tree str = TREE_CODE (exp) == STRING_CST + ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0); exp_len = int_expr_size (exp); if (exp_len <= 0) goto normal_expr; - str_copy_len = strlen (TREE_STRING_POINTER (exp)); - if (str_copy_len < TREE_STRING_LENGTH (exp) - 1) - goto normal_expr; - - str_copy_len = TREE_STRING_LENGTH (exp); - if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0) - { - str_copy_len += STORE_MAX_PIECES - 1; - str_copy_len &= ~(STORE_MAX_PIECES - 1); - } - str_copy_len = MIN (str_copy_len, exp_len); - if (!can_store_by_pieces (str_copy_len, builtin_strncpy_read_str, - CONST_CAST(char *, TREE_STRING_POINTER (exp)), - MEM_ALIGN (target), false)) - goto normal_expr; - - dest_mem = target; - - dest_mem = store_by_pieces (dest_mem, - str_copy_len, builtin_strncpy_read_str, - CONST_CAST(char *, TREE_STRING_POINTER (exp)), - MEM_ALIGN (target), false, - exp_len > str_copy_len ? 1 : 0); - if (exp_len > str_copy_len) - clear_storage (adjust_address (dest_mem, BLKmode, 0), - GEN_INT (exp_len - str_copy_len), - BLOCK_OP_NORMAL); - return NULL_RTX; - } - else if (TREE_CODE (exp) == MEM_REF - && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) == STRING_CST - && integer_zerop (TREE_OPERAND (exp, 1)) - && !nontemporal && !call_param_p - && TYPE_MODE (TREE_TYPE (exp)) == BLKmode) - { - /* Optimize initialization of an array with a STRING_CST. */ - HOST_WIDE_INT exp_len, str_copy_len; - rtx dest_mem; - tree str = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); - - exp_len = int_expr_size (exp); - if (exp_len <= 0) + if (TREE_STRING_LENGTH (str) <= 0) goto normal_expr; str_copy_len = strlen (TREE_STRING_POINTER (str)); @@ -4699,14 +4663,15 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) goto normal_expr; str_copy_len = TREE_STRING_LENGTH (str); - if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0) + if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0 + && TREE_STRING_POINTER (str)[TREE_STRING_LENGTH (str) - 1] == '\0') { str_copy_len += STORE_MAX_PIECES - 1; str_copy_len &= ~(STORE_MAX_PIECES - 1); } str_copy_len = MIN (str_copy_len, exp_len); if (!can_store_by_pieces (str_copy_len, builtin_strncpy_read_str, - CONST_CAST(char *, TREE_STRING_POINTER (str)), + CONST_CAST (char *, TREE_STRING_POINTER (str)), MEM_ALIGN (target), false)) goto normal_expr; @@ -4714,7 +4679,8 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) dest_mem = store_by_pieces (dest_mem, str_copy_len, builtin_strncpy_read_str, - CONST_CAST(char *, TREE_STRING_POINTER (str)), + CONST_CAST (char *, + TREE_STRING_POINTER (str)), MEM_ALIGN (target), false, exp_len > str_copy_len ? 1 : 0); if (exp_len > str_copy_len)