From fb9c0b3360928887038a296c338025ced68e2d8c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 2 Oct 2005 21:24:12 +0000 Subject: [PATCH] Use unlocked I/O for a minor performance improvement on hosts like GNU/Linux and Solaris that support unlocked I/O. The basic idea is to use the gnlib unlocked-io module, and to prefer putc and puts to printf when either will work (since the latter doesn't come in an unlocked flavor). * bootstrap (gnulib_modules): Add unlocked-io. * data/c.m4 (yysymprint): Prefer puts and putc to printf. * data/glr.c (YYFPUTC, YYFPUTS, YYDPUTS): New macros. Prefer them to YYFPRINTF and YYDPRINTF if either will do, and similarly for puts and putc and printf. * data/yacc.c: Likewise. * lib/bitset.c (bitset_print): Likewise. * lib/bitset.h [USE_UNLOCKED_IO]: Include unlocked-io.h. * lib/bitsetv.c (bitsetv_dump, debug-bitsetv): Prefer putc and puts to printf. * lib/lbitset.c (debug_lbitset): Likewise. * src/closure.c (print_firsts, print_fderives): Likewise. * src/gram.c (grammar_dump): Likewise. * src/lalr.c (look_ahead_tokens_print): Likewise. * src/output.c (escaped_output): Likewise. (user_actions_output): Coalesce two printfs. * src/parse-gram.h (%printer): Prefer putc and puts to printf. * src/reduce.c (reduce_print): Likewise. * src/state.c (state_rule_look_ahead_tokens_print): Likewise. * src/system.h: Include unlocked-io.h rathe than stdio.h. --- ChangeLog | 26 +++++++++++++++++++++++ bootstrap | 1 + data/c.m4 | 4 ++-- data/glr.c | 55 +++++++++++++++++++++++++++++------------------- data/yacc.c | 29 +++++++++++++++++++------ lib/bitset.c | 4 ++-- lib/bitset.h | 4 ++++ lib/bitsetv.c | 4 ++-- lib/lbitset.c | 2 +- src/closure.c | 8 +++---- src/gram.c | 19 +++++++++-------- src/lalr.c | 4 ++-- src/output.c | 7 +++--- src/parse-gram.y | 2 +- src/reduce.c | 2 +- src/state.c | 4 ++-- src/system.h | 3 ++- 17 files changed, 118 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index a34dd47d..888421cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,31 @@ 2005-10-02 Paul Eggert + Use unlocked I/O for a minor performance improvement on hosts like + GNU/Linux and Solaris that support unlocked I/O. The basic idea + is to use the gnlib unlocked-io module, and to prefer putc and + puts to printf when either will work (since the latter doesn't + come in an unlocked flavor). + * bootstrap (gnulib_modules): Add unlocked-io. + * data/c.m4 (yysymprint): Prefer puts and putc to printf. + * data/glr.c (YYFPUTC, YYFPUTS, YYDPUTS): New macros. + Prefer them to YYFPRINTF and YYDPRINTF if either will do, + and similarly for puts and putc and printf. + * data/yacc.c: Likewise. + * lib/bitset.c (bitset_print): Likewise. + * lib/bitset.h [USE_UNLOCKED_IO]: Include unlocked-io.h. + * lib/bitsetv.c (bitsetv_dump, debug-bitsetv): Prefer putc and puts + to printf. + * lib/lbitset.c (debug_lbitset): Likewise. + * src/closure.c (print_firsts, print_fderives): Likewise. + * src/gram.c (grammar_dump): Likewise. + * src/lalr.c (look_ahead_tokens_print): Likewise. + * src/output.c (escaped_output): Likewise. + (user_actions_output): Coalesce two printfs. + * src/parse-gram.h (%printer): Prefer putc and puts to printf. + * src/reduce.c (reduce_print): Likewise. + * src/state.c (state_rule_look_ahead_tokens_print): Likewise. + * src/system.h: Include unlocked-io.h rathe than stdio.h. + * data/lalr1.cc: Don't put an unmatched ' in a dnl comment, as this confuses xgettext. diff --git a/bootstrap b/bootstrap index ce5fc487..4b3164a3 100755 --- a/bootstrap +++ b/bootstrap @@ -112,6 +112,7 @@ strerror strtoul strverscmp unistd-safer +unlocked-io verify xalloc xalloc-die diff --git a/data/c.m4 b/data/c.m4 index 03f20ff7..56b749e6 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -431,7 +431,7 @@ b4_location_if([ (void) yylocationp; YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); ]b4_location_if([ YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); + YYFPUTS (": ", yyoutput); ])dnl [ # ifdef YYPRINT @@ -444,6 +444,6 @@ b4_location_if([ (void) yylocationp; [ default: break; } - YYFPRINTF (yyoutput, ")"); + YYFPUTC (')', yyoutput); } ]]) diff --git a/data/glr.c b/data/glr.c index 0f466131..36a98d85 100644 --- a/data/glr.c +++ b/data/glr.c @@ -519,9 +519,14 @@ typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG; #if YYDEBUG -#if ! defined (YYFPRINTF) +# ifdef YYFPRINTF +# define YYFPUTC(Char, Stream) YYFPRINTF (Stream, "%c", Char) +# define YYFPUTS(Char, Stream) YYFPRINTF (Stream, "%s", String) +# else # define YYFPRINTF fprintf -#endif +# define YYFPUTC fputc +# define YYFPUTS fputs +# endif # define YYDPRINTF(Args) \ do { \ @@ -529,6 +534,12 @@ do { \ YYFPRINTF Args; \ } while (0) +# define YYDPUTS(String, Stream) \ +do { \ + if (yydebug) \ + YYFPUTS (String, Stream); \ +} while (0) + ]b4_yysymprint_generate([b4_c_ansi_function_def])[ # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ @@ -538,7 +549,7 @@ do { \ YYFPRINTF (stderr, "%s ", Title); \ yysymprint (stderr, \ Type, Value]b4_location_if([, Location])[); \ - YYFPRINTF (stderr, "\n"); \ + YYFPUTC ('\n', stderr); \ } \ } while (0) @@ -548,6 +559,7 @@ int yydebug; #else /* !YYDEBUG */ +# define YYDPUTS(String, File) # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) @@ -913,7 +925,7 @@ yydestroyGLRState (char const *yymsg, yyGLRState *yys) YYFPRINTF (stderr, "%s unresolved ", yymsg); yysymprint (stderr, yystos[yys->yylrState], &yys->yysemantics.yysval]b4_location_if([, &yys->yyloc])[); - YYFPRINTF (stderr, "\n"); + YYFPUTC ('\n', stderr); } #endif @@ -1178,7 +1190,7 @@ yyundeleteLastStack (yyGLRStack* yystack) return; yystack->yytops.yystates[0] = yystack->yylastDeleted; yystack->yytops.yysize = 1; - YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n")); + YYDPUTS ("Restoring last deleted stack as stack #0.\n", stderr); yystack->yylastDeleted = NULL; } @@ -1193,7 +1205,7 @@ yyremoveDeletes (yyGLRStack* yystack) { if (yyi == yyj) { - YYDPRINTF ((stderr, "Removing dead stacks.\n")); + YYDPUTS ("Removing dead stacks.\n", stderr); } yystack->yytops.yysize -= 1; } @@ -1626,12 +1638,11 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1, (void) yyx1; #if YYDEBUG - YYFPRINTF (stderr, "Ambiguity detected.\n"); - YYFPRINTF (stderr, "Option 1,\n"); + YYFPUTS ("Ambiguity detected.\nOption 1,\n", stderr); yyreportTree (yyx0, 2); - YYFPRINTF (stderr, "\nOption 2,\n"); + YYFPUTS ("\nOption 2,\n", stderr); yyreportTree (yyx1, 2); - YYFPRINTF (stderr, "\n"); + YYFPUTC ('\n', stderr); #endif yyFail (yystack][]b4_pure_args[, YY_("syntax is ambiguous")); } @@ -1787,7 +1798,7 @@ yyprocessOneStack (yyGLRStack* yystack, size_t yyk, { if (*yytokenp == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPUTS ("Reading a token: ", stderr); yychar = YYLEX; *yytokenp = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", *yytokenp, yylvalp, yyllocp); @@ -1970,7 +1981,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack, yydestruct ("Error: discarding", *yytokenp, yylvalp]b4_location_if([, yyllocp])[); } - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPUTS ("Reading a token: ", stderr); yychar = YYLEX; *yytokenp = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", *yytokenp, yylvalp, yyllocp); @@ -2070,7 +2081,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack, YYSTYPE* const yylvalp = &yylval; YYLTYPE* const yyllocp = &yylloc; - YYDPRINTF ((stderr, "Starting parse\n")); + YYDPUTS ("Starting parse\n", stderr); yytoken = YYEMPTY; yylval = yyval_default; @@ -2134,7 +2145,7 @@ b4_syncline([@oline@], [@ofile@])])dnl { if (yytoken == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPUTS ("Reading a token: ", stderr); yychar = YYLEX; yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, yylvalp, yyllocp); @@ -2179,7 +2190,7 @@ b4_syncline([@oline@], [@ofile@])])dnl if (yystack.yytops.yysize == 0) yyFail (&yystack][]b4_lpure_args[, YY_("syntax error")); YYCHK1 (yyresolveStack (&yystack]b4_user_args[)); - YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); + YYDPUTS ("Returning to deterministic operation.\n", stderr); ]b4_location_if([[ yystack.yyerror_range[1].yystate.yyloc = *yyllocp;]])[ yyreportSyntaxError (&yystack, yylvalp, yyllocp]b4_user_args[); goto yyuser_error; @@ -2187,7 +2198,7 @@ b4_syncline([@oline@], [@ofile@])])dnl else if (yystack.yytops.yysize == 1) { YYCHK1 (yyresolveStack (&yystack]b4_user_args[)); - YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); + YYDPUTS ("Returning to deterministic operation.\n", stderr); yycompressStack (&yystack); break; } @@ -2254,7 +2265,7 @@ yy_yypstack (yyGLRState* yys) if (yys->yypred) { yy_yypstack (yys->yypred); - fprintf (stderr, " -> "); + fputs (" -> ", stderr); } fprintf (stderr, "%d@@%lu", yys->yylrState, (unsigned long int) yys->yyposn); } @@ -2263,10 +2274,10 @@ static void yypstates (yyGLRState* yyst) { if (yyst == NULL) - fprintf (stderr, ""); + fputs ("", stderr); else yy_yypstack (yyst); - fprintf (stderr, "\n"); + fputc ('\n', stderr); } static void @@ -2304,13 +2315,13 @@ yypdumpstack (yyGLRStack* yystack) (long int) YYINDEX (yyp->yyoption.yystate), (long int) YYINDEX (yyp->yyoption.yynext)); } - fprintf (stderr, "\n"); + fputc ('\n', stderr); } - fprintf (stderr, "Tops:"); + fputs ("Tops:", stderr); for (yyi = 0; yyi < yystack->yytops.yysize; yyi += 1) fprintf (stderr, "%lu: %ld; ", (unsigned long int) yyi, (long int) YYINDEX (yystack->yytops.yystates[yyi])); - fprintf (stderr, "\n"); + fputc ('\n', stderr); } #endif ] diff --git a/data/yacc.c b/data/yacc.c index cbce25b1..a8b4e6c9 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -604,9 +604,14 @@ while (0) /* Enable debugging if requested. */ #if YYDEBUG -# ifndef YYFPRINTF +# ifdef YYFPRINTF +# define YYFPUTC(Char, Stream) YYFPRINTF (Stream, "%c", Char) +# define YYFPUTS(Char, Stream) YYFPRINTF (Stream, "%s", String) +# else # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf +# define YYFPUTC fputc +# define YYFPUTS fputs # endif # define YYDPRINTF(Args) \ @@ -615,6 +620,12 @@ do { \ YYFPRINTF Args; \ } while (0) +# define YYDPUTS(String, Stream) \ +do { \ + if (yydebug) \ + YYFPUTS (String, Stream); \ +} while (0) + # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ do { \ if (yydebug) \ @@ -622,7 +633,7 @@ do { \ YYFPRINTF (stderr, "%s ", Title); \ yysymprint (stderr, \ Type, Value]b4_location_if([, Location])[); \ - YYFPRINTF (stderr, "\n"); \ + YYFPUTC ('\n', stderr); \ } \ } while (0) @@ -635,10 +646,10 @@ do { \ [[short int *bottom], [bottom]], [[short int *top], [top]])[ { - YYFPRINTF (stderr, "Stack now"); + YYFPUTS ("Stack now", stderr); for (/* Nothing. */; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); + YYFPUTC ('\n', stderr); } # define YY_STACK_PRINT(Bottom, Top) \ @@ -674,11 +685,15 @@ do { \ /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; + #else /* !YYDEBUG */ + +# define YYDPUTS(String, File) # define YYDPRINTF(Args) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) + #endif /* !YYDEBUG */ @@ -1020,7 +1035,7 @@ b4_c_function_def([yyparse], [int], b4_parse_param) rule. */ int yylen; - YYDPRINTF ((stderr, "Starting parse\n")); + YYDPUTS ("Starting parse\n", stderr); yystate = 0; yyerrstatus = 0; @@ -1158,14 +1173,14 @@ yybackup: /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ if (yychar == YYEMPTY) { - YYDPRINTF ((stderr, "Reading a token: ")); + YYDPUTS ("Reading a token: ", stderr); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); + YYDPUTS ("Now at end of input.\n", stderr); } else { diff --git a/lib/bitset.c b/lib/bitset.c index ddbef843..24bfb879 100644 --- a/lib/bitset.c +++ b/lib/bitset.c @@ -303,7 +303,7 @@ bitset_print (FILE *file, bitset bset, bool verbose) { if (pos > 70) { - fprintf (file, "\n"); + fputc ('\n', file); pos = 0; } @@ -312,7 +312,7 @@ bitset_print (FILE *file, bitset bset, bool verbose) }; if (verbose) - fprintf (file, "}\n"); + fputs ("}\n", file); } diff --git a/lib/bitset.h b/lib/bitset.h index 0b6aa6b3..45c8818c 100644 --- a/lib/bitset.h +++ b/lib/bitset.h @@ -26,6 +26,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "obstack.h" #include +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif + /* Attributes used to select a bitset implementation. */ enum bitset_attr {BITSET_FIXED = 1, /* Bitset size fixed. */ BITSET_VARIABLE = 2, /* Bitset size variable. */ diff --git a/lib/bitsetv.c b/lib/bitsetv.c index db2aa1af..16fa4c07 100644 --- a/lib/bitsetv.c +++ b/lib/bitsetv.c @@ -153,7 +153,7 @@ bitsetv_dump (FILE *file, char const *title, char const *subtitle, bitset_dump (file, bsetv[i]); } - fprintf (file, "\n"); + fputc ('\n', file); } @@ -168,5 +168,5 @@ debug_bitsetv (bitsetv bsetv) debug_bitset (bsetv[i]); } - fprintf (stderr, "\n"); + fputc ('\n', stderr); } diff --git a/lib/lbitset.c b/lib/lbitset.c index 9d3d9573..b1fbd77c 100644 --- a/lib/lbitset.c +++ b/lib/lbitset.c @@ -1400,7 +1400,7 @@ debug_lbitset (bitset bset) for (j = 0; j < LBITSET_WORD_BITS; j++) if ((word & ((bitset_word) 1 << j))) fprintf (stderr, " %u", j); - fprintf (stderr, "\n"); + fputc ('\n', stderr); } } } diff --git a/src/closure.c b/src/closure.c index eb53ee05..8652a22b 100644 --- a/src/closure.c +++ b/src/closure.c @@ -75,7 +75,7 @@ print_firsts (void) { symbol_number i, j; - fprintf (stderr, "FIRSTS\n"); + fputs ("FIRSTS\n", stderr); for (i = ntokens; i < nsyms; i++) { bitset_iterator iter; @@ -86,7 +86,7 @@ print_firsts (void) symbols[j + ntokens]->tag); } } - fprintf (stderr, "\n\n"); + fputs ("\n\n", stderr); } @@ -96,7 +96,7 @@ print_fderives (void) int i; rule_number r; - fprintf (stderr, "FDERIVES\n"); + fputs ("FDERIVES\n", stderr); for (i = ntokens; i < nsyms; i++) { bitset_iterator iter; @@ -107,7 +107,7 @@ print_fderives (void) rule_rhs_print (&rules[r], stderr); } } - fprintf (stderr, "\n\n"); + fputs ("\n\n", stderr); } /*------------------------------------------------------------------. diff --git a/src/gram.c b/src/gram.c index 4636f4e1..dd77a766 100644 --- a/src/gram.c +++ b/src/gram.c @@ -247,23 +247,24 @@ grammar_dump (FILE *out, const char *title) ntokens, nvars, nsyms, nrules, nritems); - fprintf (out, "Variables\n---------\n\n"); + fputs (("Variables\n---------\n\n" + "Value Sprec Sassoc Tag\n"), + out); { symbol_number i; - fprintf (out, "Value Sprec Sassoc Tag\n"); - for (i = ntokens; i < nsyms; i++) fprintf (out, "%5d %5d %5d %s\n", i, symbols[i]->prec, symbols[i]->assoc, symbols[i]->tag); - fprintf (out, "\n\n"); } + fputs ("\n\n", out); - fprintf (out, "Rules\n-----\n\n"); + fputs (("Rules\n-----\n\n" + "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n"), + out); { rule_number i; - fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n"); for (i = 0; i < nrules + nuseless_productions; i++) { rule *rule_i = &rules[i]; @@ -287,9 +288,9 @@ grammar_dump (FILE *out, const char *title) fprintf (out, " [%d]\n", item_number_as_rule_number (*rp)); } } - fprintf (out, "\n\n"); + fputs ("\n\n", out); - fprintf (out, "Rules interpreted\n-----------------\n\n"); + fputs ("Rules interpreted\n-----------------\n\n", out); { rule_number r; for (r = 0; r < nrules + nuseless_productions; r++) @@ -298,7 +299,7 @@ grammar_dump (FILE *out, const char *title) rule_print (&rules[r], out); } } - fprintf (out, "\n\n"); + fputs ("\n\n", out); } diff --git a/src/lalr.c b/src/lalr.c index 8627f1cb..6d72d05a 100644 --- a/src/lalr.c +++ b/src/lalr.c @@ -410,7 +410,7 @@ look_ahead_tokens_print (FILE *out) { state_number i; int j, k; - fprintf (out, "Look-ahead tokens: BEGIN\n"); + fputs ("Look-ahead tokens: BEGIN\n", out); for (i = 0; i < nstates; ++i) { reductions *reds = states[i]->reductions; @@ -434,7 +434,7 @@ look_ahead_tokens_print (FILE *out) reds->rules[j]->number); }; } - fprintf (out, "Look-ahead tokens: END\n"); + fputs ("Look-ahead tokens: END\n", out); } void diff --git a/src/output.c b/src/output.c index 1f3bbcaa..3dcd2287 100644 --- a/src/output.c +++ b/src/output.c @@ -119,7 +119,7 @@ static void escaped_output (FILE *out, char const *string) { char const *p; - fprintf (out, "[["); + fputs ("[[", out); for (p = quotearg_style (c_quoting_style, string); *p; p++) switch (*p) @@ -131,7 +131,7 @@ escaped_output (FILE *out, char const *string) default: fputc (*p, out); break; } - fprintf (out, "]]"); + fputs ("]]", out); } @@ -302,8 +302,7 @@ user_actions_output (FILE *out) fprintf (out, "]b4_syncline(%d, ", rules[r].action_location.start.line); escaped_output (out, rules[r].action_location.start.file); - fprintf (out, ")[\n"); - fprintf (out, " %s\n break;\n\n", + fprintf (out, ")[\n %s\n break;\n\n", rules[r].action); } fputs ("]])\n\n", out); diff --git a/src/parse-gram.y b/src/parse-gram.y index 4a986300..027a773d 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -181,7 +181,7 @@ static int current_prec = 0; %type INT %printer { fprintf (stderr, "%d", $$); } INT %type ID symbol string_as_id -%printer { fprintf (stderr, "%s", $$->tag); } ID symbol string_as_id +%printer { fputs ($$->tag, stderr); } ID symbol string_as_id %type ID_COLON %printer { fprintf (stderr, "%s:", $$->tag); } ID_COLON %type precedence_declarator diff --git a/src/reduce.c b/src/reduce.c index a6b9e629..d53dc159 100644 --- a/src/reduce.c +++ b/src/reduce.c @@ -407,7 +407,7 @@ reduce_print (void) "%d useless rules", nuseless_productions), nuseless_productions); - fprintf (stderr, "\n"); + fputc ('\n', stderr); } void diff --git a/src/state.c b/src/state.c index 89d0c870..8030811a 100644 --- a/src/state.c +++ b/src/state.c @@ -237,13 +237,13 @@ state_rule_look_ahead_tokens_print (state *s, rule *r, FILE *out) bitset_iterator biter; int k; char const *sep = ""; - fprintf (out, " ["); + fputs (" [", out); BITSET_FOR_EACH (biter, reds->look_ahead_tokens[red], k, 0) { fprintf (out, "%s%s", sep, symbols[k]->tag); sep = ", "; } - fprintf (out, "]"); + fputc (']', out); } } diff --git a/src/system.h b/src/system.h index feb851d6..1e161770 100644 --- a/src/system.h +++ b/src/system.h @@ -26,10 +26,11 @@ #include #include -#include #include #include +#include "unlocked-io.h" + #if HAVE_SYS_TYPES_H # include #endif -- 2.47.2