builtins.c (expand_builtin_fputs): Also expand when length!=1.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Thu, 21 Sep 2000 01:59:07 +0000 (01:59 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Thu, 21 Sep 2000 01:59:07 +0000 (01:59 +0000)
* 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
gcc/builtins.c
gcc/builtins.def
gcc/c-common.c

index 2fd3cba4c8fc7412a77720cd67422bd42b3a54ce..c9a05bb669bd5b3570078bebdb79d82e395f9793 100644 (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.
index 052972308255f0c2a6aa130cbb89067e22ca8b95..4f03dc7f8cba6753689b2fcdb900e31e45f91b7e 100644 (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:
index 7220cf9124c185c14d533edcc63f314a089f9341..ede0d2e06345816def1d31571f2ddc6370258326 100644 (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)
index fec74eb69ef0462361786788f943eb4d5d8d396c..ce0b33ad7888f5ed0257d1b509f7d5ac3ab549a6 100644 (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");