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
This commit is contained in:
Kaveh R. Ghazi 2000-09-21 01:59:07 +00:00 committed by Kaveh Ghazi
parent dc36ec2cad
commit 0732816781
4 changed files with 62 additions and 22 deletions

View File

@ -1,3 +1,12 @@
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>
* gcc.c (modify_target): New variable and struct.

View File

@ -2329,12 +2329,12 @@ expand_builtin_fputs (arglist, ignore)
tree arglist;
int ignore;
{
tree call_expr, len, stripped_string, newarglist;
tree fn = built_in_decls[BUILT_IN_FPUTC];
tree call_expr, len, fn, fn_fputc = 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
initialized, don't do the transformation. */
if (!ignore || !fn)
if (!ignore || !fn_fputc || !fn_fwrite)
return 0;
/* Verify the arguments in the original call. */
@ -2345,29 +2345,54 @@ expand_builtin_fputs (arglist, ignore)
!= POINTER_TYPE))
return 0;
/* Get the length of the string passed to fputs. */
len = c_strlen (TREE_VALUE (arglist));
/* If the length != 1, punt. */
if (len == 0 || compare_tree_int (len, 1))
/* Get the length of the string passed to fputs. If the length
can't be determined, punt. */
if (!(len = c_strlen (TREE_VALUE (arglist))))
return 0;
stripped_string = TREE_VALUE (arglist);
STRIP_NOPS (stripped_string);
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
stripped_string = TREE_OPERAND (stripped_string, 0);
switch (compare_tree_int (len, 1))
{
case -1: /* length is 0, delete the call entirely . */
return const0_rtx;
case 0: /* length is 1, call fputc. */
{
tree stripped_string = TREE_VALUE (arglist);
/* New argument list transforming fputs(string, stream) to
fputc(string[0], stream). */
newarglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
newarglist =
tree_cons (NULL_TREE,
build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0),
newarglist);
STRIP_NOPS (stripped_string);
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
stripped_string = TREE_OPERAND (stripped_string, 0);
/* New argument list transforming fputs(string, stream) to
fputc(string[0], stream). */
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 = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call_expr, newarglist, NULL_TREE);
call_expr, arglist, NULL_TREE);
TREE_SIDE_EFFECTS (call_expr) = 1;
return expand_expr (call_expr, (ignore ? const0_rtx : NULL_RTX),
VOIDmode, EXPAND_NORMAL);
@ -2563,7 +2588,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
|| fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
|| 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);
switch (fcode)
@ -2779,6 +2804,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_PUTCHAR:
case BUILT_IN_PUTS:
case BUILT_IN_FPUTC:
case BUILT_IN_FWRITE:
break;
case BUILT_IN_FPUTS:

View File

@ -64,6 +64,7 @@ DEF_BUILTIN(BUILT_IN_PUTS)
DEF_BUILTIN(BUILT_IN_PRINTF)
DEF_BUILTIN(BUILT_IN_FPUTC)
DEF_BUILTIN(BUILT_IN_FPUTS)
DEF_BUILTIN(BUILT_IN_FWRITE)
/* ISO C99 floating point unordered comparisons. */
DEF_BUILTIN(BUILT_IN_ISGREATER)

View File

@ -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 sizetype_endlink;
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 float_ftype_float, ldouble_ftype_ldouble;
tree int_ftype_cptr_cptr_sizet;
@ -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. */
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);
void_ftype_any = build_function_type (void_type_node, NULL_TREE);
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)
them later with argument without worrying about the explicit
declarations in stdio.h being taken as the initial declaration.
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] =
builtin_function ("__builtin_fputc", int_ftype_any,
BUILT_IN_FPUTC, BUILT_IN_NORMAL, "fputc");