Within cp/parser.c, cp_lexer_peek_token and the rest of the token-related functions are bloated by lexer-debugging code, code that is completely dead unless calls to the functions cp_lexer_[start|stop]_debugging are deliberately inserted somewhere in the parser source code for temporary debugging purposes.
The compiler doesn't fold away this dead code at compile time because it cannot prove that the flag lexer->debugging_p doesn't change. So we end up with this dead debugging code, guarded by cp_lexer_debugging_p, in the release binary. This is especially wasteful with code like while (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ) && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA) && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN) && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF)) which, after inlining, ought to be equivalent to: token = parser->lexer->token; while (token != CPP_EQ && token != CPP_COMMA && token != CPP_CLOSE_PAREN && token != CPP_EOF) but because of the lexer-debugging stuff getting in the way of inlining/CSE, the final code is much worse. This patch helps the compiler to fold away calls to cp_lexer_debugging_p when the lexer is not being debugged, by adding a new macro that short-circuits the cp_lexer_debugging_p predicate. This change reduces the size of parser.o by 3.5% -- from 6060 Kb to 5852 Kb. This change also reduces the time it takes to compile a dummy C++ file of mine from 1.95s to 1.85s, a reduction of 5%. Bootstrapped + regtested on x86_64-pc-linux-gnu. Does this patch look OK to commit? gcc/cp/ChangeLog: PR c++/24208 * parser.c (LEXER_DEBUGGING_ENABLED_P): New macro. (cp_lexer_debugging_p): Use it. (cp_lexer_start_debugging): Likewise. (cp_lexer_stop_debugging): Likewise. --- gcc/cp/parser.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 33f1df3..d03b0c9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -706,11 +706,21 @@ cp_lexer_destroy (cp_lexer *lexer) ggc_free (lexer); } +/* This needs to be set to TRUE before the lexer-debugging infrastructure can + be used. The point of this flag is to help the compiler to fold away calls + to cp_lexer_debugging_p within this source file at compile time, when the + lexer is not being debugged. */ + +#define LEXER_DEBUGGING_ENABLED_P false + /* Returns nonzero if debugging information should be output. */ static inline bool cp_lexer_debugging_p (cp_lexer *lexer) { + if (!LEXER_DEBUGGING_ENABLED_P) + return false; + return lexer->debugging_p; } @@ -1296,6 +1306,10 @@ debug (cp_token *ptr) static void cp_lexer_start_debugging (cp_lexer* lexer) { + if (!LEXER_DEBUGGING_ENABLED_P) + fatal_error (input_location, + "LEXER_DEBUGGING_ENABLED_P is not set to true"); + lexer->debugging_p = true; cp_lexer_debug_stream = stderr; } @@ -1305,6 +1319,10 @@ cp_lexer_start_debugging (cp_lexer* lexer) static void cp_lexer_stop_debugging (cp_lexer* lexer) { + if (!LEXER_DEBUGGING_ENABLED_P) + fatal_error (input_location, + "LEXER_DEBUGGING_ENABLED_P is not set to true"); + lexer->debugging_p = false; cp_lexer_debug_stream = NULL; } -- 2.7.0.134.gf5046bd.dirty