summaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-08 17:40:22 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-08 17:40:22 +0000
commitf0613857bfe9030adb2482f73961065d66cad236 (patch)
tree39e4ab0ff10a947c37ee4abcbe91d60592309b6e /gcc/builtins.c
parent978836e597ffb94e9b71f2fc28eddadc8a4a8091 (diff)
downloadgcc-f0613857bfe9030adb2482f73961065d66cad236.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@84302 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c248
1 files changed, 87 insertions, 161 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 9bcef91a70b..c07ff044e3e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -156,8 +156,6 @@ static tree fold_builtin_bitop (tree);
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);
@@ -170,6 +168,7 @@ static tree fold_builtin_isdigit (tree);
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);
@@ -7314,14 +7313,15 @@ fold_builtin_memmove (tree exp)
return 0;
}
-/* Fold function call to builtin strcpy. Return
- NULL_TREE if no simplification can be made. */
+/* 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. */
-static tree
-fold_builtin_strcpy (tree exp)
+tree
+fold_builtin_strcpy (tree exp, tree len)
{
tree arglist = TREE_OPERAND (exp, 1);
- tree dest, src;
+ tree dest, src, fn;
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
@@ -7334,17 +7334,37 @@ fold_builtin_strcpy (tree exp)
if (operand_equal_p (src, dest, 0))
return fold_convert (TREE_TYPE (exp), dest);
- return 0;
+ 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. Return
- NULL_TREE if no simplification can be made. */
+/* 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. */
-static tree
-fold_builtin_strncpy (tree exp)
+tree
+fold_builtin_strncpy (tree exp, tree slen)
{
tree arglist = TREE_OPERAND (exp, 1);
- tree dest, src, len;
+ tree dest, src, len, fn;
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -7358,7 +7378,27 @@ fold_builtin_strncpy (tree exp)
if (integer_zerop (len))
return omit_one_operand (TREE_TYPE (exp), dest, src);
- return 0;
+ 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.
@@ -7886,11 +7926,13 @@ fold_builtin_unordered_cmp (tree exp,
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. */
+/* 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)
+fold_builtin_1 (tree exp, bool ignore)
{
tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
@@ -8397,10 +8439,10 @@ fold_builtin_1 (tree exp)
return fold_builtin_memmove (exp);
case BUILT_IN_STRCPY:
- return fold_builtin_strcpy (exp);
+ return fold_builtin_strcpy (exp, NULL_TREE);
case BUILT_IN_STRNCPY:
- return fold_builtin_strncpy (exp);
+ return fold_builtin_strncpy (exp, NULL_TREE);
case BUILT_IN_INDEX:
case BUILT_IN_STRCHR:
@@ -8466,6 +8508,12 @@ fold_builtin_1 (tree exp)
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;
}
@@ -8478,9 +8526,9 @@ fold_builtin_1 (tree exp)
call node earlier than the warning is generated. */
tree
-fold_builtin (tree exp)
+fold_builtin (tree exp, bool ignore)
{
- exp = fold_builtin_1 (exp);
+ exp = fold_builtin_1 (exp, ignore);
if (exp)
{
/* ??? Don't clobber shared nodes such as integer_zero_node. */
@@ -8614,10 +8662,10 @@ simplify_builtin (tree exp, int ignore)
switch (fcode)
{
case BUILT_IN_FPUTS:
- val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
+ val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
break;
case BUILT_IN_FPUTS_UNLOCKED:
- val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
+ val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
break;
case BUILT_IN_STRSTR:
val = simplify_builtin_strstr (arglist);
@@ -8643,10 +8691,10 @@ simplify_builtin (tree exp, int ignore)
val = simplify_builtin_strrchr (arglist);
break;
case BUILT_IN_STRCPY:
- val = simplify_builtin_strcpy (arglist, NULL_TREE);
+ val = fold_builtin_strcpy (exp, NULL_TREE);
break;
case BUILT_IN_STRNCPY:
- val = simplify_builtin_strncpy (arglist, NULL_TREE);
+ val = fold_builtin_strncpy (exp, NULL_TREE);
break;
case BUILT_IN_STRCMP:
val = simplify_builtin_strcmp (arglist);
@@ -8936,115 +8984,6 @@ simplify_builtin_strpbrk (tree arglist)
}
}
-/* 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
@@ -9454,31 +9393,16 @@ simplify_builtin_strcspn (tree arglist)
}
}
-/* 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. */
+/* 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
-simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
+fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
{
- tree len, fn;
+ 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]
@@ -9493,7 +9417,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
- len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 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. */
@@ -9517,8 +9442,7 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
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);
+ arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
fn = fn_fputc;
break;
}
@@ -9534,7 +9458,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
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 = 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);
@@ -9545,7 +9470,8 @@ simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
abort ();
}
- return build_function_call_expr (fn, arglist);
+ return fold_convert (integer_type_node,
+ build_function_call_expr (fn, arglist));
}
static void