40.7 sec user + 0.9 sec system *** input.c.patch3 2008-02-28 02:11:11.000000000 +0100 --- input.c 2008-02-28 02:23:00.000000000 +0100 *************** *** 64,69 **** --- 64,78 ---- # include "regex.h" #endif /* ENABLE_CHANGEWORD */ + /* __builtin_expect(condition, expected_value) tells GCC about the expected + value of boolean conditions. */ + #if __GNUC__ < 3 + # undef __builtin_expect + # define __builtin_expect(condition, expected_value) (condition) + #endif + #define likely(condition) __builtin_expect (condition, 1) + #define unlikely(condition) __builtin_expect (condition, 0) + /* Number of bytes where it is more efficient to inline the reference as a string than it is to track reference bookkeeping for those bytes. */ *************** *** 762,774 **** switch (block->type) { case INPUT_STRING: ! if (!block->str_len) break; return to_uchar (block->u.u_s.str[0]); case INPUT_FILE: ch = getc (block->u.u_f.fp); ! if (ch != EOF) { ungetc (ch, block->u.u_f.fp); return ch; --- 771,783 ---- switch (block->type) { case INPUT_STRING: ! if (unlikely (!block->str_len)) break; return to_uchar (block->u.u_s.str[0]); case INPUT_FILE: ch = getc (block->u.u_f.fp); ! if (likely (ch != EOF)) { ungetc (ch, block->u.u_f.fp); return ch; *************** *** 847,853 **** `-------------------------------------------------------------------*/ #define next_char(AQ) \ ! (isp->str_len && !input_change \ ? (isp->str_len--, to_uchar (*isp->u.u_s.str++)) \ : next_char_1 (AQ)) --- 856,862 ---- `-------------------------------------------------------------------*/ #define next_char(AQ) \ ! (likely (isp->str_len) && likely (!input_change) \ ? (isp->str_len--, to_uchar (*isp->u.u_s.str++)) \ : next_char_1 (AQ)) *************** *** 859,865 **** while (1) { ! if (input_change) { current_file = isp->file; current_line = isp->line; --- 868,874 ---- while (1) { ! if (unlikely (input_change)) { current_file = isp->file; current_line = isp->line; *************** *** 869,881 **** switch (isp->type) { case INPUT_STRING: ! if (!isp->str_len) break; isp->str_len--; return to_uchar (*isp->u.u_s.str++); case INPUT_FILE: ! if (start_of_input_line) { start_of_input_line = false; current_line = ++isp->line; --- 878,890 ---- switch (isp->type) { case INPUT_STRING: ! if (unlikely (!isp->str_len)) break; isp->str_len--; return to_uchar (*isp->u.u_s.str++); case INPUT_FILE: ! if (unlikely (start_of_input_line)) { start_of_input_line = false; current_line = ++isp->line; *************** *** 884,895 **** /* If stdin is a terminal, calling getc after peek_input already called it would make the user have to hit ^D twice to quit. */ ! if (!isp->u.u_f.end) { ch = getc (isp->u.u_f.fp); ! if (ch != EOF) { ! if (ch == '\n') start_of_input_line = true; return ch; } --- 893,904 ---- /* If stdin is a terminal, calling getc after peek_input already called it would make the user have to hit ^D twice to quit. */ ! if (likely (!isp->u.u_f.end)) { ch = getc (isp->u.u_f.fp); ! if (likely (ch != EOF)) { ! if (unlikely (ch == '\n')) start_of_input_line = true; return ch; } *************** *** 1516,1522 **** /* Can't consume character until after CHAR_MACRO is handled. */ TOKEN_DATA_TYPE (td) = TOKEN_VOID; ch = peek_input (allow_argv && current_quote_age); ! if (ch == CHAR_EOF) { #ifdef DEBUG_INPUT xfprintf (stderr, "next_token -> EOF\n"); --- 1525,1531 ---- /* Can't consume character until after CHAR_MACRO is handled. */ TOKEN_DATA_TYPE (td) = TOKEN_VOID; ch = peek_input (allow_argv && current_quote_age); ! if (unlikely (ch == CHAR_EOF)) { #ifdef DEBUG_INPUT xfprintf (stderr, "next_token -> EOF\n"); *************** *** 1524,1530 **** next_char (false); return TOKEN_EOF; } ! if (ch == CHAR_MACRO) { init_macro_token (td); next_char (false); --- 1533,1539 ---- next_char (false); return TOKEN_EOF; } ! if (unlikely (ch == CHAR_MACRO)) { init_macro_token (td); next_char (false); *************** *** 1534,1540 **** #endif /* DEBUG_INPUT */ return TOKEN_MACDEF; } ! if (ch == CHAR_ARGV) { init_argv_token (obs, td); #ifdef DEBUG_INPUT --- 1543,1549 ---- #endif /* DEBUG_INPUT */ return TOKEN_MACDEF; } ! if (unlikely (ch == CHAR_ARGV)) { init_argv_token (obs, td); #ifdef DEBUG_INPUT *************** *** 1549,1555 **** next_char (false); /* Consume character we already peeked at. */ file = current_file; *line = current_line; ! if (MATCH (ch, curr_comm.str1, true)) { if (obs) obs_td = obs; --- 1558,1564 ---- next_char (false); /* Consume character we already peeked at. */ file = current_file; *line = current_line; ! if (unlikely (MATCH (ch, curr_comm.str1, true))) { if (obs) obs_td = obs; *************** *** 1570,1576 **** type = TOKEN_STRING; } ! else if (default_word_regexp && (isalpha (ch) || ch == '_')) { obstack_1grow (&token_stack, ch); while ((ch = peek_input (false)) < CHAR_EOF --- 1579,1585 ---- type = TOKEN_STRING; } ! else if (unlikely (default_word_regexp && (isalpha (ch) || ch == '_'))) { obstack_1grow (&token_stack, ch); while ((ch = peek_input (false)) < CHAR_EOF *************** *** 1584,1590 **** #ifdef ENABLE_CHANGEWORD ! else if (!default_word_regexp && word_regexp.fastmap[ch]) { obstack_1grow (&token_stack, ch); while (1) --- 1593,1599 ---- #ifdef ENABLE_CHANGEWORD ! else if (unlikely (!default_word_regexp && word_regexp.fastmap[ch])) { obstack_1grow (&token_stack, ch); while (1) *************** *** 1644,1650 **** while (1) { ch = next_char (obs != NULL && current_quote_age); ! if (ch == CHAR_EOF) /* Current_file changed to "" if we see CHAR_EOF, use the previous value we stored earlier. */ m4_error_at_line (EXIT_FAILURE, 0, file, *line, caller, --- 1653,1659 ---- while (1) { ch = next_char (obs != NULL && current_quote_age); ! if (unlikely (ch == CHAR_EOF)) /* Current_file changed to "" if we see CHAR_EOF, use the previous value we stored earlier. */ m4_error_at_line (EXIT_FAILURE, 0, file, *line, caller,