This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] use movstr in strcat


On Thu, Aug 25, 2005 at 10:46:26AM -0700, Richard Henderson wrote:
> On Thu, Aug 25, 2005 at 01:12:18PM +0200, Adrian Straetling wrote:
> > 	* builtins.c: (expand_builtin_strcat): Add support for
> > 	expand_movstr.
> 
> You're duplicating a lot of code here.  It seems to me the best
> way to approach this is to start a sequence, build the strlen
> addition, and then defer to expand_builtin_strcpy.  If the
> expansion of the strcpy fails, abort the sequence.  You may have
> to play games like in expand_builtin_mathfn_2 in order to reliably
> stabilize the arguments.
Thank you for the quick review and pointing at the right place to look at.
You'll find updated patch below.

I've changed the prototype of expand_builtin_strcpy to avoid the packing and
unpacking of exp.

A quick test showed no problems with builtin.exp, bootstrap is currently running.
I'll repost the patch with a changelog tomorrow if testing looks fine and there
are no other objections.

regards,
Adrian

Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c.orig	2005-08-24 09:34:50.000000000 +0200
--- gcc/builtins.c	2005-08-25 23:02:57.000000000 +0200
*************** static rtx expand_builtin_memcpy (tree, 
*** 113,119 ****
  static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
  static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
  static rtx expand_builtin_bcopy (tree);
! static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
  static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
  static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
  static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
--- 113,119 ----
  static rtx expand_builtin_mempcpy (tree, tree, rtx, enum machine_mode, int);
  static rtx expand_builtin_memmove (tree, tree, rtx, enum machine_mode, tree);
  static rtx expand_builtin_bcopy (tree);
! static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
  static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
  static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
  static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
*************** expand_movstr (tree dest, tree src, rtx 
*** 3087,3096 ****
     convenient).  */
  
  static rtx
! expand_builtin_strcpy (tree exp, rtx target, enum machine_mode mode)
  {
-   tree fndecl = get_callee_fndecl (exp);
-   tree arglist = TREE_OPERAND (exp, 1);
    if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      {
        tree result = fold_builtin_strcpy (fndecl, arglist, 0);
--- 3087,3094 ----
     convenient).  */
  
  static rtx
! expand_builtin_strcpy (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
  {
    if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      {
        tree result = fold_builtin_strcpy (fndecl, arglist, 0);
*************** expand_builtin_stpcpy (tree exp, rtx tar
*** 3159,3165 ****
  
  	  if (GET_CODE (len_rtx) == CONST_INT)
  	    {
! 	      ret = expand_builtin_strcpy (exp, target, mode);
  
  	      if (ret)
  		{
--- 3157,3164 ----
  
  	  if (GET_CODE (len_rtx) == CONST_INT)
  	    {
! 	      ret = expand_builtin_strcpy (get_callee_fndecl (exp), 
! 					   arglist, target, mode);
  
  	      if (ret)
  		{
*************** expand_builtin_strncmp (tree exp, rtx ta
*** 3825,3885 ****
     otherwise try to get the result in TARGET, if convenient.  */
  
  static rtx
! expand_builtin_strcat (tree arglist, tree type, rtx target, enum machine_mode mode)
  {
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      return 0;
    else
      {
        tree dst = TREE_VALUE (arglist),
! 	src = TREE_VALUE (TREE_CHAIN (arglist));
        const char *p = c_getstr (src);
  
!       if (p)
  	{
! 	  /* If the string length is zero, return the dst parameter.  */
! 	  if (*p == '\0')
! 	    return expand_expr (dst, target, mode, EXPAND_NORMAL);
! 	  else if (!optimize_size)
! 	    {
! 	      /* Otherwise if !optimize_size, see if we can store by
!                  pieces into (dst + strlen(dst)).  */
! 	      tree newdst, arglist,
! 		strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
! 
! 	      /* This is the length argument.  */
! 	      arglist = build_tree_list (NULL_TREE,
! 					 fold (size_binop (PLUS_EXPR,
! 							   c_strlen (src, 0),
! 							   ssize_int (1))));
! 	      /* Prepend src argument.  */
! 	      arglist = tree_cons (NULL_TREE, src, arglist);
  
! 	      /* We're going to use dst more than once.  */
! 	      dst = builtin_save_expr (dst);
  
! 	      /* Create strlen (dst).  */
! 	      newdst =
! 		build_function_call_expr (strlen_fn,
! 					  build_tree_list (NULL_TREE, dst));
! 	      /* Create (dst + (cast) strlen (dst)).  */
! 	      newdst = fold_convert (TREE_TYPE (dst), newdst);
! 	      newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
! 
! 	      /* Prepend the new dst argument.  */
! 	      arglist = tree_cons (NULL_TREE, newdst, arglist);
! 
! 	      /* We don't want to get turned into a memcpy if the
!                  target is const0_rtx, i.e. when the return value
!                  isn't used.  That would produce pessimized code so
!                  pass in a target of zero, it should never actually be
!                  used.  If this was successful return the original
!                  dst, not the result of mempcpy.  */
! 	      if (expand_builtin_mempcpy (arglist, type, /*target=*/0, mode, /*endp=*/0))
! 		return expand_expr (dst, target, mode, EXPAND_NORMAL);
! 	      else
! 		return 0;
  	    }
  	}
  
        return 0;
--- 3824,3884 ----
     otherwise try to get the result in TARGET, if convenient.  */
  
  static rtx
! expand_builtin_strcat (tree fndecl, tree arglist, rtx target, enum machine_mode mode)
  {
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      return 0;
    else
      {
        tree dst = TREE_VALUE (arglist),
!       src = TREE_VALUE (TREE_CHAIN (arglist));
        const char *p = c_getstr (src);
  
!       /* If the string length is zero, return the dst parameter.  */
!       if (p && *p == '\0')	  
! 	return expand_expr (dst, target, mode, EXPAND_NORMAL);
!       
!       if (!optimize_size)
  	{
! 	  /* See if we can store by pieces into (dst + strlen(dst)).  */
! 	  tree newsrc, newdst,
! 	    strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
! 	  rtx insns;
! 
! 	  /* Stabilize the argument list.  */
! 	  newsrc = builtin_save_expr (src);
! 	  if (newsrc != src)
! 	    arglist = build_tree_list (NULL_TREE, newsrc);
! 	  else 
! 	    arglist = TREE_CHAIN (arglist); /* Reusing arglist if safe.  */
! 
! 	  dst = builtin_save_expr (dst);
! 
! 	  start_sequence ();
! 
! 	  /* Create strlen (dst).  */
! 	  newdst =
! 	    build_function_call_expr (strlen_fn,
! 				      build_tree_list (NULL_TREE, dst));
! 	  /* Create (dst + (cast) strlen (dst)).  */
! 	  newdst = fold_convert (TREE_TYPE (dst), newdst);
! 	  newdst = fold_build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
  
! 	  newdst = builtin_save_expr (newdst);
! 	  arglist = tree_cons (NULL_TREE, newdst, arglist);
  
! 	  if (!expand_builtin_strcpy (fndecl, arglist, target, mode))
! 	    {
! 	      end_sequence (); /* Stop sequence.  */
! 	      return 0;
  	    }
+ 	  
+ 	  /* Output the entire sequence.  */
+ 	  insns = get_insns ();
+ 	  end_sequence ();
+ 	  emit_insn (insns);
+ 	  
+ 	  return expand_expr (dst, target, mode, EXPAND_NORMAL);
  	}
  
        return 0;
*************** expand_builtin (tree exp, rtx target, rt
*** 5828,5834 ****
        break;
  
      case BUILT_IN_STRCPY:
!       target = expand_builtin_strcpy (exp, target, mode);
        if (target)
  	return target;
        break;
--- 5827,5833 ----
        break;
  
      case BUILT_IN_STRCPY:
!       target = expand_builtin_strcpy (fndecl, arglist, target, mode);
        if (target)
  	return target;
        break;
*************** expand_builtin (tree exp, rtx target, rt
*** 5846,5852 ****
        break;
  
      case BUILT_IN_STRCAT:
!       target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
        if (target)
  	return target;
        break;
--- 5845,5851 ----
        break;
  
      case BUILT_IN_STRCAT:
!       target = expand_builtin_strcat (fndecl, arglist, target, mode);
        if (target)
  	return target;
        break;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]