]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins.def (BUILT_IN_PRINTF, [...]): Changed from front-end builtins to normal...
authorRoger Sayle <roger@eyesopen.com>
Thu, 24 Jul 2003 21:04:12 +0000 (21:04 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 24 Jul 2003 21:04:12 +0000 (21:04 +0000)
* builtins.def (BUILT_IN_PRINTF, BUILT_IN_FPRINTF): Changed from
front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
(BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_FPRINTF_UNLOCKED): Changed
from front-end to normal builtins, using DEF_EXT_LIB_BUILTIN.
(DEF_FRONT_END_LIB_BUILTIN): Delete.
(DEF_EXT_FRONT_END_LIB_BUILTIN): Delete.
(BUILT_IN_FWRITE_UNLOCKED): Wrap long line.

* builtins.c (build_string_literal): New function to construct
a char* pointer to a string literal.
(expand_builtin_fputs): Change 2nd argument from "int ignore" to
"rtx target" to be consistent with other expand_builtin_* functions.
Change 3rd argument from "int unlocked" to "bool unlocked".
(expand_builtin_printf): Rewrite of c_expand_builtin_printf from
c-common.c to avoid front-end dependencies.  Optimize printf("")
as a no-op when the result isn't required.  Handle embedded NULs
in format string.
(expand_builtin_fprintf): A rewrite of c_expand_builtin_fprintf
from c-common.c to avoid front-end dependencies.  Likewise, optimize
fprintf(fp,"") as a no-op when the result isn't required, evaluating
fp for side-effects.  Handle embedded NULs in format string.
(expand_builtin_sprintf): Fix typo.
(expand_builtin): Don't expand BUILT_IN_FPRINT{,_UNLOCKED} when not
optimizing.  Adjust calls of expand_builtin_fputs to match the API
change. Expand BUILT_IN_PRINTF and BUILT_IN_PRINTF_UNLOCKED using
expand_builtin_printf.  Likewise, expand BUILT_IN_FPRINTF_UNLOCKED
and BUILT_IN_FPRINTF using expand_builtin_fprintf.

* c-common.c (is_valid_printf_arglist): Delete.
(c_expand_builtin): Delete.
(c_expand_builtin_printf): Moved to builtins.c. Delete.
(c_expand_builtin_fprintf): Moved to builtins.c.  Delete.
(c_expand_expr): No longer treat CALL_EXPRs specially.
(CALLED_AS_BUILT_IN): Delete.

From-SVN: r69760

gcc/ChangeLog
gcc/builtins.c
gcc/builtins.def
gcc/c-common.c

index 0a4b1a36539dba1815056596d963b0040be80e07..4a68dfba09074c3b891c098f07b85fad3e934792 100644 (file)
@@ -1,3 +1,40 @@
+2003-07-24  Roger Sayle  <roger@eyesopen.com>
+
+       * builtins.def (BUILT_IN_PRINTF, BUILT_IN_FPRINTF): Changed from
+       front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
+       (BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_FPRINTF_UNLOCKED): Changed
+       from front-end to normal builtins, using DEF_EXT_LIB_BUILTIN.
+       (DEF_FRONT_END_LIB_BUILTIN): Delete.
+       (DEF_EXT_FRONT_END_LIB_BUILTIN): Delete.
+       (BUILT_IN_FWRITE_UNLOCKED): Wrap long line.
+
+       * builtins.c (build_string_literal): New function to construct
+       a char* pointer to a string literal.
+       (expand_builtin_fputs): Change 2nd argument from "int ignore" to
+       "rtx target" to be consistent with other expand_builtin_* functions.
+       Change 3rd argument from "int unlocked" to "bool unlocked".
+       (expand_builtin_printf): Rewrite of c_expand_builtin_printf from
+       c-common.c to avoid front-end dependencies.  Optimize printf("")
+       as a no-op when the result isn't required.  Handle embedded NULs
+       in format string.
+       (expand_builtin_fprintf): A rewrite of c_expand_builtin_fprintf
+       from c-common.c to avoid front-end dependencies.  Likewise, optimize
+       fprintf(fp,"") as a no-op when the result isn't required, evaluating
+       fp for side-effects.  Handle embedded NULs in format string.
+       (expand_builtin_sprintf): Fix typo.
+       (expand_builtin): Don't expand BUILT_IN_FPRINT{,_UNLOCKED} when not
+       optimizing.  Adjust calls of expand_builtin_fputs to match the API
+       change. Expand BUILT_IN_PRINTF and BUILT_IN_PRINTF_UNLOCKED using
+       expand_builtin_printf.  Likewise, expand BUILT_IN_FPRINTF_UNLOCKED
+       and BUILT_IN_FPRINTF using expand_builtin_fprintf.
+
+       * c-common.c (is_valid_printf_arglist): Delete.
+       (c_expand_builtin): Delete.
+       (c_expand_builtin_printf): Moved to builtins.c. Delete.
+       (c_expand_builtin_fprintf): Moved to builtins.c.  Delete.
+       (c_expand_expr): No longer treat CALL_EXPRs specially.
+       (CALLED_AS_BUILT_IN): Delete.
+
 2003-07-24  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        PR optimization/11631
index 0a44edf064d96748d96c23b87fda39289877edf0..a8c1d47277f7824a722952aadce5cdf40ec92a59 100644 (file)
@@ -90,6 +90,7 @@ static const char *c_getstr (tree);
 static rtx c_readstr (const char *, enum machine_mode);
 static int target_char_cast (tree, char *);
 static rtx get_memory_rtx (tree);
+static tree build_string_literal (int, const char *);
 static int apply_args_size (void);
 static int apply_result_size (void);
 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
@@ -140,7 +141,9 @@ static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
 static rtx expand_builtin_alloca (tree, rtx);
 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
 static rtx expand_builtin_frame_address (tree, tree);
-static rtx expand_builtin_fputs (tree, int, int);
+static rtx expand_builtin_fputs (tree, rtx, bool);
+static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
+static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
 static tree stabilize_va_list (tree, int);
 static rtx expand_builtin_expect (tree, rtx);
@@ -820,10 +823,10 @@ expand_builtin_prefetch (tree arglist)
       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
             (op0,
              insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
-         || (GET_MODE(op0) != Pmode))
+         || (GET_MODE (op0) != Pmode))
        {
 #ifdef POINTERS_EXTEND_UNSIGNED
-         if (GET_MODE(op0) != Pmode)
+         if (GET_MODE (op0) != Pmode)
            op0 = convert_memory_address (Pmode, op0);
 #endif
          op0 = force_reg (Pmode, op0);
@@ -2137,7 +2140,7 @@ expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
 
   val = (n < 0) ? -n : n;
 
-  memset (cache, 0, sizeof(cache));
+  memset (cache, 0, sizeof (cache));
   cache[1] = x;
 
   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
@@ -4258,7 +4261,7 @@ expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
    long, we attempt to transform this call into __builtin_fputc().  */
 
 static rtx
-expand_builtin_fputs (tree arglist, int ignore, int unlocked)
+expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
 {
   tree len, fn;
   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
@@ -4268,7 +4271,7 @@ expand_builtin_fputs (tree arglist, int ignore, int unlocked)
 
   /* If the return value is used, or the replacement _DECL isn't
      initialized, don't do the transformation.  */
-  if (!ignore || !fn_fputc || !fn_fwrite)
+  if (target != const0_rtx || !fn_fputc || !fn_fwrite)
     return 0;
 
   /* Verify the arguments in the original call.  */
@@ -4330,8 +4333,7 @@ expand_builtin_fputs (tree arglist, int ignore, int unlocked)
     }
 
   return expand_expr (build_function_call_expr (fn, arglist),
-                     (ignore ? const0_rtx : NULL_RTX),
-                     VOIDmode, EXPAND_NORMAL);
+                     const0_rtx, VOIDmode, EXPAND_NORMAL);
 }
 
 /* Expand a call to __builtin_expect.  We return our argument and emit a
@@ -4551,6 +4553,227 @@ expand_builtin_cabs (tree arglist, rtx target)
   return expand_complex_abs (mode, op0, target, 0);
 }
 
+/* Create a new constant string literal and return a char* pointer to it.
+   The STRING_CST value is the LEN characters at STR.  */
+static tree
+build_string_literal (int len, const char *str)
+{
+  tree t, elem, index, type;
+
+  t = build_string (len, str);
+  elem = build_type_variant (char_type_node, 1, 0);
+  index = build_index_type (build_int_2 (len - 1, 0));
+  type = build_array_type (elem, index);
+  TREE_TYPE (t) = type;
+  TREE_CONSTANT (t) = 1;
+  TREE_READONLY (t) = 1;
+  TREE_STATIC (t) = 1;
+
+  type = build_pointer_type (type);
+  t = build1 (ADDR_EXPR, type, t);
+
+  type = build_pointer_type (elem);
+  t = build1 (NOP_EXPR, type, t);
+  return t;
+}
+
+/* Expand a call to printf or printf_unlocked with argument list ARGLIST.
+   Return 0 if a normal call should be emitted rather than transforming
+   the function inline.  If convenient, the result should be placed in
+   TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
+   call.  */
+static rtx
+expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
+                      bool unlocked)
+{
+  tree fn_putchar = unlocked
+                   ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
+                   : implicit_built_in_decls[BUILT_IN_PUTCHAR];
+  tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
+                         : implicit_built_in_decls[BUILT_IN_PUTS];
+  const char *fmt_str;
+  tree fn, fmt, arg;
+
+  /* If the return value is used, don't do the transformation.  */
+  if (target != const0_rtx)
+    return 0;
+
+  /* Verify the required arguments in the original call.  */
+  if (! arglist)
+    return 0;
+  fmt = TREE_VALUE (arglist);
+  if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+    return 0;
+  arglist = TREE_CHAIN (arglist);
+
+  /* Check whether the format is a literal string constant.  */
+  fmt_str = c_getstr (fmt);
+  if (fmt_str == NULL)
+    return 0;
+
+  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
+  if (strcmp (fmt_str, "%s\n") == 0)
+    {
+      if (! arglist
+          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+         || TREE_CHAIN (arglist))
+       return 0;
+      fn = fn_puts;
+    }
+  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
+  else if (strcmp (fmt_str, "%c") == 0)
+    {
+      if (! arglist
+         || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
+         || TREE_CHAIN (arglist))
+       return 0;
+      fn = fn_putchar;
+    }
+  else
+    {
+      /* We can't handle anything else with % args or %% ... yet.  */
+      if (strchr (fmt_str, '%'))
+        return 0;
+
+      if (arglist)
+       return 0;
+
+      /* If the format specifier was "", printf does nothing.  */
+      if (fmt_str[0] == '\0')
+       return const0_rtx;
+      /* If the format specifier has length of 1, call putchar.  */
+      if (fmt_str[1] == '\0')
+       {
+         /* Given printf("c"), (where c is any one character,)
+            convert "c"[0] to an int and pass that to the replacement
+            function.  */
+         arg = build_int_2 (fmt_str[0], 0);
+         arglist = build_tree_list (NULL_TREE, arg);
+         fn = fn_putchar;
+       }
+      else
+       {
+         /* If the format specifier was "string\n", call puts("string").  */
+         size_t len = strlen (fmt_str);
+         if (fmt_str[len - 1] == '\n')
+           {
+             /* Create a NUL-terminalted string that's one char shorter
+                than the original, stripping off the trailing '\n'.  */
+             char *newstr = (char *) alloca (len);
+             memcpy (newstr, fmt_str, len - 1);
+             newstr[len - 1] = 0;
+
+             arg = build_string_literal (len, newstr);
+             arglist = build_tree_list (NULL_TREE, arg);
+             fn = fn_puts;
+           }
+         else
+           /* We'd like to arrange to call fputs(string,stdout) here,
+              but we need stdout and don't have a way to get it yet.  */
+           return 0;
+       }
+    }
+
+  if (!fn)
+    return 0;
+  return expand_expr (build_function_call_expr (fn, arglist),
+                     target, mode, EXPAND_NORMAL);
+}
+
+/* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
+   Return 0 if a normal call should be emitted rather than transforming
+   the function inline.  If convenient, the result should be placed in
+   TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
+   call.  */
+static rtx
+expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
+                       bool unlocked)
+{
+  tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+                          : implicit_built_in_decls[BUILT_IN_FPUTC];
+  tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
+                          : implicit_built_in_decls[BUILT_IN_FPUTS];
+  const char *fmt_str;
+  tree fn, fmt, fp, arg;
+
+  /* If the return value is used, don't do the transformation.  */
+  if (target != const0_rtx)
+    return 0;
+
+  /* Verify the required arguments in the original call.  */
+  if (! arglist)
+    return 0;
+  fp = TREE_VALUE (arglist);
+  if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
+    return 0;
+  arglist = TREE_CHAIN (arglist);
+  if (! arglist)
+    return 0;
+  fmt = TREE_VALUE (arglist);
+  if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+    return 0;
+  arglist = TREE_CHAIN (arglist);
+
+  /* Check whether the format is a literal string constant.  */
+  fmt_str = c_getstr (fmt);
+  if (fmt_str == NULL)
+    return 0;
+
+  /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
+  if (strcmp (fmt_str, "%s") == 0)
+    {
+      if (! arglist
+          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+         || TREE_CHAIN (arglist))
+       return 0;
+      arg = TREE_VALUE (arglist);
+      arglist = build_tree_list (NULL_TREE, fp);
+      arglist = tree_cons (NULL_TREE, arg, arglist);
+      fn = fn_fputs;
+    }
+  /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
+  else if (strcmp (fmt_str, "%c") == 0)
+    {
+      if (! arglist
+         || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
+         || TREE_CHAIN (arglist))
+       return 0;
+      arg = TREE_VALUE (arglist);
+      arglist = build_tree_list (NULL_TREE, fp);
+      arglist = tree_cons (NULL_TREE, arg, arglist);
+      fn = fn_fputc;
+    }
+  else
+    {
+      /* We can't handle anything else with % args or %% ... yet.  */
+      if (strchr (fmt_str, '%'))
+        return 0;
+
+      if (arglist)
+       return 0;
+
+      /* If the format specifier was "", fprintf does nothing.  */
+      if (fmt_str[0] == '\0')
+       {
+         /* Evaluate and ignore FILE* argument for side-effects.  */
+         expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
+         return const0_rtx;
+       }
+
+      /* When "string" doesn't contain %, replace all cases of
+        fprintf(stream,string) with fputs(string,stream).  The fputs
+        builtin will take care of special cases like length == 1.  */
+      arglist = build_tree_list (NULL_TREE, fp);
+      arglist = tree_cons (NULL_TREE, fmt, arglist);
+      fn = fn_fputs;
+    }
+
+  if (!fn)
+    return 0;
+  return expand_expr (build_function_call_expr (fn, arglist),
+                     target, mode, EXPAND_NORMAL);
+}
+
 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
    a normal call should be emitted rather than expanding the function
    inline.  If convenient, the result should be placed in TARGET with
@@ -4574,7 +4797,7 @@ expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
   if (! arglist)
     return 0;
   fmt = TREE_VALUE (arglist);
-  if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
+  if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
     return 0;
   arglist = TREE_CHAIN (arglist);
 
@@ -4721,12 +4944,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       case BUILT_IN_FPUTC:
       case BUILT_IN_FPUTS:
       case BUILT_IN_FWRITE:
+      case BUILT_IN_FPRINTF:
       case BUILT_IN_PUTCHAR_UNLOCKED:
       case BUILT_IN_PUTS_UNLOCKED:
       case BUILT_IN_PRINTF_UNLOCKED:
       case BUILT_IN_FPUTC_UNLOCKED:
       case BUILT_IN_FPUTS_UNLOCKED:
       case BUILT_IN_FWRITE_UNLOCKED:
+      case BUILT_IN_FPRINTF_UNLOCKED:
       case BUILT_IN_FLOOR:
       case BUILT_IN_FLOORF:
       case BUILT_IN_FLOORL:
@@ -5167,13 +5392,38 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       expand_builtin_trap ();
       return const0_rtx;
 
+    case BUILT_IN_PRINTF:
+      target = expand_builtin_printf (arglist, target, mode, false);
+      if (target)
+       return target;
+      break;
+
+    case BUILT_IN_PRINTF_UNLOCKED:
+      target = expand_builtin_printf (arglist, target, mode, true);
+      if (target)
+       return target;
+      break;
+
     case BUILT_IN_FPUTS:
-      target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
+      target = expand_builtin_fputs (arglist, target, false);
       if (target)
        return target;
       break;
+
     case BUILT_IN_FPUTS_UNLOCKED:
-      target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
+      target = expand_builtin_fputs (arglist, target, true);
+      if (target)
+       return target;
+      break;
+
+    case BUILT_IN_FPRINTF:
+      target = expand_builtin_fprintf (arglist, target, mode, false);
+      if (target)
+       return target;
+      break;
+
+    case BUILT_IN_FPRINTF_UNLOCKED:
+      target = expand_builtin_fprintf (arglist, target, mode, true);
       if (target)
        return target;
       break;
index 0eaba889dcb70f48631ca238bd3f9e2f571a4aa1..e05795d5ca5fd4dff382ac01c9dda547f1c88068 100644 (file)
@@ -70,9 +70,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,     \
                false, false, false, ATTRS, true)
 
-
 /* A fallback builtin is a builtin (like __builtin_puts) that falls
-   back to the corresopnding library function if necessary -- but
+   back to the corresponding library function if necessary -- but
    for which we should not introduce the non-`__builtin' variant of
    the name.  */
 #undef DEF_FALLBACK_BUILTIN                            
@@ -124,21 +123,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,        \
               true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)
 
-/* Like DEF_LIB_BUILTIN, except that the function is expanded in the
-   front-end.  */
-#undef DEF_FRONT_END_LIB_BUILTIN                       
-#define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS)     \
-  DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE,      \
-              true, true, false, ATTRS, true)
-
-/* Like DEF_FRONT_END_LIB_BUILTIN, except that the function is not one
-   that is specified by ANSI/ISO C.  So, when we're being fully
-   conformant we ignore the version of these builtins that does not
-   begin with __builtin.  */
-#undef DEF_EXT_FRONT_END_LIB_BUILTIN                   
-#define DEF_EXT_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
-  DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE,      \
-              true, true, true, ATTRS, true)
 
 DEF_EXT_LIB_BUILTIN(BUILT_IN_ALLOCA,
                    "__builtin_alloca",
@@ -769,10 +753,10 @@ DEF_GCC_BUILTIN(BUILT_IN_PREFETCH,
 
 /* stdio.h builtins (without FILE *).  */
 
-DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF,
-                         "__builtin_printf",
-                         BT_FN_INT_CONST_STRING_VAR,
-                         ATTR_FORMAT_PRINTF_1_2)
+DEF_LIB_BUILTIN(BUILT_IN_PRINTF,
+               "__builtin_printf",
+               BT_FN_INT_CONST_STRING_VAR,
+               ATTR_FORMAT_PRINTF_1_2)
 DEF_LIB_BUILTIN(BUILT_IN_PUTCHAR,
                "__builtin_putchar",
                BT_FN_INT_INT,
@@ -840,10 +824,10 @@ DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
                     "__builtin_fwrite",
                     BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
                      ATTR_NOTHROW_NONNULL_1_4)
-DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF,
-                        "__builtin_fprintf",
-                        BT_FN_INT_PTR_CONST_STRING_VAR,
-                        ATTR_FORMAT_PRINTF_2_3)
+DEF_LIB_BUILTIN(BUILT_IN_FPRINTF,
+               "__builtin_fprintf",
+               BT_FN_INT_PTR_CONST_STRING_VAR,
+               ATTR_FORMAT_PRINTF_2_3)
 
 /* stdio unlocked builtins (without FILE *).  */
 
@@ -853,10 +837,10 @@ DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR_UNLOCKED,
 DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTS_UNLOCKED,
                         "__builtin_puts_unlocked",
                         BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1)
-DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF_UNLOCKED,
-                             "__builtin_printf_unlocked",
-                             BT_FN_INT_CONST_STRING_VAR,
-                             ATTR_FORMAT_PRINTF_1_2)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_PRINTF_UNLOCKED,
+                   "__builtin_printf_unlocked",
+                   BT_FN_INT_CONST_STRING_VAR,
+                   ATTR_FORMAT_PRINTF_1_2)
 
 /* stdio unlocked builtins (with FILE *).  */
 
@@ -876,11 +860,12 @@ DEF_BUILTIN (BUILT_IN_FPUTS_UNLOCKED,
             true, true, true, ATTR_NOTHROW_NONNULL_1_2, true)
 DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FWRITE_UNLOCKED,
                         "__builtin_fwrite_unlocked",
-                        BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, ATTR_NOTHROW_NONNULL_1_4)
-DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF_UNLOCKED,
-                             "__builtin_fprintf_unlocked",
-                             BT_FN_INT_PTR_CONST_STRING_VAR,
-                             ATTR_FORMAT_PRINTF_2_3)
+                        BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
+                        ATTR_NOTHROW_NONNULL_1_4)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_FPRINTF_UNLOCKED,
+                   "__builtin_fprintf_unlocked",
+                   BT_FN_INT_PTR_CONST_STRING_VAR,
+                   ATTR_FORMAT_PRINTF_2_3)
 
   /* ISO C99 floating point unordered comparisons.  */
 DEF_GCC_BUILTIN(BUILT_IN_ISGREATER, 
index 685ec2cae7d51c2263fbbdda9474b93e46b57421..2e985c2a4d2c32d4bb93fcab67363ee6b9a13923 100644 (file)
@@ -1175,14 +1175,6 @@ fix_string_type (tree value)
   return value;
 }
 \f
-static int is_valid_printf_arglist (tree);
-static rtx c_expand_builtin (tree, rtx, enum machine_mode,
-                            enum expand_modifier);
-static rtx c_expand_builtin_printf (tree, rtx, enum machine_mode,
-                                   enum expand_modifier, int, int);
-static rtx c_expand_builtin_fprintf (tree, rtx, enum machine_mode,
-                                    enum expand_modifier, int, int);
-\f
 /* Print a warning if a constant expression had overflow in folding.
    Invoke this function on every expression that the language
    requires to be a constant expression.
@@ -4053,20 +4045,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier)
       }
       break;
 
-    case CALL_EXPR:
-      {
-       if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
-           && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-               == FUNCTION_DECL)
-           && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-           && (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
-               == BUILT_IN_FRONTEND))
-         return c_expand_builtin (exp, target, tmode, modifier);
-       else
-         abort ();
-      }
-      break;
-
     case COMPOUND_LITERAL_EXPR:
       {
        /* Initialize the anonymous variable declared in the compound
@@ -4135,280 +4113,6 @@ c_staticp (tree exp)
     return 1;
   return 0;
 }
-
-#define CALLED_AS_BUILT_IN(NODE) \
-   (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
-
-static rtx
-c_expand_builtin (tree exp, rtx target, enum machine_mode tmode,
-                 enum expand_modifier modifier)
-{
-  tree type = TREE_TYPE (exp);
-  tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
-  tree arglist = TREE_OPERAND (exp, 1);
-  enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
-  enum tree_code code = TREE_CODE (exp);
-  const int ignore = (target == const0_rtx
-                     || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
-                          || code == CONVERT_EXPR || code == REFERENCE_EXPR
-                          || code == COND_EXPR)
-                         && TREE_CODE (type) == VOID_TYPE));
-
-  if (! optimize && ! CALLED_AS_BUILT_IN (fndecl))
-    return expand_call (exp, target, ignore);
-
-  switch (fcode)
-    {
-    case BUILT_IN_PRINTF:
-      target = c_expand_builtin_printf (arglist, target, tmode,
-                                       modifier, ignore, /*unlocked=*/ 0);
-      if (target)
-       return target;
-      break;
-
-    case BUILT_IN_PRINTF_UNLOCKED:
-      target = c_expand_builtin_printf (arglist, target, tmode,
-                                       modifier, ignore, /*unlocked=*/ 1);
-      if (target)
-       return target;
-      break;
-
-    case BUILT_IN_FPRINTF:
-      target = c_expand_builtin_fprintf (arglist, target, tmode,
-                                        modifier, ignore, /*unlocked=*/ 0);
-      if (target)
-       return target;
-      break;
-
-    case BUILT_IN_FPRINTF_UNLOCKED:
-      target = c_expand_builtin_fprintf (arglist, target, tmode,
-                                        modifier, ignore, /*unlocked=*/ 1);
-      if (target)
-       return target;
-      break;
-
-    default:                   /* just do library call, if unknown builtin */
-      error ("built-in function `%s' not currently supported",
-            IDENTIFIER_POINTER (DECL_NAME (fndecl)));
-    }
-
-  /* The switch statement above can drop through to cause the function
-     to be called normally.  */
-  return expand_call (exp, target, ignore);
-}
-
-/* Check an arglist to *printf for problems.  The arglist should start
-   at the format specifier, with the remaining arguments immediately
-   following it.  */
-static int
-is_valid_printf_arglist (tree arglist)
-{
-  /* Save this value so we can restore it later.  */
-  const int SAVE_pedantic = pedantic;
-  int diagnostic_occurred = 0;
-  tree attrs;
-
-  /* Set this to a known value so the user setting won't affect code
-     generation.  */
-  pedantic = 1;
-  /* Check to make sure there are no format specifier errors.  */
-  attrs = tree_cons (get_identifier ("format"),
-                    tree_cons (NULL_TREE,
-                               get_identifier ("printf"),
-                               tree_cons (NULL_TREE,
-                                          integer_one_node,
-                                          tree_cons (NULL_TREE,
-                                                     build_int_2 (2, 0),
-                                                     NULL_TREE))),
-                    NULL_TREE);
-  check_function_format (&diagnostic_occurred, attrs, arglist);
-
-  /* Restore the value of `pedantic'.  */
-  pedantic = SAVE_pedantic;
-
-  /* If calling `check_function_format_ptr' produces a warning, we
-     return false, otherwise we return true.  */
-  return ! diagnostic_occurred;
-}
-
-/* If the arguments passed to printf are suitable for optimizations,
-   we attempt to transform the call.  */
-static rtx
-c_expand_builtin_printf (tree arglist, rtx target, enum machine_mode tmode,
-                        enum expand_modifier modifier, int ignore,
-                        int unlocked)
-{
-  tree fn_putchar = unlocked ?
-    implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR];
-  tree fn_puts = unlocked ?
-    implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS];
-  tree fn, format_arg, stripped_string;
-
-  /* If the return value is used, or the replacement _DECL isn't
-     initialized, don't do the transformation.  */
-  if (!ignore || !fn_putchar || !fn_puts)
-    return 0;
-
-  /* Verify the required arguments in the original call.  */
-  if (arglist == 0
-      || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE))
-    return 0;
-
-  /* Check the specifier vs. the parameters.  */
-  if (!is_valid_printf_arglist (arglist))
-    return 0;
-
-  format_arg = TREE_VALUE (arglist);
-  stripped_string = format_arg;
-  STRIP_NOPS (stripped_string);
-  if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
-    stripped_string = TREE_OPERAND (stripped_string, 0);
-
-  /* If the format specifier isn't a STRING_CST, punt.  */
-  if (TREE_CODE (stripped_string) != STRING_CST)
-    return 0;
-
-  /* OK!  We can attempt optimization.  */
-
-  /* If the format specifier was "%s\n", call __builtin_puts(arg2).  */
-  if (strcmp (TREE_STRING_POINTER (stripped_string), "%s\n") == 0)
-    {
-      arglist = TREE_CHAIN (arglist);
-      fn = fn_puts;
-    }
-  /* If the format specifier was "%c", call __builtin_putchar (arg2).  */
-  else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
-    {
-      arglist = TREE_CHAIN (arglist);
-      fn = fn_putchar;
-    }
-  else
-    {
-      /* We can't handle anything else with % args or %% ... yet.  */
-      if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
-       return 0;
-
-      /* If the resulting constant string has a length of 1, call
-         putchar.  Note, TREE_STRING_LENGTH includes the terminating
-         NULL in its count.  */
-      if (TREE_STRING_LENGTH (stripped_string) == 2)
-        {
-         /* Given printf("c"), (where c is any one character,)
-             convert "c"[0] to an int and pass that to the replacement
-             function.  */
-         arglist = build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0);
-         arglist = build_tree_list (NULL_TREE, arglist);
-
-         fn = fn_putchar;
-        }
-      /* If the resulting constant was "string\n", call
-         __builtin_puts("string").  Ensure "string" has at least one
-         character besides the trailing \n.  Note, TREE_STRING_LENGTH
-         includes the terminating NULL in its count.  */
-      else if (TREE_STRING_LENGTH (stripped_string) > 2
-              && TREE_STRING_POINTER (stripped_string)
-              [TREE_STRING_LENGTH (stripped_string) - 2] == '\n')
-        {
-         /* Create a NULL-terminated string that's one char shorter
-            than the original, stripping off the trailing '\n'.  */
-         const int newlen = TREE_STRING_LENGTH (stripped_string) - 1;
-         char *newstr = alloca (newlen);
-         memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1);
-         newstr[newlen - 1] = 0;
-
-         arglist = fix_string_type (build_string (newlen, newstr));
-         arglist = build_tree_list (NULL_TREE, arglist);
-         fn = fn_puts;
-       }
-      else
-       /* We'd like to arrange to call fputs(string) here, but we
-           need stdout and don't have a way to get it ... yet.  */
-       return 0;
-    }
-
-  return expand_expr (build_function_call (fn, arglist),
-                     (ignore ? const0_rtx : target),
-                     tmode, modifier);
-}
-
-/* If the arguments passed to fprintf are suitable for optimizations,
-   we attempt to transform the call.  */
-static rtx
-c_expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode tmode,
-                         enum expand_modifier modifier, int ignore,
-                         int unlocked)
-{
-  tree fn_fputc = unlocked ?
-    implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC];
-  tree fn_fputs = unlocked ?
-    implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS];
-  tree fn, format_arg, stripped_string;
-
-  /* If the return value is used, or the replacement _DECL isn't
-     initialized, don't do the transformation.  */
-  if (!ignore || !fn_fputc || !fn_fputs)
-    return 0;
-
-  /* Verify the required arguments in the original call.  */
-  if (arglist == 0
-      || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
-      || (TREE_CHAIN (arglist) == 0)
-      || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) !=
-         POINTER_TYPE))
-    return 0;
-
-  /* Check the specifier vs. the parameters.  */
-  if (!is_valid_printf_arglist (TREE_CHAIN (arglist)))
-    return 0;
-
-  format_arg = TREE_VALUE (TREE_CHAIN (arglist));
-  stripped_string = format_arg;
-  STRIP_NOPS (stripped_string);
-  if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
-    stripped_string = TREE_OPERAND (stripped_string, 0);
-
-  /* If the format specifier isn't a STRING_CST, punt.  */
-  if (TREE_CODE (stripped_string) != STRING_CST)
-    return 0;
-
-  /* OK!  We can attempt optimization.  */
-
-  /* If the format specifier was "%s", call __builtin_fputs(arg3, arg1).  */
-  if (strcmp (TREE_STRING_POINTER (stripped_string), "%s") == 0)
-    {
-      tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
-      arglist = tree_cons (NULL_TREE,
-                          TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
-                          newarglist);
-      fn = fn_fputs;
-    }
-  /* If the format specifier was "%c", call __builtin_fputc (arg3, arg1).  */
-  else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
-    {
-      tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
-      arglist = tree_cons (NULL_TREE,
-                          TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
-                          newarglist);
-      fn = fn_fputc;
-    }
-  else
-    {
-      /* We can't handle anything else with % args or %% ... yet.  */
-      if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
-       return 0;
-
-      /* When "string" doesn't contain %, replace all cases of
-         fprintf(stream,string) with fputs(string,stream).  The fputs
-         builtin will take take of special cases like length==1.  */
-      arglist = tree_cons (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)),
-                          build_tree_list (NULL_TREE, TREE_VALUE (arglist)));
-      fn = fn_fputs;
-    }
-
-  return expand_expr (build_function_call (fn, arglist),
-                     (ignore ? const0_rtx : target),
-                     tmode, modifier);
-}
 \f
 
 /* Given a boolean expression ARG, return a tree representing an increment