From 07328167818043c60e665d3c5bb750a9b54da09b Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Thu, 21 Sep 2000 01:59:07 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++++ gcc/builtins.c | 68 +++++++++++++++++++++++++++++++++--------------- gcc/builtins.def | 1 + gcc/c-common.c | 6 ++++- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fd3cba4c8f..c9a05bb669b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2000-09-20 Kaveh R. Ghazi + + * 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 * gcc.c (modify_target): New variable and struct. diff --git a/gcc/builtins.c b/gcc/builtins.c index 05297230825..4f03dc7f8cb 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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: diff --git a/gcc/builtins.def b/gcc/builtins.def index 7220cf9124c..ede0d2e0634 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -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) diff --git a/gcc/c-common.c b/gcc/c-common.c index fec74eb69ef..ce0b33ad788 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -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"); -- 2.30.2