This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[3.4 Patch] Fix PR 25022, failure to transform the unlocked stdio calls


This patch addresses PR middle-end/25022 (a regression from gcc-3.3)
for the 3.4 branch.  The fix has already been applied to 4.0, 4,1 and
mainline.

Bootstrapped/regtested on i686-unknown-linux-gnu.

Okay for 3.4?

		Thanks,
		--Kaveh


2005-12-03  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	PR middle-end/25022
	* builtins.c (expand_builtin_fputs, expand_builtin_printf,
	expand_builtin_fprintf): Lookup the explicit replacement functions
	for any unlocked stdio builtin transformations.

	* builtins.c (expand_builtin_fputs): Defer check for missing
	replacement functions.

testsuite:
	* gcc.c-torture/execute/stdio-opt-1.c,
	gcc.c-torture/execute/stdio-opt-2.c,
	gcc.c-torture/execute/stdio-opt-3.c: Test the unlocked style.
	
diff -rup orig/egcc-3.4-SVN20051203/gcc/builtins.c egcc-3.4-SVN20051203/gcc/builtins.c
--- orig/egcc-3.4-SVN20051203/gcc/builtins.c	2005-11-03 11:02:46.000000000 -0500
+++ egcc-3.4-SVN20051203/gcc/builtins.c	2005-12-03 16:24:46.000000000 -0500
@@ -4329,14 +4329,15 @@ static rtx
 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
 {
   tree len, fn;
-  tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+  /* If we're using an unlocked function, assume the other unlocked
+     functions exist explicitly.  */
+  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
     : implicit_built_in_decls[BUILT_IN_FPUTC];
-  tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+  tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
     : implicit_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 (target != const0_rtx || !fn_fputc || !fn_fwrite)
+  /* If the return value is used, don't do the transformation.  */
+  if (target != const0_rtx)
     return 0;
 
   /* Verify the arguments in the original call.  */
@@ -4397,6 +4398,11 @@ expand_builtin_fputs (tree arglist, rtx 
       abort ();
     }
 
+  /* If the replacement _DECL isn't initialized, don't do the
+     transformation.  */
+  if (!fn)
+    return 0;
+
   return expand_expr (build_function_call_expr (fn, arglist),
 		      const0_rtx, VOIDmode, EXPAND_NORMAL);
 }
@@ -4651,11 +4657,12 @@ 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];
+  /* If we're using an unlocked function, assume the other unlocked
+     functions exist explicitly.  */
+  tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
+    : implicit_built_in_decls[BUILT_IN_PUTCHAR];
+  tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
+    : implicit_built_in_decls[BUILT_IN_PUTS];
   const char *fmt_str;
   tree fn, fmt, arg;
 
@@ -4754,10 +4761,12 @@ 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];
+  /* If we're using an unlocked function, assume the other unlocked
+     functions exist explicitly.  */
+  tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+    : implicit_built_in_decls[BUILT_IN_FPUTC];
+  tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
+    : implicit_built_in_decls[BUILT_IN_FPUTS];
   const char *fmt_str;
   tree fn, fmt, fp, arg;
 
diff -rup orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-1.c egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-1.c
--- orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-1.c	2005-11-03 11:00:42.000000000 -0500
+++ egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-1.c	2005-12-03 16:54:24.000000000 -0500
@@ -52,6 +52,10 @@ int main()
      prototypes are set correctly too.  */
   __builtin_fputc ('\n', *s_ptr);
   __builtin_fwrite ("hello\n", 1, 6, *s_ptr);
+  /* Check the unlocked style, these evaluate to nothing to avoid
+     problems on systems without the unlocked functions.  */
+  fputs_unlocked ("", *s_ptr);
+  __builtin_fputs_unlocked ("", *s_ptr);
 
   /* Check side-effects in conditional expression.  */
   s_ptr = s_array;
@@ -75,4 +79,16 @@ fputs(const char *string, FILE *stream)
 {
   abort();
 }
+
+#endif
+
+/* Locking stdio doesn't matter for the purposes of this test.  */
+static int __attribute__ ((__noinline__))
+fputs_unlocked(const char *string, FILE *stream)
+{
+#ifdef __OPTIMIZE__
+  abort();
+#else
+  return fputs (string, stream);
 #endif
+}
diff -rup orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-2.c egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-2.c
--- orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-2.c	2005-11-03 11:00:42.000000000 -0500
+++ egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-2.c	2005-12-03 16:56:31.000000000 -0500
@@ -5,7 +5,10 @@
 
    Written by Kaveh R. Ghazi, 12/4/2000.  */
 
+#include <stdio.h>
+#include <stdarg.h>
 extern int printf (const char *, ...);
+extern int printf_unlocked (const char *, ...);
 extern void abort(void);
 
 int main()
@@ -27,6 +30,7 @@ int main()
   if (s3 != s2+1 || *s3 != 0)
     abort();
   
+  printf ("");
   printf ("\n");
   printf ("hello world\n");
   
@@ -37,6 +41,10 @@ int main()
      prototypes are set correctly too.  */
   __builtin_putchar ('\n');
   __builtin_puts ("hello");
+  /* Check the unlocked style, these evaluate to nothing to avoid
+     problems on systems without the unlocked functions.  */
+  printf_unlocked ("");
+  __builtin_printf_unlocked ("");
 
   return 0;
 }
@@ -52,3 +60,19 @@ printf (const char *string, ...)
   abort();
 }
 #endif
+
+/* Locking stdio doesn't matter for the purposes of this test.  */
+static int __attribute__ ((__noinline__))
+printf_unlocked (const char *string, ...)
+{
+#ifdef __OPTIMIZE__
+  abort();
+#else
+  va_list ap;
+  int r;
+  va_start (ap, string);
+  r = vprintf (string, ap);
+  va_end (ap);
+  return r;
+#endif
+}
diff -rup orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-3.c egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-3.c
--- orig/egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-3.c	2005-11-03 11:00:42.000000000 -0500
+++ egcc-3.4-SVN20051203/gcc/testsuite/gcc.c-torture/execute/stdio-opt-3.c	2005-12-03 16:57:10.000000000 -0500
@@ -6,6 +6,8 @@
    Written by Kaveh R. Ghazi, 1/7/2001.  */
 
 #include <stdio.h>
+#include <stdarg.h>
+extern int fprintf_unlocked (FILE *, const char *, ...);
 extern int fprintf (FILE *, const char *, ...);
 extern void abort(void);
 
@@ -15,6 +17,8 @@ int main()
   const char *const s1 = "hello world";
   const char *const s2[] = { s1, 0 }, *const*s3;
   
+  fprintf (*s_ptr, "");
+  fprintf (*s_ptr, "%s", "");
   fprintf (*s_ptr, "%s", "hello");
   fprintf (*s_ptr, "%s", "\n");
   fprintf (*s_ptr, "%s", *s2);
@@ -49,6 +53,12 @@ int main()
   /* Test at least one instance of the __builtin_ style.  We do this
      to ensure that it works and that the prototype is correct.  */
   __builtin_fprintf (*s_ptr, "%s", "hello world\n");
+  /* Check the unlocked style, these evaluate to nothing to avoid
+     problems on systems without the unlocked functions.  */
+  fprintf_unlocked (*s_ptr, "");
+  __builtin_fprintf_unlocked (*s_ptr, "");
+  fprintf_unlocked (*s_ptr, "%s", "");
+  __builtin_fprintf_unlocked (*s_ptr, "%s", "");
 
   return 0;
 }
@@ -64,3 +74,19 @@ fprintf (FILE *stream, const char *strin
   abort();
 }
 #endif
+
+/* Locking stdio doesn't matter for the purposes of this test.  */
+static int __attribute__ ((__noinline__))
+fprintf_unlocked (FILE *stream, const char *string, ...)
+{
+#ifdef __OPTIMIZE__
+  abort();
+#else
+  va_list ap;
+  int r;
+  va_start (ap, string);
+  r = vfprintf (stream, string, ap);
+  va_end (ap);
+  return r;
+#endif
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]