Commit 07328167 by Kaveh R. Ghazi Committed by Kaveh Ghazi

builtins.c (expand_builtin_fputs): Also expand when length!=1.

	* builtins.c (expand_builtin_fputs): Also expand when length!=1.
	(expand_builtin): Handle BUILT_IN_FWRITE.

	* builtins.def (BUILT_IN_FWRITE): New entry.

	* c-common.c (c_common_nodes_and_builtins): Declare __builtin_fwrite.

From-SVN: r36556
parent dc36ec2c
2000-09-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtins.c (expand_builtin_fputs): Also expand when length!=1.
(expand_builtin): Handle BUILT_IN_FWRITE.
* builtins.def (BUILT_IN_FWRITE): New entry.
* c-common.c (c_common_nodes_and_builtins): Declare __builtin_fwrite.
Wed Sep 20 15:39:14 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Wed Sep 20 15:39:14 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* gcc.c (modify_target): New variable and struct. * gcc.c (modify_target): New variable and struct.
......
...@@ -2329,12 +2329,12 @@ expand_builtin_fputs (arglist, ignore) ...@@ -2329,12 +2329,12 @@ expand_builtin_fputs (arglist, ignore)
tree arglist; tree arglist;
int ignore; int ignore;
{ {
tree call_expr, len, stripped_string, newarglist; tree call_expr, len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
tree fn = built_in_decls[BUILT_IN_FPUTC]; fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
/* If the return value is used, or the replacement _DECL isn't /* If the return value is used, or the replacement _DECL isn't
initialized, don't do the transformation. */ initialized, don't do the transformation. */
if (!ignore || !fn) if (!ignore || !fn_fputc || !fn_fwrite)
return 0; return 0;
/* Verify the arguments in the original call. */ /* Verify the arguments in the original call. */
...@@ -2345,29 +2345,54 @@ expand_builtin_fputs (arglist, ignore) ...@@ -2345,29 +2345,54 @@ expand_builtin_fputs (arglist, ignore)
!= POINTER_TYPE)) != POINTER_TYPE))
return 0; return 0;
/* Get the length of the string passed to fputs. */ /* Get the length of the string passed to fputs. If the length
len = c_strlen (TREE_VALUE (arglist)); can't be determined, punt. */
if (!(len = c_strlen (TREE_VALUE (arglist))))
/* If the length != 1, punt. */
if (len == 0 || compare_tree_int (len, 1))
return 0; return 0;
stripped_string = TREE_VALUE (arglist); switch (compare_tree_int (len, 1))
STRIP_NOPS (stripped_string); {
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR) case -1: /* length is 0, delete the call entirely . */
stripped_string = TREE_OPERAND (stripped_string, 0); return const0_rtx;
case 0: /* length is 1, call fputc. */
{
tree stripped_string = TREE_VALUE (arglist);
/* New argument list transforming fputs(string, stream) to STRIP_NOPS (stripped_string);
fputc(string[0], stream). */ if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
newarglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist))); stripped_string = TREE_OPERAND (stripped_string, 0);
newarglist =
tree_cons (NULL_TREE, /* New argument list transforming fputs(string, stream) to
build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0), fputc(string[0], stream). */
newarglist); arglist =
build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
arglist =
tree_cons (NULL_TREE,
build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0),
arglist);
fn = fn_fputc;
break;
}
case 1: /* length is greater than 1, call fwrite. */
{
tree 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, integer_one_node, arglist);
arglist = tree_cons (NULL_TREE, string_arg, arglist);
fn = fn_fwrite;
break;
}
default:
abort();
}
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn); call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)), call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call_expr, newarglist, NULL_TREE); call_expr, arglist, NULL_TREE);
TREE_SIDE_EFFECTS (call_expr) = 1; TREE_SIDE_EFFECTS (call_expr) = 1;
return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX), return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX),
VOIDmode, EXPAND_NORMAL); VOIDmode, EXPAND_NORMAL);
...@@ -2563,7 +2588,7 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -2563,7 +2588,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS || fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
|| fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS || fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
|| fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC || fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
|| fcode == BUILT_IN_FPUTS)) || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE))
return expand_call (exp, target, ignore); return expand_call (exp, target, ignore);
switch (fcode) switch (fcode)
...@@ -2779,6 +2804,7 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -2779,6 +2804,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_PUTCHAR: case BUILT_IN_PUTCHAR:
case BUILT_IN_PUTS: case BUILT_IN_PUTS:
case BUILT_IN_FPUTC: case BUILT_IN_FPUTC:
case BUILT_IN_FWRITE:
break; break;
case BUILT_IN_FPUTS: case BUILT_IN_FPUTS:
......
...@@ -64,6 +64,7 @@ DEF_BUILTIN(BUILT_IN_PUTS) ...@@ -64,6 +64,7 @@ DEF_BUILTIN(BUILT_IN_PUTS)
DEF_BUILTIN(BUILT_IN_PRINTF) DEF_BUILTIN(BUILT_IN_PRINTF)
DEF_BUILTIN(BUILT_IN_FPUTC) DEF_BUILTIN(BUILT_IN_FPUTC)
DEF_BUILTIN(BUILT_IN_FPUTS) DEF_BUILTIN(BUILT_IN_FPUTS)
DEF_BUILTIN(BUILT_IN_FWRITE)
/* ISO C99 floating point unordered comparisons. */ /* ISO C99 floating point unordered comparisons. */
DEF_BUILTIN(BUILT_IN_ISGREATER) DEF_BUILTIN(BUILT_IN_ISGREATER)
......
...@@ -4014,7 +4014,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins) ...@@ -4014,7 +4014,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
tree endlink, int_endlink, double_endlink, unsigned_endlink; tree endlink, int_endlink, double_endlink, unsigned_endlink;
tree sizetype_endlink; tree sizetype_endlink;
tree ptr_ftype, ptr_ftype_unsigned; tree ptr_ftype, ptr_ftype_unsigned;
tree void_ftype_any, void_ftype_int, int_ftype_any; tree void_ftype_any, void_ftype_int, int_ftype_any, sizet_ftype_any;
tree double_ftype_double, double_ftype_double_double; tree double_ftype_double, double_ftype_double_double;
tree float_ftype_float, ldouble_ftype_ldouble; tree float_ftype_float, ldouble_ftype_ldouble;
tree int_ftype_cptr_cptr_sizet; tree int_ftype_cptr_cptr_sizet;
...@@ -4060,6 +4060,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins) ...@@ -4060,6 +4060,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
/* We realloc here because sizetype could be int or unsigned. S'ok. */ /* We realloc here because sizetype could be int or unsigned. S'ok. */
ptr_ftype_sizetype = build_function_type (ptr_type_node, sizetype_endlink); ptr_ftype_sizetype = build_function_type (ptr_type_node, sizetype_endlink);
sizet_ftype_any = build_function_type (sizetype, NULL_TREE);
int_ftype_any = build_function_type (integer_type_node, NULL_TREE); int_ftype_any = build_function_type (integer_type_node, NULL_TREE);
void_ftype_any = build_function_type (void_type_node, NULL_TREE); void_ftype_any = build_function_type (void_type_node, NULL_TREE);
void_ftype = build_function_type (void_type_node, endlink); void_ftype = build_function_type (void_type_node, endlink);
...@@ -4377,6 +4378,9 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins) ...@@ -4377,6 +4378,9 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
them later with argument without worrying about the explicit them later with argument without worrying about the explicit
declarations in stdio.h being taken as the initial declaration. declarations in stdio.h being taken as the initial declaration.
Also, save the _DECL for these so we can use them later. */ Also, save the _DECL for these so we can use them later. */
built_in_decls[BUILT_IN_FWRITE] =
builtin_function ("__builtin_fwrite", sizet_ftype_any,
BUILT_IN_FWRITE, BUILT_IN_NORMAL, "fwrite");
built_in_decls[BUILT_IN_FPUTC] = built_in_decls[BUILT_IN_FPUTC] =
builtin_function ("__builtin_fputc", int_ftype_any, builtin_function ("__builtin_fputc", int_ftype_any,
BUILT_IN_FPUTC, BUILT_IN_NORMAL, "fputc"); BUILT_IN_FPUTC, BUILT_IN_NORMAL, "fputc");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment