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]

A small performance improvement for standalone cpp


This patch gives numbers (and, obscurely, comments in -C mode) their
own spelling category.  That lets us avoid a bunch of mispredicted
branches in cpp_output_token.  I get about 1% performance improvement.

This change exposed a longstanding bug in cppexp.c which was causing
confusing error messages about ill-formed #if statements.

bootstrapped i686-linux, no regressions, although the test suite is in
kinda bad shape right now.

zw

	* cpplex.c (enum spell_type): Add SPELL_NUMBER.
	(cpp_token_len, cpp_spell_token, cpp_output_token,
	_cpp_equiv_tokens): Handle it.
	* cpplib.h (TTYPE_TABLE): Use SPELL_NUMBER for CPP_NUMBER and
	CPP_COMMENT, SPELL_NONE for CPP_PADDING and CPP_EOF.
	* cppexp.c (_cpp_parse_expr): Use the correct operator code in
	error messages.

===================================================================
Index: cppexp.c
--- cppexp.c	2001/09/24 22:53:04	1.96
+++ cppexp.c	2001/10/06 23:02:29
@@ -819,13 +819,13 @@ _cpp_parse_expr (pfile)
 	{
 	  if (top->flags & HAVE_VALUE)
 	    SYNTAX_ERROR2 ("missing binary operator before '%s'",
-			   op_as_text (pfile, top->op));
+			   op_as_text (pfile, op.op));
 	}
       else
 	{
 	  if (!(top->flags & HAVE_VALUE))
 	    SYNTAX_ERROR2 ("operator '%s' has no left operand",
-			   op_as_text (pfile, top->op));
+			   op_as_text (pfile, op.op));
 	}
 
       /* Check for and handle stack overflow.  */
===================================================================
Index: cpplex.c
--- cpplex.c	2001/09/30 10:03:09	1.172
+++ cpplex.c	2001/10/06 23:02:30
@@ -58,6 +58,7 @@ enum spell_type
   SPELL_OPERATOR = 0,
   SPELL_CHAR,
   SPELL_IDENT,
+  SPELL_NUMBER,
   SPELL_STRING,
   SPELL_NONE
 };
@@ -1412,10 +1413,11 @@ cpp_token_len (token)
   switch (TOKEN_SPELL (token))
     {
     default:		len = 0;				break;
+    case SPELL_NUMBER:
     case SPELL_STRING:	len = token->val.str.len;		break;
     case SPELL_IDENT:	len = NODE_LEN (token->val.node);	break;
     }
-  /* 1 for whitespace, 4 for comment delimeters.  */
+  /* 1 for whitespace, 4 for comment delimiters.  */
   return len + 5;
 }
 
@@ -1449,12 +1451,21 @@ cpp_spell_token (pfile, token, buffer)
       }
       break;
 
+    case SPELL_CHAR:
+      *buffer++ = token->val.c;
+      break;
+
+    spell_ident:
     case SPELL_IDENT:
-      spell_ident:
       memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node));
       buffer += NODE_LEN (token->val.node);
       break;
 
+    case SPELL_NUMBER:
+      memcpy (buffer, token->val.str.text, token->val.str.len);
+      buffer += token->val.str.len;
+      break;
+
     case SPELL_STRING:
       {
 	int left, right, tag;
@@ -1465,20 +1476,18 @@ cpp_spell_token (pfile, token, buffer)
 	  case CPP_CHAR:	left = '\''; right = '\''; tag = '\0'; break;
     	  case CPP_WCHAR:	left = '\''; right = '\''; tag = 'L';  break;
 	  case CPP_HEADER_NAME:	left = '<';  right = '>';  tag = '\0'; break;
-	  default:		left = '\0'; right = '\0'; tag = '\0'; break;
+	  default:
+	    cpp_ice (pfile, "unknown string token %s\n", TOKEN_NAME (token));
+	    return buffer;
 	  }
 	if (tag) *buffer++ = tag;
-	if (left) *buffer++ = left;
+	*buffer++ = left;
 	memcpy (buffer, token->val.str.text, token->val.str.len);
 	buffer += token->val.str.len;
-	if (right) *buffer++ = right;
+	*buffer++ = right;
       }
       break;
 
-    case SPELL_CHAR:
-      *buffer++ = token->val.c;
-      break;
-
     case SPELL_NONE:
       cpp_ice (pfile, "Unspellable token %s", TOKEN_NAME (token));
       break;
@@ -1541,11 +1550,19 @@ cpp_output_token (token, fp)
       }
       break;
 
+    case SPELL_CHAR:
+      putc (token->val.c, fp);
+      break;
+
     spell_ident:
     case SPELL_IDENT:
       fwrite (NODE_NAME (token->val.node), 1, NODE_LEN (token->val.node), fp);
     break;
 
+    case SPELL_NUMBER:
+      fwrite (token->val.str.text, 1, token->val.str.len, fp);
+      break;
+
     case SPELL_STRING:
       {
 	int left, right, tag;
@@ -1556,19 +1573,17 @@ cpp_output_token (token, fp)
 	  case CPP_CHAR:	left = '\''; right = '\''; tag = '\0'; break;
     	  case CPP_WCHAR:	left = '\''; right = '\''; tag = 'L';  break;
 	  case CPP_HEADER_NAME:	left = '<';  right = '>';  tag = '\0'; break;
-	  default:		left = '\0'; right = '\0'; tag = '\0'; break;
+	  default:
+	    fprintf (stderr, "impossible STRING token %s\n", TOKEN_NAME (token));
+	    return;
 	  }
 	if (tag) putc (tag, fp);
-	if (left) putc (left, fp);
+	putc (left, fp);
 	fwrite (token->val.str.text, 1, token->val.str.len, fp);
-	if (right) putc (right, fp);
+	putc (right, fp);
       }
       break;
 
-    case SPELL_CHAR:
-      putc (token->val.c, fp);
-      break;
-
     case SPELL_NONE:
       /* An error, most probably.  */
       break;
@@ -1592,6 +1607,7 @@ _cpp_equiv_tokens (a, b)
 	return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
       case SPELL_IDENT:
 	return a->val.node == b->val.node;
+      case SPELL_NUMBER:
       case SPELL_STRING:
 	return (a->val.str.len == b->val.str.len
 		&& !memcmp (a->val.str.text, b->val.str.text,
===================================================================
Index: cpplib.h
--- cpplib.h	2001/10/02 12:57:23	1.194
+++ cpplib.h	2001/10/06 23:02:30
@@ -122,7 +122,7 @@ struct file_name_map_list;
   OP(CPP_ATSIGN,	"@")  /* used in Objective C */ \
 \
   TK(CPP_NAME,		SPELL_IDENT)	/* word */			\
-  TK(CPP_NUMBER,	SPELL_STRING)	/* 34_be+ta  */			\
+  TK(CPP_NUMBER,	SPELL_NUMBER)	/* 34_be+ta  */			\
 \
   TK(CPP_CHAR,		SPELL_STRING)	/* 'char' */			\
   TK(CPP_WCHAR,		SPELL_STRING)	/* L'char' */			\
@@ -132,10 +132,11 @@ struct file_name_map_list;
   TK(CPP_WSTRING,	SPELL_STRING)	/* L"string" */			\
   TK(CPP_HEADER_NAME,	SPELL_STRING)	/* <stdio.h> in #include */	\
 \
-  TK(CPP_COMMENT,	SPELL_STRING)	/* Only if output comments.  */ \
+  TK(CPP_COMMENT,	SPELL_NUMBER)	/* Only if output comments.  */ \
+                                        /* SPELL_NUMBER happens to DTRT.  */ \
   TK(CPP_MACRO_ARG,	SPELL_NONE)	/* Macro argument.  */		\
-  OP(CPP_PADDING,	"")		/* Whitespace for cpp0.  */	\
-  OP(CPP_EOF,		"EOL")		/* End of line or file.  */
+  TK(CPP_PADDING,	SPELL_NONE)	/* Whitespace for cpp0.  */	\
+  TK(CPP_EOF,		SPELL_NONE)	/* End of line or file.  */
 
 #define OP(e, s) e,
 #define TK(e, s) e,


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