[cplus] Another performance tweak

Daniel Jacobowitz drow@mvista.com
Fri Dec 19 19:16:00 GMT 2003


This is good for another 20% performance improvement in the lexer.  strncmp
can be optimized extremely efficiently when it is used with a constant
string, but not in a loop with an array of constant strings.

With this patch:
% time sh -c 'cat a-* | ../obj/gdb/foo > /dev/null'
7.21s user 0.78s system 96% cpu 8.304 total
% time sh -c 'cat a-* | ../../x86-as/binutils/cxxfilt > /dev/null'
1.55s user 0.08s system 97% cpu 1.671 total

Foo, my test harness, involves calling the demangler also.  That makes the
parser/lexer/reprinter take a bit under four times as long as the demangler. 
I was hoping for a little better, but I think this will do.  I'm just about
ready now to hook this into GDB and measure its actual impact on startup
time for large applications.  There's another 4% available by turning off
yydebug if necessary.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-12-19  Daniel Jacobowitz  <drow@mvista.com>

	* cp-names.y (tokentab2, tokentab3): Remove.
	(HANDLE_TOKEN2, HANDLE_TOKEN3): New macros.
	(yylex): Use them.

Index: cp-names.y
===================================================================
RCS file: /cvs/src/src/gdb/Attic/cp-names.y,v
retrieving revision 1.1.2.9
diff -u -p -r1.1.2.9 cp-names.y
--- cp-names.y	19 Dec 2003 18:54:02 -0000	1.1.2.9
+++ cp-names.y	19 Dec 2003 19:07:36 -0000
@@ -1413,36 +1413,6 @@ struct token
   int opcode;
 };
 
-static const struct token tokentab3[] =
-  {
-    {">>=", ASSIGN_MODIFY, BINOP_RSH},
-    {"<<=", ASSIGN_MODIFY, BINOP_LSH},
-  };
-
-static const struct token tokentab2[] =
-  {
-    {"+=", ASSIGN_MODIFY, BINOP_ADD},
-    {"-=", ASSIGN_MODIFY, BINOP_SUB},
-    {"*=", ASSIGN_MODIFY, BINOP_MUL},
-    {"/=", ASSIGN_MODIFY, BINOP_DIV},
-    {"%=", ASSIGN_MODIFY, BINOP_REM},
-    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
-    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
-    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
-    {"++", INCREMENT, BINOP_END},
-    {"--", DECREMENT, BINOP_END},
-    {"->", ARROW, BINOP_END},
-    {"&&", ANDAND, BINOP_END},
-    {"||", OROR, BINOP_END},
-    {"::", COLONCOLON, BINOP_END},
-    {"<<", LSH, BINOP_END},
-    {">>", RSH, BINOP_END},
-    {"==", EQUAL, BINOP_END},
-    {"!=", NOTEQUAL, BINOP_END},
-    {"<=", LEQ, BINOP_END},
-    {">=", GEQ, BINOP_END}
-  };
-
 #define HANDLE_SPECIAL(string, len, comp)		\
   if (strncmp (tokstart, string, len) == 0)		\
     {							\
@@ -1451,6 +1421,22 @@ static const struct token tokentab2[] =
       return DEMANGLER_SPECIAL;				\
     }
 
+#define HANDLE_TOKEN2(string, token, op)		\
+  if (lexptr[1] == string[1])				\
+    {							\
+      lexptr += 2;					\
+      yylval.opname = string;				\
+      return token;					\
+    }      
+
+#define HANDLE_TOKEN3(string, token, op)		\
+  if (lexptr[1] == string[1] && lexptr[2] == string[2])	\
+    {							\
+      lexptr += 2;					\
+      yylval.opname = string;				\
+      return token;					\
+    }      
+
 /* Read one token, getting characters through lexptr.  */
 
 static int
@@ -1458,7 +1444,6 @@ yylex (void)
 {
   int c;
   int namelen;
-  unsigned int i;
   char *tokstart;
   char *tokptr;
   int tempbufindex;
@@ -1472,26 +1457,6 @@ yylex (void)
   unquoted_expr = 1;
 
   tokstart = lexptr;
-  /* See if it is a special token of length 3.  */
-  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (tokstart[0] == tokentab3[i].operator[0]
-        && tokstart[1] == tokentab3[i].operator[1]
-        && tokstart[2] == tokentab3[i].operator[2])
-      {
-	lexptr += 3;
-	yylval.opname = tokentab3[i].operator;
-	return tokentab3[i].token;
-      }
-
-  /* See if it is a special token of length 2.  */
-  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (tokstart[0] == tokentab2[i].operator[0]
-        && tokstart[1] == tokentab2[i].operator[1])
-      {
-	lexptr += 2;
-	yylval.opname = tokentab2[i].operator;
-	return tokentab2[i].token;
-      }
 
   switch (c = *tokstart)
     {
@@ -1561,6 +1526,10 @@ yylex (void)
       /* FALL THRU into number case.  */
 
     case '-':
+      HANDLE_TOKEN2 ("-=", ASSIGN_MODIFY, BINOP_SUB);
+      HANDLE_TOKEN2 ("--", DECREMENT, BINOP_END);
+      HANDLE_TOKEN2 ("->", ARROW, BINOP_END);
+
       /* For construction vtables.  This is kind of hokey.  */
       if (strncmp (tokstart, "-in-", 4) == 0)
 	{
@@ -1643,22 +1612,66 @@ yylex (void)
       }
 
     case '+':
+      HANDLE_TOKEN2 ("+=", ASSIGN_MODIFY, BINOP_ADD);
+      HANDLE_TOKEN2 ("++", INCREMENT, BINOP_END);
+      lexptr++;
+      return c;
     case '*':
+      HANDLE_TOKEN2 ("*=", ASSIGN_MODIFY, BINOP_MUL);
+      lexptr++;
+      return c;
     case '/':
+      HANDLE_TOKEN2 ("/=", ASSIGN_MODIFY, BINOP_DIV);
+      lexptr++;
+      return c;
     case '%':
+      HANDLE_TOKEN2 ("%=", ASSIGN_MODIFY, BINOP_REM);
+      lexptr++;
+      return c;
     case '|':
+      HANDLE_TOKEN2 ("|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR);
+      HANDLE_TOKEN2 ("||", OROR, BINOP_END);
+      lexptr++;
+      return c;
     case '&':
+      HANDLE_TOKEN2 ("&=", ASSIGN_MODIFY, BINOP_BITWISE_AND);
+      HANDLE_TOKEN2 ("&&", ANDAND, BINOP_END);
+      lexptr++;
+      return c;
     case '^':
-    case '~':
+      HANDLE_TOKEN2 ("^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR);
+      lexptr++;
+      return c;
     case '!':
-    case '@':
+      HANDLE_TOKEN2 ("!=", NOTEQUAL, BINOP_END);
+      lexptr++;
+      return c;
     case '<':
+      HANDLE_TOKEN2 ("<=", LEQ, BINOP_END);
+      HANDLE_TOKEN2 ("<<", LSH, BINOP_END);
+      HANDLE_TOKEN3 ("<<=", ASSIGN_MODIFY, BINOP_LSH);
+      lexptr++;
+      return c;
     case '>':
+      HANDLE_TOKEN2 (">=", GEQ, BINOP_END);
+      HANDLE_TOKEN2 (">>", RSH, BINOP_END);
+      HANDLE_TOKEN3 (">>=", ASSIGN_MODIFY, BINOP_RSH);
+      lexptr++;
+      return c;
+    case '=':
+      HANDLE_TOKEN2 ("==", EQUAL, BINOP_END);
+      lexptr++;
+      return c;
+    case ':':
+      HANDLE_TOKEN2 ("::", COLONCOLON, BINOP_END);
+      lexptr++;
+      return c;
+
     case '[':
     case ']':
     case '?':
-    case ':':
-    case '=':
+    case '@':
+    case '~':
     case '{':
     case '}':
     symbol:



More information about the Gdb-patches mailing list