public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Unify fold_builtin and simplify_builtin APIs
@ 2004-07-05  6:03 Roger Sayle
  2004-07-08  4:45 ` Richard Henderson
  0 siblings, 1 reply; 2+ messages in thread
From: Roger Sayle @ 2004-07-05  6:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law


The following patch is the necessary prerequisite to eliminating
the duplication between fold_builtin_foo and simplify_builtin_foo
in builtins.c.  This first step unifies the "external" APIs from
builtins.c, such that once applied simplify_builtin and fold_builtin
take the same paramaters, and all calls outside of builtins.c to
simplify_builtin_foo are replaced with calls to fold_builtin_foo.

The only simplify_builtin functions used outside of builtins.c,
are simplify_builtin_strcpy, simplify_builtin_strncpy and
simplify_builtin_fputs.  The first step of this patch is to
either rename these functions, or integrate their functionality
into their existing fold_builtin_* equivalents, and then export
these fold_builtin_* variants instead.  The original external
simplify_builtin_* entry points are deleted and all callers are
updated.

The second part is that simplify_builtin currently takes an extra
argument that fold_builtin doesn't; a parameter indicating whether
the result of the tree will be ignored or not.  To provide the
superset of this functionality a "bool ignore" parameter is also
added to fold_builtin, and all of its callers are updated.

Now that tree-ssa-ccp.c has been updated to check whether the
result from calling fold_builtin is gimple (the only non-fold
caller of this function), there's no remaining distinction between
fold_builtin and simplify_builtin other than the transformations
performed by each.


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with
a top-level "make -k check" with no new failures.

Ok for mainline?



2004-06-03  Roger Sayle  <roger@eyesopen.com>

	* builtins.c (fold_builtin_strcpy): Merge functionality from
	simplify_builtin_strcpy.  Add additional len argument.  No longer
	static.  Remove function prototype.
	(fold_builtin_strncpy): Likewise integrate functionality from
	simplify_builtin_strncpy.  Add additional slen argument.  No
	longer static.  Remove function prototype.
	(simplify_builtin_strcy, simplify_builtin_strncpy): Delete.
	(simplify_builtin_fputs): Rename to fold_builtin_fputs.  Change
	types of "ignore" and "unlocked" parameters to bool.
	(fold_builtin_1):  Add additional ignore argument.  Call renamed
	fold_builtin_fputs to simplify GCC "fputs" and "fputs_unlocked"
	builtins.  Update arguments to fold_builtin_strncpy and
	fold_builtin_strcpy.  Add function prototype.
	(fold_builtin): Add additional Boolean ignore argument to pass
	to fold_builtin_1.
	(simplify_builtin): Call fold_builtin_fputs, fold_builtin_strcpy
	and fold_builtin_strncpy instead of simplify_builtin_fputs,
	simplify_builtin_strcpy and simplify_builtin_strncpy respectively.

	* expr.h (simplify_builtin_fputs, simplify_builtin_strcpy,
	simplify_builtin_strncpy): Delete function prototypes.
	* tree.h (fold_builtin_fputs, fold_builtin_strcpy,
	fold_builtin_strncpy): Add function prototypes here.
	(fold_builtin): Update function prototype with new "bool ignore".

	* tree-ssa-ccp.c (ccp_fold): Update call to fold_builtin.
	(ccp_fold_builtin):  Update call to fold_builtin.  Call
	fold_builtin_fputs, fold_builtin_strcpy and fold_builtin_strncpy
	instead of simplify_builtin_fputs, simplify_builtin_strcpy and
	simplify_builtin_strncpy respectively.
	* fold-const.c (fold) Update call to fold_builtin.


Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.346
diff -c -3 -p -r1.346 builtins.c
*** builtins.c	1 Jul 2004 12:52:33 -0000	1.346
--- builtins.c	5 Jul 2004 02:29:08 -0000
*************** static tree fold_builtin_bitop (tree);
*** 156,163 ****
  static tree fold_builtin_memcpy (tree);
  static tree fold_builtin_mempcpy (tree);
  static tree fold_builtin_memmove (tree);
- static tree fold_builtin_strcpy (tree);
- static tree fold_builtin_strncpy (tree);
  static tree fold_builtin_strchr (tree, bool);
  static tree fold_builtin_memcmp (tree);
  static tree fold_builtin_strcmp (tree);
--- 156,161 ----
*************** static tree fold_builtin_isdigit (tree);
*** 170,175 ****
--- 168,174 ----
  static tree fold_builtin_fabs (tree, tree);
  static tree fold_builtin_abs (tree, tree);
  static tree fold_builtin_unordered_cmp (tree, enum tree_code, enum tree_code);
+ static tree fold_builtin_1 (tree, bool);

  static tree simplify_builtin_memcmp (tree);
  static tree simplify_builtin_strcmp (tree);
*************** fold_builtin_memmove (tree exp)
*** 7209,7222 ****
    return 0;
  }

! /* Fold function call to builtin strcpy.  Return
!    NULL_TREE if no simplification can be made.  */

! static tree
! fold_builtin_strcpy (tree exp)
  {
    tree arglist = TREE_OPERAND (exp, 1);
!   tree dest, src;

    if (!validate_arglist (arglist,
  			 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
--- 7208,7222 ----
    return 0;
  }

! /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
!    the length of the string to be copied.  Return NULL_TREE if no
!    simplification can be made.  */

! tree
! fold_builtin_strcpy (tree exp, tree len)
  {
    tree arglist = TREE_OPERAND (exp, 1);
!   tree dest, src, fn;

    if (!validate_arglist (arglist,
  			 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
*************** fold_builtin_strcpy (tree exp)
*** 7229,7245 ****
    if (operand_equal_p (src, dest, 0))
      return fold_convert (TREE_TYPE (exp), dest);

!   return 0;
  }

! /* Fold function call to builtin strncpy.  Return
!    NULL_TREE if no simplification can be made.  */

! static tree
! fold_builtin_strncpy (tree exp)
  {
    tree arglist = TREE_OPERAND (exp, 1);
!   tree dest, src, len;

    if (!validate_arglist (arglist,
  			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
--- 7229,7265 ----
    if (operand_equal_p (src, dest, 0))
      return fold_convert (TREE_TYPE (exp), dest);

!   if (optimize_size)
!     return 0;
!
!   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
!   if (!fn)
!     return 0;
!
!   if (!len)
!     {
!       len = c_strlen (src, 1);
!       if (! len || TREE_SIDE_EFFECTS (len))
! 	return 0;
!     }
!
!   len = size_binop (PLUS_EXPR, len, ssize_int (1));
!   arglist = build_tree_list (NULL_TREE, len);
!   arglist = tree_cons (NULL_TREE, src, arglist);
!   arglist = tree_cons (NULL_TREE, dest, arglist);
!   return fold_convert (TREE_TYPE (exp),
! 		       build_function_call_expr (fn, arglist));
  }

! /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
!    the length of the source string.  Return NULL_TREE if no simplification
!    can be made.  */

! tree
! fold_builtin_strncpy (tree exp, tree slen)
  {
    tree arglist = TREE_OPERAND (exp, 1);
!   tree dest, src, len, fn;

    if (!validate_arglist (arglist,
  			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
*************** fold_builtin_strncpy (tree exp)
*** 7253,7259 ****
    if (integer_zerop (len))
      return omit_one_operand (TREE_TYPE (exp), dest, src);

!   return 0;
  }

  /* Fold function call to builtin strchr and strrchr.
--- 7273,7299 ----
    if (integer_zerop (len))
      return omit_one_operand (TREE_TYPE (exp), dest, src);

!   if (!slen)
!     slen = c_strlen (src, 1);
!
!   /* Now, we must be passed a constant src ptr parameter.  */
!   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
!     return 0;
!
!   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
!
!   /* We do not support simplification of this case, though we do
!      support it when expanding trees into RTL.  */
!   /* FIXME: generate a call to __builtin_memset.  */
!   if (tree_int_cst_lt (slen, len))
!     return 0;
!
!   /* OK transform into builtin memcpy.  */
!   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
!   if (!fn)
!     return 0;
!   return fold_convert (TREE_TYPE (exp),
! 		       build_function_call_expr (fn, arglist));
  }

  /* Fold function call to builtin strchr and strrchr.
*************** fold_builtin_unordered_cmp (tree exp,
*** 7781,7791 ****
  		       fold (build2 (code, type, arg0, arg1))));
  }

! /* Used by constant folding to eliminate some builtin calls early.  EXP is
!    the CALL_EXPR of a call to a builtin function.  */

  static tree
! fold_builtin_1 (tree exp)
  {
    tree fndecl = get_callee_fndecl (exp);
    tree arglist = TREE_OPERAND (exp, 1);
--- 7821,7833 ----
  		       fold (build2 (code, type, arg0, arg1))));
  }

! /* Used by constant folding to simplify calls to builtin functions.  EXP is
!    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
!    result of the function call is ignored.  This function returns NULL_TREE
!    if no simplification was possible.  */

  static tree
! fold_builtin_1 (tree exp, bool ignore)
  {
    tree fndecl = get_callee_fndecl (exp);
    tree arglist = TREE_OPERAND (exp, 1);
*************** fold_builtin_1 (tree exp)
*** 8292,8301 ****
        return fold_builtin_memmove (exp);

      case BUILT_IN_STRCPY:
!       return fold_builtin_strcpy (exp);

      case BUILT_IN_STRNCPY:
!       return fold_builtin_strncpy (exp);

      case BUILT_IN_INDEX:
      case BUILT_IN_STRCHR:
--- 8334,8343 ----
        return fold_builtin_memmove (exp);

      case BUILT_IN_STRCPY:
!       return fold_builtin_strcpy (exp, NULL_TREE);

      case BUILT_IN_STRNCPY:
!       return fold_builtin_strncpy (exp, NULL_TREE);

      case BUILT_IN_INDEX:
      case BUILT_IN_STRCHR:
*************** fold_builtin_1 (tree exp)
*** 8361,8366 ****
--- 8403,8414 ----
      case BUILT_IN_ISUNORDERED:
        return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);

+     case BUILT_IN_FPUTS:
+       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
+
+     case BUILT_IN_FPUTS_UNLOCKED:
+       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
+
      default:
        break;
      }
*************** fold_builtin_1 (tree exp)
*** 8373,8381 ****
     call node earlier than the warning is generated.  */

  tree
! fold_builtin (tree exp)
  {
!   exp = fold_builtin_1 (exp);
    if (exp)
      {
        /* ??? Don't clobber shared nodes such as integer_zero_node.  */
--- 8421,8429 ----
     call node earlier than the warning is generated.  */

  tree
! fold_builtin (tree exp, bool ignore)
  {
!   exp = fold_builtin_1 (exp, ignore);
    if (exp)
      {
        /* ??? Don't clobber shared nodes such as integer_zero_node.  */
*************** simplify_builtin (tree exp, int ignore)
*** 8509,8518 ****
    switch (fcode)
      {
      case BUILT_IN_FPUTS:
!       val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
        break;
      case BUILT_IN_FPUTS_UNLOCKED:
!       val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
        break;
      case BUILT_IN_STRSTR:
        val = simplify_builtin_strstr (arglist);
--- 8557,8566 ----
    switch (fcode)
      {
      case BUILT_IN_FPUTS:
!       val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
        break;
      case BUILT_IN_FPUTS_UNLOCKED:
!       val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
        break;
      case BUILT_IN_STRSTR:
        val = simplify_builtin_strstr (arglist);
*************** simplify_builtin (tree exp, int ignore)
*** 8538,8547 ****
        val = simplify_builtin_strrchr (arglist);
        break;
      case BUILT_IN_STRCPY:
!       val = simplify_builtin_strcpy (arglist, NULL_TREE);
        break;
      case BUILT_IN_STRNCPY:
!       val = simplify_builtin_strncpy (arglist, NULL_TREE);
        break;
      case BUILT_IN_STRCMP:
        val = simplify_builtin_strcmp (arglist);
--- 8586,8595 ----
        val = simplify_builtin_strrchr (arglist);
        break;
      case BUILT_IN_STRCPY:
!       val = fold_builtin_strcpy (exp, NULL_TREE);
        break;
      case BUILT_IN_STRNCPY:
!       val = fold_builtin_strncpy (exp, NULL_TREE);
        break;
      case BUILT_IN_STRCMP:
        val = simplify_builtin_strcmp (arglist);
*************** simplify_builtin_strpbrk (tree arglist)
*** 8831,8945 ****
      }
  }

- /* Simplify a call to the strcpy builtin.
-
-    Return 0 if no simplification was possible, otherwise return the
-    simplified form of the call as a tree.
-
-    The simplified form may be a constant or other expression which
-    computes the same value, but in a more efficient manner (including
-    calls to other builtin functions).
-
-    The call may contain arguments which need to be evaluated, but
-    which are not useful to determine the result of the call.  In
-    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
-    COMPOUND_EXPR will be an argument which must be evaluated.
-    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
-    COMPOUND_EXPR in the chain will contain the tree for the simplified
-    form of the builtin function call.  */
-
- tree
- simplify_builtin_strcpy (tree arglist, tree len)
- {
-   tree fn, src, dst;
-
-   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
-     return 0;
-
-   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
-   if (!fn)
-     return 0;
-
-   src = TREE_VALUE (TREE_CHAIN (arglist));
-   dst = TREE_VALUE (arglist);
-
-   if (!len)
-     {
-       len = c_strlen (src, 1);
-       if (!len || TREE_SIDE_EFFECTS (len))
- 	return 0;
-     }
-
-   len = size_binop (PLUS_EXPR, len, ssize_int (1));
-   arglist = build_tree_list (NULL_TREE, len);
-   arglist = tree_cons (NULL_TREE, src, arglist);
-   arglist = tree_cons (NULL_TREE, dst, arglist);
-   return build_function_call_expr (fn, arglist);
- }
-
- /* Simplify a call to the strncpy builtin.
-
-    Return 0 if no simplification was possible, otherwise return the
-    simplified form of the call as a tree.
-
-    The simplified form may be a constant or other expression which
-    computes the same value, but in a more efficient manner (including
-    calls to other builtin functions).
-
-    The call may contain arguments which need to be evaluated, but
-    which are not useful to determine the result of the call.  In
-    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
-    COMPOUND_EXPR will be an argument which must be evaluated.
-    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
-    COMPOUND_EXPR in the chain will contain the tree for the simplified
-    form of the builtin function call.  */
-
- tree
- simplify_builtin_strncpy (tree arglist, tree slen)
- {
-   if (!validate_arglist (arglist,
- 			 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
-     return 0;
-   else
-     {
-       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
-       tree fn;
-
-       /* We must be passed a constant len parameter.  */
-       if (TREE_CODE (len) != INTEGER_CST)
- 	return 0;
-
-       /* If the len parameter is zero, return the dst parameter.  */
-       if (integer_zerop (len))
- 	/* Evaluate and ignore the src argument in case it has
- 	   side-effects and return the dst parameter.  */
- 	return omit_one_operand (TREE_TYPE (TREE_VALUE (arglist)),
- 				 TREE_VALUE (arglist),
- 				 TREE_VALUE (TREE_CHAIN (arglist)));
-
-       if (!slen)
-         slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 0);
-
-       /* Now, we must be passed a constant src ptr parameter.  */
-       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
- 	return 0;
-
-       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
-
-       /* We do not support simplification of this case, though we do
-          support it when expanding trees into RTL.  */
-       /* FIXME: generate a call to __builtin_memset.  */
-       if (tree_int_cst_lt (slen, len))
- 	return 0;
-
-       /* OK transform into builtin memcpy.  */
-       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
-       if (!fn)
- 	return 0;
-       return build_function_call_expr (fn, arglist);
-     }
- }
-
  /* Simplify a call to the memcmp builtin.

     Return 0 if no simplification was possible, otherwise return the
--- 8879,8884 ----
*************** simplify_builtin_strcspn (tree arglist)
*** 9349,9379 ****
      }
  }

! /* Simplify a call to the fputs builtin.
!
!    Return 0 if no simplification was possible, otherwise return the
!    simplified form of the call as a tree.
!
!    The simplified form may be a constant or other expression which
!    computes the same value, but in a more efficient manner (including
!    calls to other builtin functions).
!
!    The call may contain arguments which need to be evaluated, but
!    which are not useful to determine the result of the call.  In
!    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
!    COMPOUND_EXPR will be an argument which must be evaluated.
!    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
!    COMPOUND_EXPR in the chain will contain the tree for the simplified
!    form of the builtin function call.
!
!    If KNOWN_LEN is non-NULL, it represents the known length of the string.
!    This is determined by SSA-CCP in cases where the string itself is not
!    known to be constant but its length is always the same constant.  */

  tree
! simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
  {
!   tree len, fn;
    tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
      : implicit_built_in_decls[BUILT_IN_FPUTC];
    tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
--- 9288,9303 ----
      }
  }

! /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
!    by the builtin will be ignored.  UNLOCKED is true is true if this
!    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
!    the known length of the string.  Return NULL_TREE if no simplification
!    was possible.  */

  tree
! fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
  {
!   tree fn;
    tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
      : implicit_built_in_decls[BUILT_IN_FPUTC];
    tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
*************** simplify_builtin_fputs (tree arglist, in
*** 9388,9394 ****
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      return 0;

!   len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 0);

    /* Get the length of the string passed to fputs.  If the length
       can't be determined, punt.  */
--- 9312,9319 ----
    if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
      return 0;

!   if (! len)
!     len = c_strlen (TREE_VALUE (arglist), 0);

    /* Get the length of the string passed to fputs.  If the length
       can't be determined, punt.  */
*************** simplify_builtin_fputs (tree arglist, in
*** 9412,9419 ****
  	       fputc(string[0], stream).  */
  	    arglist =
  	      build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
! 	    arglist =
! 	      tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
  	    fn = fn_fputc;
  	    break;
  	  }
--- 9337,9343 ----
  	       fputc(string[0], stream).  */
  	    arglist =
  	      build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
! 	    arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
  	    fn = fn_fputc;
  	    break;
  	  }
*************** simplify_builtin_fputs (tree arglist, in
*** 9429,9435 ****
  	string_arg = TREE_VALUE (arglist);
  	/* New argument list transforming fputs(string, stream) to
  	   fwrite(string, 1, len, stream).  */
! 	arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
  	arglist = tree_cons (NULL_TREE, len, arglist);
  	arglist = tree_cons (NULL_TREE, size_one_node, arglist);
  	arglist = tree_cons (NULL_TREE, string_arg, arglist);
--- 9353,9360 ----
  	string_arg = TREE_VALUE (arglist);
  	/* New argument list transforming fputs(string, stream) to
  	   fwrite(string, 1, len, stream).  */
! 	arglist = build_tree_list (NULL_TREE,
! 				   TREE_VALUE (TREE_CHAIN (arglist)));
  	arglist = tree_cons (NULL_TREE, len, arglist);
  	arglist = tree_cons (NULL_TREE, size_one_node, arglist);
  	arglist = tree_cons (NULL_TREE, string_arg, arglist);
*************** simplify_builtin_fputs (tree arglist, in
*** 9440,9446 ****
        abort ();
      }

!   return build_function_call_expr (fn, arglist);
  }

  static void
--- 9365,9372 ----
        abort ();
      }

!   return fold_convert (integer_type_node,
! 		       build_function_call_expr (fn, arglist));
  }

  static void
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.159
diff -c -3 -p -r1.159 expr.h
*** expr.h	24 Jun 2004 13:47:49 -0000	1.159
--- expr.h	5 Jul 2004 02:29:08 -0000
*************** extern void expand_builtin_setjmp_receiv
*** 377,385 ****
  extern void expand_builtin_longjmp (rtx, rtx);
  extern rtx expand_builtin_saveregs (void);
  extern void expand_builtin_trap (void);
- extern tree simplify_builtin_fputs (tree, int, int, tree);
- extern tree simplify_builtin_strcpy (tree, tree);
- extern tree simplify_builtin_strncpy (tree, tree);

  /* Functions from expr.c:  */

--- 377,382 ----
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.539
diff -c -3 -p -r1.539 tree.h
*** tree.h	4 Jul 2004 08:06:55 -0000	1.539
--- tree.h	5 Jul 2004 02:29:09 -0000
*************** extern bool tree_swap_operands_p (tree,
*** 3413,3419 ****
  extern enum tree_code swap_tree_comparison (enum tree_code);

  /* In builtins.c */
! extern tree fold_builtin (tree);
  extern enum built_in_function builtin_mathfn_code (tree);
  extern tree build_function_call_expr (tree, tree);
  extern tree mathfn_built_in (tree, enum built_in_function fn);
--- 3413,3422 ----
  extern enum tree_code swap_tree_comparison (enum tree_code);

  /* In builtins.c */
! extern tree fold_builtin (tree, bool);
! extern tree fold_builtin_fputs (tree, bool, bool, tree);
! extern tree fold_builtin_strcpy (tree, tree);
! extern tree fold_builtin_strncpy (tree, tree);
  extern enum built_in_function builtin_mathfn_code (tree);
  extern tree build_function_call_expr (tree, tree);
  extern tree mathfn_built_in (tree, enum built_in_function fn);
Index: tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-ccp.c,v
retrieving revision 2.16
diff -c -3 -p -r2.16 tree-ssa-ccp.c
*** tree-ssa-ccp.c	4 Jul 2004 18:41:05 -0000	2.16
--- tree-ssa-ccp.c	5 Jul 2004 02:29:09 -0000
*************** ccp_fold (tree stmt)
*** 950,956 ****

  	  /* Substitute operands with their values and try to fold.  */
  	  replace_uses_in (stmt, NULL);
! 	  retval = fold_builtin (rhs);

  	  /* Restore operands to their original form.  */
  	  for (i = 0; i < NUM_USES (uses); i++)
--- 950,956 ----

  	  /* Substitute operands with their values and try to fold.  */
  	  replace_uses_in (stmt, NULL);
! 	  retval = fold_builtin (rhs, false);

  	  /* Restore operands to their original form.  */
  	  for (i = 0; i < NUM_USES (uses); i++)
*************** ccp_fold (tree stmt)
*** 963,975 ****

    /* If we got a simplified form, see if we need to convert its type.  */
    if (retval)
!     {
!       if (TREE_TYPE (retval) != TREE_TYPE (rhs))
! 	retval = fold_convert (TREE_TYPE (rhs), retval);
!
!       if (TREE_TYPE (retval) == TREE_TYPE (rhs))
! 	return retval;
!     }

    /* No simplification was possible.  */
    return rhs;
--- 963,969 ----

    /* If we got a simplified form, see if we need to convert its type.  */
    if (retval)
!     return fold_convert (TREE_TYPE (rhs), retval);

    /* No simplification was possible.  */
    return rhs;
*************** static tree
*** 2288,2310 ****
  ccp_fold_builtin (tree stmt, tree fn)
  {
    tree result, strlen_val[2];
!   tree arglist = TREE_OPERAND (fn, 1), a;
!   tree callee = get_callee_fndecl (fn);
!   bitmap visited;
    int strlen_arg, i;

!   /* Ignore MD builtins.  */
!   if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
!     return NULL_TREE;

    /* First try the generic builtin folder.  If that succeeds, return the
       result directly.  */
!   result = fold_builtin (fn);
    if (result)
      return result;

    /* If the builtin could not be folded, and it has no argument list,
       we're done.  */
    if (!arglist)
      return NULL_TREE;

--- 2282,2312 ----
  ccp_fold_builtin (tree stmt, tree fn)
  {
    tree result, strlen_val[2];
!   tree callee, arglist, a;
    int strlen_arg, i;
+   bitmap visited;
+   bool ignore;

!   ignore = TREE_CODE (stmt) != MODIFY_EXPR;

    /* First try the generic builtin folder.  If that succeeds, return the
       result directly.  */
!   result = fold_builtin (fn, ignore);
    if (result)
+   {
+     if (ignore)
+       STRIP_NOPS (result);
      return result;
+   }
+
+   /* Ignore MD builtins.  */
+   callee = get_callee_fndecl (fn);
+   if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_MD)
+     return NULL_TREE;

    /* If the builtin could not be folded, and it has no argument list,
       we're done.  */
+   arglist = TREE_OPERAND (fn, 1);
    if (!arglist)
      return NULL_TREE;

*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2340,2355 ****

    BITMAP_XFREE (visited);

!   /* FIXME.  All this code looks dangerous in the sense that it might
!      create non-gimple expressions.  */
    switch (DECL_FUNCTION_CODE (callee))
      {
      case BUILT_IN_STRLEN:
!       /* Convert from the internal "sizetype" type to "size_t".  */
!       if (strlen_val[0]
! 	  && size_type_node)
  	{
! 	  tree new = convert (size_type_node, strlen_val[0]);

  	  /* If the result is not a valid gimple value, or not a cast
  	     of a valid gimple value, then we can not use the result.  */
--- 2342,2354 ----

    BITMAP_XFREE (visited);

!   result = NULL_TREE;
    switch (DECL_FUNCTION_CODE (callee))
      {
      case BUILT_IN_STRLEN:
!       if (strlen_val[0])
  	{
! 	  tree new = fold_convert (TREE_TYPE (fn), strlen_val[0]);

  	  /* If the result is not a valid gimple value, or not a cast
  	     of a valid gimple value, then we can not use the result.  */
*************** ccp_fold_builtin (tree stmt, tree fn)
*** 2357,2388 ****
  	      || (is_gimple_cast (new)
  		  && is_gimple_val (TREE_OPERAND (new, 0))))
  	    return new;
- 	  else
- 	    return NULL_TREE;
  	}
!       return strlen_val[0];
      case BUILT_IN_STRCPY:
!       if (strlen_val[1]
! 	  && is_gimple_val (strlen_val[1]))
!       return simplify_builtin_strcpy (arglist, strlen_val[1]);
      case BUILT_IN_STRNCPY:
!       if (strlen_val[1]
! 	  && is_gimple_val (strlen_val[1]))
!       return simplify_builtin_strncpy (arglist, strlen_val[1]);
      case BUILT_IN_FPUTS:
!       return simplify_builtin_fputs (arglist,
! 				     TREE_CODE (stmt) != MODIFY_EXPR, 0,
! 				     strlen_val[0]);
      case BUILT_IN_FPUTS_UNLOCKED:
!       return simplify_builtin_fputs (arglist,
! 				     TREE_CODE (stmt) != MODIFY_EXPR, 1,
! 				     strlen_val[0]);

      default:
        abort ();
      }

!   return NULL_TREE;
  }


--- 2356,2393 ----
  	      || (is_gimple_cast (new)
  		  && is_gimple_val (TREE_OPERAND (new, 0))))
  	    return new;
  	}
!       break;
!
      case BUILT_IN_STRCPY:
!       if (strlen_val[1] && is_gimple_val (strlen_val[1]))
!         result = fold_builtin_strcpy (fn, strlen_val[1]);
!       break;
!
      case BUILT_IN_STRNCPY:
!       if (strlen_val[1] && is_gimple_val (strlen_val[1]))
! 	result = fold_builtin_strncpy (fn, strlen_val[1]);
!       break;
!
      case BUILT_IN_FPUTS:
!       result = fold_builtin_fputs (arglist,
! 				   TREE_CODE (stmt) != MODIFY_EXPR, 0,
! 				   strlen_val[0]);
!       break;
!
      case BUILT_IN_FPUTS_UNLOCKED:
!       result = fold_builtin_fputs (arglist,
! 				   TREE_CODE (stmt) != MODIFY_EXPR, 1,
! 				   strlen_val[0]);
!       break;

      default:
        abort ();
      }

!   if (result && ignore)
!     STRIP_NOPS (result);
!   return result;
  }


*************** execute_fold_all_builtins (void)
*** 2503,2521 ****
  	    continue;

  	  result = ccp_fold_builtin (*stmtp, call);
- 	  if (!result)
- 	    switch (DECL_FUNCTION_CODE (callee))
- 	      {
- 	      case BUILT_IN_CONSTANT_P:
- 		/* Resolve __builtin_constant_p.  If it hasn't been
- 		   folded to integer_one_node by now, it's fairly
- 		   certain that the value simply isn't constant.  */
- 		result = integer_zero_node;
- 		break;

! 	      default:
  		continue;
! 	      }

  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
--- 2508,2524 ----
  	    continue;

  	  result = ccp_fold_builtin (*stmtp, call);

! 	  /* Resolve __builtin_constant_p.  If it hasn't been folded
! 	     to integer_one_node by now, it's fairly certain that the
! 	     value simply isn't constant.  */
! 	  if (! result)
! 	    {
! 	      if (DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
! 		result = integer_zero_node;
! 	      else
  		continue;
! 	    }

  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.416
diff -c -3 -p -r1.416 fold-const.c
*** fold-const.c	3 Jul 2004 00:15:40 -0000	1.416
--- fold-const.c	5 Jul 2004 02:29:11 -0000
*************** fold (tree expr)
*** 8890,8896 ****
  	      == FUNCTION_DECL)
  	  && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
  	{
! 	  tree tmp = fold_builtin (t);
  	  if (tmp)
  	    return tmp;
  	}
--- 8890,8896 ----
  	      == FUNCTION_DECL)
  	  && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
  	{
! 	  tree tmp = fold_builtin (t, false);
  	  if (tmp)
  	    return tmp;
  	}

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Unify fold_builtin and simplify_builtin APIs
  2004-07-05  6:03 [PATCH] Unify fold_builtin and simplify_builtin APIs Roger Sayle
@ 2004-07-08  4:45 ` Richard Henderson
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Henderson @ 2004-07-08  4:45 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, Jeff Law

On Sun, Jul 04, 2004 at 10:59:39PM -0600, Roger Sayle wrote:
>   	  result = ccp_fold_builtin (*stmtp, call);
> - 	  if (!result)
> - 	    switch (DECL_FUNCTION_CODE (callee))
> - 	      {
> - 	      case BUILT_IN_CONSTANT_P:
> - 		/* Resolve __builtin_constant_p.  If it hasn't been
> - 		   folded to integer_one_node by now, it's fairly
> - 		   certain that the value simply isn't constant.  */
> - 		result = integer_zero_node;
> - 		break;
> 
> ! 	      default:
>   		continue;
> ! 	      }
> 
>   	  if (dump_file && (dump_flags & TDF_DETAILS))
>   	    {
> --- 2508,2524 ----
>   	    continue;
> 
>   	  result = ccp_fold_builtin (*stmtp, call);
> 
> ! 	  /* Resolve __builtin_constant_p.  If it hasn't been folded
> ! 	     to integer_one_node by now, it's fairly certain that the
> ! 	     value simply isn't constant.  */
> ! 	  if (! result)
> ! 	    {
> ! 	      if (DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P)
> ! 		result = integer_zero_node;
> ! 	      else
>   		continue;

I'd prefer you leave this as a switch.  I had thought we might
resolve other builtins here in the future.

Otherwise ok.


r~

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-07-08  3:46 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-05  6:03 [PATCH] Unify fold_builtin and simplify_builtin APIs Roger Sayle
2004-07-08  4:45 ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).