diff mbox

Low-hanging C++-lexer speedup (PR c++/24208)

Message ID 1453783536-23868-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka Jan. 26, 2016, 4:45 a.m. UTC
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(+)

Comments

Jason Merrill Jan. 27, 2016, 9:33 p.m. UTC | #1
On 01/25/2016 11:45 PM, Patrick Palka wrote:
> +/* 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

I wonder about using an existing flag, such as CHECKING_P, but I guess 
this is OK too.

Jason
Patrick Palka Jan. 27, 2016, 10:31 p.m. UTC | #2
On Wed, Jan 27, 2016 at 4:33 PM, Jason Merrill <jason@redhat.com> wrote:
> On 01/25/2016 11:45 PM, Patrick Palka wrote:
>>
>> +/* 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
>
>
> I wonder about using an existing flag, such as CHECKING_P, but I guess this
> is OK too.

The way I look at it is that you need to deliberately add calls to
cp_lexer_[start|stop]_debugging in parser.c in order to make use of
the lexer debugging stuff anyway, so it's not too invasive to guard
this functionality behind a distinct flag that needs to be manually
toggled within parser.c.  And it is nice to avoid this overhead even
when CHECKING_P, to provide a minor speed-up in bootstrap times and
stuff.
diff mbox

Patch

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;
 }