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:
parent
dc36ec2cad
commit
0732816781
4 changed files with 62 additions and 22 deletions
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Add table
Reference in a new issue