RFC: patch for builtin unlocked stdio (tester wanted!)
Kaveh R. Ghazi
ghazi@caip.rutgers.edu
Sat Nov 17 06:08:00 GMT 2001
This patch adds builtins for the *_unlocked stdio functions
corresponding to the same optimizations we do for the regular stdio
functions.
The POSIX Threads Extension (1003.1c-1995) defines a few of the
unlocked functions like putc_unlocked, etc. However I believe the
high level ones like printf are all glibc extensions anyway so I put
them under the "nonansi" exclusion.
I tested this a bit on my solaris2 box to make sure it DTRT by
manually inspecting assembly on some test input. However since
solaris2's libc doesn't have the appropriate _unlocked functions I
cannot do much more than that.
I couldn't think of a good testcase yet. I'm wondering how best to do
that given that the _unlocked functions don't always exist on a
platform.
Since gcc/system.h defines many stdio functions in terms of their
_unlocked counterparts if they exist, I'd like to solicit a volunteer
to test this on a platform using glibc with a full bootstrap and
testsuite run to completely test it.
Also comments are welcome.
Thanks,
--Kaveh
2001-11-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* builtin-attrs.def (__builtin_printf_unlocked,
__builtin_fprintf_unlocked, printf_unlocked, fprintf_unlocked):
Mark with the __printf__ attribute.
* builtins.c (expand_builtin_fputs): Add an `unlocked' parameter
and set the replacement function depending on it.
(expand_builtin): Skip BUILT_IN_*_UNLOCKED when not optimizing.
Handle BUILT_IN_*_UNLOCKED when optimizing.
* builtins.def (DEF_EXT_FALLBACK_BUILTIN,
DEF_EXT_FRONT_END_LIB_BUILTIN): New macros.
Declare the "unlocked" stdio functions.
* c-common.c (c_expand_builtin_printf, c_expand_builtin_fprintf):
Add an `unlocked' parameter and set the replacement function
depending on it.
(c_expand_builtin): Handle BUILT_IN_PRINTF_UNLOCKED and
BUILT_IN_FPRINTF_UNLOCKED.
* doc/extend.texi (printf_unlocked, fprintf_unlocked,
fputs_unlocked): Document.
diff -rup orig/egcc-CVS20011127/gcc/builtin-attrs.def egcc-CVS20011127/gcc/builtin-attrs.def
--- orig/egcc-CVS20011127/gcc/builtin-attrs.def Tue Oct 2 03:12:20 2001
+++ egcc-CVS20011127/gcc/builtin-attrs.def Tue Nov 27 22:04:05 2001
@@ -125,6 +125,15 @@ DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_2, A
-ffreestanding. */
DEF_FN_ATTR_IDENT (__builtin_printf, ATTR_FORMAT_PRINTF_1_2, true)
DEF_FN_ATTR_IDENT (__builtin_fprintf, ATTR_FORMAT_PRINTF_2_3, true)
+DEF_FN_ATTR_IDENT (__builtin_printf_unlocked, ATTR_FORMAT_PRINTF_1_2, true)
+DEF_FN_ATTR_IDENT (__builtin_fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3, true)
+
+/* Extension functions outside the various C standards. */
+#define DEF_EXTENSION_ATTR(NAME, ATTRS) \
+ DEF_FN_ATTR_IDENT (NAME, ATTRS, (flag_hosted && !flag_no_nonansi_builtin))
+DEF_EXTENSION_ATTR (printf_unlocked, ATTR_FORMAT_PRINTF_1_2)
+DEF_EXTENSION_ATTR (fprintf_unlocked, ATTR_FORMAT_PRINTF_2_3)
+#undef DEF_EXTENSION_ATTR
/* Functions from ISO/IEC 9899:1990. */
#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
diff -rup orig/egcc-CVS20011127/gcc/builtins.c egcc-CVS20011127/gcc/builtins.c
--- orig/egcc-CVS20011127/gcc/builtins.c Fri Nov 16 07:30:12 2001
+++ egcc-CVS20011127/gcc/builtins.c Tue Nov 27 22:35:05 2001
@@ -139,7 +139,7 @@ static rtx expand_builtin_strrchr PARAMS
static rtx expand_builtin_alloca PARAMS ((tree, rtx));
static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
static rtx expand_builtin_frame_address PARAMS ((tree));
-static rtx expand_builtin_fputs PARAMS ((tree, int));
+static rtx expand_builtin_fputs PARAMS ((tree, int, int));
static tree stabilize_va_list PARAMS ((tree, int));
static rtx expand_builtin_expect PARAMS ((tree, rtx));
static tree fold_builtin_constant_p PARAMS ((tree));
@@ -3203,12 +3203,16 @@ expand_builtin_ffs (arglist, target, sub
long, we attempt to transform this call into __builtin_fputc(). */
static rtx
-expand_builtin_fputs (arglist, ignore)
+expand_builtin_fputs (arglist, ignore, unlocked)
tree arglist;
int ignore;
+ int unlocked;
{
- tree len, fn, fn_fputc = built_in_decls[BUILT_IN_FPUTC],
- fn_fwrite = built_in_decls[BUILT_IN_FWRITE];
+ tree len, fn;
+ tree fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+ : built_in_decls[BUILT_IN_FWRITE];
/* If the return value is used, or the replacement _DECL isn't
initialized, don't do the transformation. */
@@ -3479,7 +3483,13 @@ expand_builtin (exp, target, subtarget,
|| 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_FWRITE))
+ || fcode == BUILT_IN_FPUTS || fcode == BUILT_IN_FWRITE
+ || fcode == BUILT_IN_PUTCHAR_UNLOCKED
+ || fcode == BUILT_IN_PUTS_UNLOCKED
+ || fcode == BUILT_IN_PRINTF_UNLOCKED
+ || fcode == BUILT_IN_FPUTC_UNLOCKED
+ || fcode == BUILT_IN_FPUTS_UNLOCKED
+ || fcode == BUILT_IN_FWRITE_UNLOCKED))
return expand_call (exp, target, ignore);
switch (fcode)
@@ -3767,9 +3777,18 @@ expand_builtin (exp, target, subtarget,
case BUILT_IN_PUTS:
case BUILT_IN_FPUTC:
case BUILT_IN_FWRITE:
+ case BUILT_IN_PUTCHAR_UNLOCKED:
+ case BUILT_IN_PUTS_UNLOCKED:
+ case BUILT_IN_FPUTC_UNLOCKED:
+ case BUILT_IN_FWRITE_UNLOCKED:
break;
case BUILT_IN_FPUTS:
- target = expand_builtin_fputs (arglist, ignore);
+ target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
+ if (target)
+ return target;
+ break;
+ case BUILT_IN_FPUTS_UNLOCKED:
+ target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
if (target)
return target;
break;
diff -rup orig/egcc-CVS20011127/gcc/builtins.def egcc-CVS20011127/gcc/builtins.def
--- orig/egcc-CVS20011127/gcc/builtins.def Wed Oct 31 16:30:37 2001
+++ egcc-CVS20011127/gcc/builtins.def Tue Nov 27 21:53:16 2001
@@ -70,6 +70,15 @@ Software Foundation, 59 Temple Place - S
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
false, true, false)
+/* Like DEF_FALLBACK_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_FALLBACK_BUILTIN
+#define DEF_EXT_FALLBACK_BUILTIN(ENUM, NAME, TYPE) \
+ DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ false, true, true)
+
/* A library builtin (like __builtin_strchr) is a builtin equivalent
of an ANSI/ISO standard library function. In addition to the
`__builtin' version, we will create an ordinary version (e.g,
@@ -111,6 +120,15 @@ Software Foundation, 59 Temple Place - S
DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
true, true, false)
+/* 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) \
+ DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
+ true, true, true)
+
/* A built-in that is not currently used. */
#undef DEF_UNUSED_BUILTIN
#define DEF_UNUSED_BUILTIN(X) \
@@ -366,6 +384,37 @@ DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF,
"__builtin_fprintf",
BT_FN_INT_PTR_CONST_STRING_VAR)
+
+/* Stdio unlocked builtins. */
+
+DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR_UNLOCKED,
+ "__builtin_putchar_unlocked",
+ BT_FN_INT_INT)
+DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTS_UNLOCKED,
+ "__builtin_puts_unlocked",
+ BT_FN_INT_CONST_STRING)
+DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF_UNLOCKED,
+ "__builtin_printf_unlocked",
+ BT_FN_INT_CONST_STRING_VAR)
+DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FPUTC_UNLOCKED,
+ "__builtin_fputc_unlocked",
+ BT_FN_INT_INT_PTR)
+/* Declare the __builtin_ style with arguments and the regular style
+ without them. We rely on stdio.h to supply the arguments for the
+ regular style declaration since we had to use void* instead of
+ FILE* in the __builtin_ prototype supplied here. */
+DEF_BUILTIN (BUILT_IN_FPUTS_UNLOCKED,
+ "__builtin_fputs_unlocked",
+ BUILT_IN_NORMAL,
+ BT_FN_INT_CONST_STRING_PTR,
+ BT_FN_INT_VAR,
+ true, true, true)
+DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FWRITE_UNLOCKED,
+ "__builtin_fwrite_unlocked",
+ BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
+DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF_UNLOCKED,
+ "__builtin_fprintf_unlocked",
+ BT_FN_INT_PTR_CONST_STRING_VAR)
/* ISO C99 floating point unordered comparisons. */
DEF_GCC_BUILTIN(BUILT_IN_ISGREATER,
diff -rup orig/egcc-CVS20011127/gcc/c-common.c egcc-CVS20011127/gcc/c-common.c
--- orig/egcc-CVS20011127/gcc/c-common.c Tue Nov 27 07:30:45 2001
+++ egcc-CVS20011127/gcc/c-common.c Tue Nov 27 21:53:06 2001
@@ -643,9 +643,9 @@ combine_strings (strings)
static int is_valid_printf_arglist PARAMS ((tree));
static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier));
static rtx c_expand_builtin_printf PARAMS ((tree, rtx, enum machine_mode,
- enum expand_modifier, int));
+ enum expand_modifier, int, int));
static rtx c_expand_builtin_fprintf PARAMS ((tree, rtx, enum machine_mode,
- enum expand_modifier, int));
+ enum expand_modifier, int, int));
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
@@ -3560,14 +3560,28 @@ c_expand_builtin (exp, target, tmode, mo
{
case BUILT_IN_PRINTF:
target = c_expand_builtin_printf (arglist, target, tmode,
- modifier, ignore);
+ 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);
+ 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;
@@ -3620,15 +3634,18 @@ is_valid_printf_arglist (arglist)
/* If the arguments passed to printf are suitable for optimizations,
we attempt to transform the call. */
static rtx
-c_expand_builtin_printf (arglist, target, tmode, modifier, ignore)
+c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked)
tree arglist;
rtx target;
enum machine_mode tmode;
enum expand_modifier modifier;
int ignore;
+ int unlocked;
{
- tree fn_putchar = built_in_decls[BUILT_IN_PUTCHAR],
- fn_puts = built_in_decls[BUILT_IN_PUTS];
+ tree fn_putchar = unlocked ?
+ built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR];
+ tree fn_puts = unlocked ?
+ built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS];
tree fn, format_arg, stripped_string;
/* If the return value is used, or the replacement _DECL isn't
@@ -3721,15 +3738,18 @@ c_expand_builtin_printf (arglist, target
/* If the arguments passed to fprintf are suitable for optimizations,
we attempt to transform the call. */
static rtx
-c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore)
+c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked)
tree arglist;
rtx target;
enum machine_mode tmode;
enum expand_modifier modifier;
int ignore;
+ int unlocked;
{
- tree fn_fputc = built_in_decls[BUILT_IN_FPUTC],
- fn_fputs = built_in_decls[BUILT_IN_FPUTS];
+ tree fn_fputc = unlocked ?
+ built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fputs = unlocked ?
+ built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS];
tree fn, format_arg, stripped_string;
/* If the return value is used, or the replacement _DECL isn't
diff -rup orig/egcc-CVS20011127/gcc/doc/extend.texi egcc-CVS20011127/gcc/doc/extend.texi
--- orig/egcc-CVS20011127/gcc/doc/extend.texi Sat Nov 17 23:19:02 2001
+++ egcc-CVS20011127/gcc/doc/extend.texi Tue Nov 27 21:49:50 2001
@@ -2096,7 +2096,8 @@ warnings are requested (using @option{-W
modify the header file @file{stdio.h}. In C99 mode, the functions
@code{snprintf}, @code{vsnprintf}, @code{vscanf}, @code{vfscanf} and
@code{vsscanf} are also checked. Except in strictly conforming C
-standard modes, the X/Open function @code{strfmon} is also checked.
+standard modes, the X/Open function @code{strfmon} is also checked as
+are @code{printf_unlocked} and @code{fprintf_unlocked}.
@xref{C Dialect Options,,Options Controlling C Dialect}.
@item format_arg (@var{string-index})
@@ -4298,7 +4299,9 @@ v4si f (v4si a, v4si b, v4si c)
@findex fabsl
@findex ffs
@findex fprintf
+@findex fprintf_unlocked
@findex fputs
+@findex fputs_unlocked
@findex imaxabs
@findex index
@findex labs
@@ -4307,6 +4310,7 @@ v4si f (v4si a, v4si b, v4si c)
@findex memcpy
@findex memset
@findex printf
+@findex printf_unlocked
@findex rindex
@findex sin
@findex sinf
@@ -4354,8 +4358,9 @@ in. @code{_exit} is not recognized in s
strict C89 mode (@option{-ansi} or @option{-std=c89}).
Outside strict ISO C mode, the functions @code{alloca}, @code{bcmp},
-@code{bzero}, @code{index}, @code{rindex} and @code{ffs} may be handled
-as built-in functions. All these functions have corresponding versions
+@code{bzero}, @code{index}, @code{rindex}, @code{ffs}, @code{fputs_unlocked},
+@code{printf_unlocked} and @code{fprintf_unlocked} may be handled as
+built-in functions. All these functions have corresponding versions
prefixed with @code{__builtin_}, which may be used even in strict C89
mode.
More information about the Gcc-patches
mailing list