This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH RFA: libcpp speedup patch: tweak _cpp_clean_line


Profiling the preprocessor shows that most of the time is spent in
_cpp_clean_line.  This patch tweaks that function to run slightly
faster.  I added calls to __builtin_expect in a few places; these
reduce the main loop to a few compact instructions.  When there is a
space at the end of the line, instead of always walking backward
looking for a backslash, we instead only walk backward if we saw a
backslash earlier; since we know there is a backslash, the loop
condition when walking backward is simplified.

In conjunction with the patches to c-common.c and to libcpp/files.c
which I already sent, this gave me an 18% reduction in time required
to run the preprocessor on a large C++ file.

Tested with a C/C++ bootstrap and testsuite run on i686-pc-linux-gnu.

OK for mainline?

Ian


2006-12-28  Ian Lance Taylor  <iant@google.com>

	* lex.c (_cpp_clean_line): Add uses of __builtin_expect.  Don't
	look backward at the end of the line unless we saw a backslash.


Index: libcpp/lex.c
===================================================================
--- libcpp/lex.c	(revision 120236)
+++ libcpp/lex.c	(working copy)
@@ -111,31 +111,39 @@ _cpp_clean_line (cpp_reader *pfile)
 
   if (!buffer->from_stage3)
     {
+      const uchar *pbackslash = NULL;
+
       /* Short circuit for the common case of an un-escaped line with
 	 no trigraphs.  The primary win here is by not writing any
 	 data back to memory until we have to.  */
       for (;;)
 	{
 	  c = *++s;
-	  if (c == '\n' || c == '\r')
+	  if (__builtin_expect (c == '\n', 0)
+	      || __builtin_expect (c == '\r', 0))
 	    {
 	      d = (uchar *) s;
 
-	      if (s == buffer->rlimit)
+	      if (__builtin_expect (s == buffer->rlimit, 0))
 		goto done;
 
 	      /* DOS line ending? */
-	      if (c == '\r' && s[1] == '\n')
-		s++;
+	      if (__builtin_expect (c == '\r', 0)
+		  && s[1] == '\n')
+		{
+		  s++;
+		  if (s == buffer->rlimit)
+		    goto done;
+		}
 
-	      if (s == buffer->rlimit)
+	      if (__builtin_expect (pbackslash == NULL, 1))
 		goto done;
 
 	      /* check for escaped newline */
 	      p = d;
-	      while (p != buffer->next_line && is_nvspace (p[-1]))
+	      while (is_nvspace (p[-1]))
 		p--;
-	      if (p == buffer->next_line || p[-1] != '\\')
+	      if (p - 1 != pbackslash)
 		goto done;
 
 	      /* Have an escaped newline; process it and proceed to
@@ -145,7 +153,11 @@ _cpp_clean_line (cpp_reader *pfile)
 	      buffer->next_line = p - 1;
 	      break;
 	    }
-	  if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
+	  if (__builtin_expect (c == '\\', 0))
+	    pbackslash = s;
+	  else if (__builtin_expect (c == '?', 0)
+		   && __builtin_expect (s[1] == '?', 0)
+		   && _cpp_trigraph_map[s[2]])
 	    {
 	      /* Have a trigraph.  We may or may not have to convert
 		 it.  Add a line note regardless, for -Wtrigraphs.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]