[PATCH] MEM = "abcd" expansion improvements

Jakub Jelinek jakub@redhat.com
Mon Oct 11 20:42:00 GMT 2010


Hi!

This patch slightly cleans up MEM = STRING_CST and MEM = MEM_REF<&STRING_CST, 0>
expansion by sharing the code for STRING_CST and MEM_REF<&STRING_CST, 0>
and allows it even for non-BLKmode mode - e.g. for "abcd" the mode
is SImode, but as long as target is MEM it is desirable to optimize it
using store_by_pieces.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-10-11  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.

--- gcc/expr.c.jj	2010-10-11 07:51:09.000000000 +0200
+++ gcc/expr.c	2010-10-11 13:46:05.000000000 +0200
@@ -4636,62 +4636,26 @@ store_expr (tree exp, rtx target, int ca
 
       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 ca
 	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 ca
 
       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)

	Jakub



More information about the Gcc-patches mailing list