* [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).