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]

Speed up some token processing


This patch speeds up token processing by moving some duplicated code
into a single switch statement.  It shows a surprisingly good speedup
of the Qt library of 1.5%.

Moving the TV_CPP timing to surround all of c_lex_with_flags will affect
the timing report slightly, but I don't think it worth worrying over much
about that.

There were a number of exit paths from c_lex_with_flags that did not go
through the no_more_pch check.  I suspect that if they occured at the
start of translation, they would be a parse error, but this fixes it up.

booted & tested on i686-pc-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-10-25  Nathan Sidwell  <nathan@codesourcery.com>

	* c-lex.c (get_nonpadding_token): Remove.
	(c_lex_with_flags): Push timevar and eat padding here.  Improve
	stray token diagnostic.
	(lex_string): Replace logic with switch statement, eat padding
	token here.

2004-10-25  Nathan Sidwell  <nathan@codesourcery.com>

	* parser.c (cp_lexer_get_preprocessor_token): Remove unneeded
	padding token checking.

2004-10-25  Nathan Sidwell  <nathan@codesourcery.com>

	* gcc.dg/cpp/direct2.c: Adjust expected errors, robustify parser
	resyncing.
	* gcc.dg/cpp/direct2s.c: Likewise.

Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.240
diff -c -3 -p -r1.240 c-lex.c
*** c-lex.c	8 Oct 2004 20:25:39 -0000	1.240
--- c-lex.c	22 Oct 2004 16:51:19 -0000
*************** cb_undef (cpp_reader * ARG_UNUSED (pfile
*** 327,358 ****
  			 (const char *) NODE_NAME (node));
  }
  
! static inline const cpp_token *
! get_nonpadding_token (void)
! {
!   const cpp_token *tok;
!   timevar_push (TV_CPP);
!   do
!     tok = cpp_get_token (parse_in);
!   while (tok->type == CPP_PADDING);
!   timevar_pop (TV_CPP);
! 
!   return tok;
! }
  
  enum cpp_ttype
  c_lex_with_flags (tree *value, unsigned char *cpp_flags)
  {
-   const cpp_token *tok;
-   location_t atloc;
    static bool no_more_pch;
  
   retry:
!   tok = get_nonpadding_token ();
! 
   retry_after_at:
!   switch (tok->type)
      {
      case CPP_NAME:
        *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
        break;
--- 327,354 ----
  			 (const char *) NODE_NAME (node));
  }
  
! /* Read a token and return its type.  Fill *VALUE with its value, if
!    applicable.  Fill *CPP_FLAGS with the token's flags, if it is
!    non-NULL.  */
  
  enum cpp_ttype
  c_lex_with_flags (tree *value, unsigned char *cpp_flags)
  {
    static bool no_more_pch;
+   const cpp_token *tok;
+   enum cpp_ttype type;
  
+   timevar_push (TV_CPP);
   retry:
!   tok = cpp_get_token (parse_in);
!   type = tok->type;
!   
   retry_after_at:
!   switch (type)
      {
+     case CPP_PADDING:
+       goto retry;
+       
      case CPP_NAME:
        *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
        break;
*************** c_lex_with_flags (tree *value, unsigned 
*** 384,416 ****
  
      case CPP_ATSIGN:
        /* An @ may give the next token special significance in Objective-C.  */
-       atloc = input_location;
-       tok = get_nonpadding_token ();
        if (c_dialect_objc ())
  	{
! 	  tree val;
! 	  switch (tok->type)
  	    {
  	    case CPP_NAME:
! 	      val = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
! 	      if (objc_is_reserved_word (val))
  		{
! 		  *value = val;
! 		  return CPP_AT_NAME;
  		}
! 	      break;
! 
! 	    case CPP_STRING:
! 	    case CPP_WSTRING:
! 	      return lex_string (tok, value, true);
  
! 	    default: break;
  	    }
  	}
  
!       /* ... or not.  */
!       error ("%Hstray '@' in program", &atloc);
!       goto retry_after_at;
  
      case CPP_OTHER:
        {
--- 380,431 ----
  
      case CPP_ATSIGN:
        /* An @ may give the next token special significance in Objective-C.  */
        if (c_dialect_objc ())
  	{
! 	  location_t atloc = input_location;
! 	  
! 	retry_at:
! 	  tok = cpp_get_token (parse_in);
! 	  type = tok->type;
! 	  switch (type)
  	    {
+ 	    case CPP_PADDING:
+ 	      goto retry_at;
+ 	      
+ 	    case CPP_STRING:
+ 	    case CPP_WSTRING:
+ 	      type = lex_string (tok, value, true);
+ 	      break;
+ 
  	    case CPP_NAME:
! 	      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
! 	      if (objc_is_reserved_word (*value))
  		{
! 		  type = CPP_AT_NAME;
! 		  break;
  		}
! 	      /* FALLTHROUGH */
  
! 	    default:
! 	      /* ... or not.  */
! 	      error ("%Hstray %<@%> in program", &atloc);
! 	      goto retry_after_at;
  	    }
+ 	  break;
  	}
  
!       /* FALLTHROUGH */
!     case CPP_HASH:
!     case CPP_PASTE:
!       {
! 	unsigned char name[4];
! 	
! 	*cpp_spell_token (parse_in, tok, name) = 0;
! 	
! 	error ("stray %qs in program", name);
!       }
!       
!       goto retry;
  
      case CPP_OTHER:
        {
*************** c_lex_with_flags (tree *value, unsigned 
*** 419,427 ****
  	if (c == '"' || c == '\'')
  	  error ("missing terminating %c character", (int) c);
  	else if (ISGRAPH (c))
! 	  error ("stray '%c' in program", (int) c);
  	else
! 	  error ("stray '\\%o' in program", (int) c);
        }
        goto retry;
  
--- 434,442 ----
  	if (c == '"' || c == '\'')
  	  error ("missing terminating %c character", (int) c);
  	else if (ISGRAPH (c))
! 	  error ("stray %qc in program", (int) c);
  	else
! 	  error ("stray %<\\%o%> in program", (int) c);
        }
        goto retry;
  
*************** c_lex_with_flags (tree *value, unsigned 
*** 433,440 ****
      case CPP_STRING:
      case CPP_WSTRING:
        if (!c_lex_return_raw_strings)
! 	return lex_string (tok, value, false);
!       /* else fall through */
  
      case CPP_PRAGMA:
        *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
--- 448,459 ----
      case CPP_STRING:
      case CPP_WSTRING:
        if (!c_lex_return_raw_strings)
! 	{
! 	  type = lex_string (tok, value, false);
! 	  break;
! 	}
!       
!       /* FALLTHROUGH */
  
      case CPP_PRAGMA:
        *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
*************** c_lex_with_flags (tree *value, unsigned 
*** 451,465 ****
        break;
      }
  
    if (!no_more_pch)
      {
        no_more_pch = true;
        c_common_no_more_pch ();
      }
! 
!   if (cpp_flags)
!     *cpp_flags = tok->flags;
!   return tok->type;
  }
  
  enum cpp_ttype
--- 470,487 ----
        break;
      }
  
+   if (cpp_flags)
+     *cpp_flags = tok->flags;
+ 
    if (!no_more_pch)
      {
        no_more_pch = true;
        c_common_no_more_pch ();
      }
!   
!   timevar_pop (TV_CPP);
!   
!   return type;
  }
  
  enum cpp_ttype
*************** lex_string (const cpp_token *tok, tree *
*** 690,696 ****
  {
    tree value;
    bool wide = false;
!   size_t count = 1;
    struct obstack str_ob;
    cpp_string istr;
  
--- 712,718 ----
  {
    tree value;
    bool wide = false;
!   size_t concats = 0;
    struct obstack str_ob;
    cpp_string istr;
  
*************** lex_string (const cpp_token *tok, tree *
*** 702,752 ****
    if (tok->type == CPP_WSTRING)
      wide = true;
  
!   tok = get_nonpadding_token ();
!   if (c_dialect_objc () && tok->type == CPP_ATSIGN)
!     {
!       objc_string = true;
!       tok = get_nonpadding_token ();
!     }
!   if (tok->type == CPP_STRING || tok->type == CPP_WSTRING)
      {
!       gcc_obstack_init (&str_ob);
!       obstack_grow (&str_ob, &str, sizeof (cpp_string));
! 
!       do
  	{
! 	  count++;
! 	  if (tok->type == CPP_WSTRING)
! 	    wide = true;
! 	  obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
! 
! 	  tok = get_nonpadding_token ();
! 	  if (c_dialect_objc () && tok->type == CPP_ATSIGN)
! 	    {
! 	      objc_string = true;
! 	      tok = get_nonpadding_token ();
! 	    }
  	}
!       while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
!       strs = (cpp_string *) obstack_finish (&str_ob);
      }
  
    /* We have read one more token than we want.  */
    _cpp_backup_tokens (parse_in, 1);
  
!   if (count > 1 && !objc_string && warn_traditional && !in_system_header)
      warning ("traditional C rejects string constant concatenation");
  
    if ((c_lex_string_translate
         ? cpp_interpret_string : cpp_interpret_string_notranslate)
!       (parse_in, strs, count, &istr, wide))
      {
        value = build_string (istr.len, (char *) istr.text);
        free ((void *) istr.text);
  
        if (c_lex_string_translate == -1)
  	{
! 	  int xlated = cpp_interpret_string_notranslate (parse_in, strs, count,
  							 &istr, wide);
  	  /* Assume that, if we managed to translate the string above,
  	     then the untranslated parsing will always succeed.  */
--- 724,781 ----
    if (tok->type == CPP_WSTRING)
      wide = true;
  
!  retry:
!   tok = cpp_get_token (parse_in);
!   switch (tok->type)
      {
!     case CPP_PADDING:
!       goto retry;
!     case CPP_ATSIGN:
!       if (c_dialect_objc ())
  	{
! 	  objc_string = true;
! 	  goto retry;
! 	}
!       /* FALLTHROUGH */
!       
!     default:
!       break;
!       
!     case CPP_WSTRING:
!       wide = true;
!       /* FALLTHROUGH */
!       
!     case CPP_STRING:
!       if (!concats)
! 	{
! 	  gcc_obstack_init (&str_ob);
! 	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
  	}
! 	
!       concats++;
!       obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
!       goto retry;
      }
  
    /* We have read one more token than we want.  */
    _cpp_backup_tokens (parse_in, 1);
+   if (concats)
+     strs = (cpp_string *) obstack_finish (&str_ob);
  
!   if (concats && !objc_string && warn_traditional && !in_system_header)
      warning ("traditional C rejects string constant concatenation");
  
    if ((c_lex_string_translate
         ? cpp_interpret_string : cpp_interpret_string_notranslate)
!       (parse_in, strs, concats + 1, &istr, wide))
      {
        value = build_string (istr.len, (char *) istr.text);
        free ((void *) istr.text);
  
        if (c_lex_string_translate == -1)
  	{
! 	  int xlated = cpp_interpret_string_notranslate (parse_in, strs,
! 							 concats + 1,
  							 &istr, wide);
  	  /* Assume that, if we managed to translate the string above,
  	     then the untranslated parsing will always succeed.  */
*************** lex_string (const cpp_token *tok, tree *
*** 782,788 ****
    TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
    *valp = fix_string_type (value);
  
!   if (strs != &str)
      obstack_free (&str_ob, 0);
  
    return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
--- 811,817 ----
    TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
    *valp = fix_string_type (value);
  
!   if (concats)
      obstack_free (&str_ob, 0);
  
    return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.269
diff -c -3 -p -r1.269 parser.c
*** cp/parser.c	22 Oct 2004 11:42:23 -0000	1.269
--- cp/parser.c	22 Oct 2004 16:52:19 -0000
*************** cp_lexer_get_preprocessor_token (cp_lexe
*** 374,403 ****
                                   cp_token *token)
  {
    static int is_extern_c = 0;
-   bool done;
  
!   done = false;
!   /* Keep going until we get a token we like.  */
!   while (!done)
!     {
!       /* Get a new token from the preprocessor.  */
!       token->type = c_lex_with_flags (&token->value, &token->flags);
!       /* Issue messages about tokens we cannot process.  */
!       switch (token->type)
! 	{
! 	case CPP_ATSIGN:
! 	case CPP_HASH:
! 	case CPP_PASTE:
! 	  error ("invalid token");
! 	  break;
! 
! 	default:
! 	  /* This is a good token, so we exit the loop.  */
! 	  done = true;
! 	  break;
! 	}
!     }
!   /* Now we've got our token.  */
    token->location = input_location;
    token->in_system_header = in_system_header;
  
--- 374,382 ----
                                   cp_token *token)
  {
    static int is_extern_c = 0;
  
!    /* Get a new token from the preprocessor.  */
!   token->type = c_lex_with_flags (&token->value, &token->flags);
    token->location = input_location;
    token->in_system_header = in_system_header;
  
Index: testsuite/gcc.dg/cpp/direct2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/direct2.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 direct2.c
*** testsuite/gcc.dg/cpp/direct2.c	25 Jan 2003 14:39:11 -0000	1.2
--- testsuite/gcc.dg/cpp/direct2.c	22 Oct 2004 16:53:01 -0000
***************
*** 10,24 ****
  #define HASHDEFINE #define
  #define HASHINCLUDE #include
  
! HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
  /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 13 }*/
! HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
! /*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 15 }*/
  
! void g ()
  {
! HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
! HASHDEFINE  Y 1 /* { dg-error "syntax error" "#define from macro" } */
  }
  
  #pragma GCC dependency "direct2.c"
--- 10,33 ----
  #define HASHDEFINE #define
  #define HASHINCLUDE #include
  
! HASH include "somerandomfile" /*{ dg-error "stray" "non-include" }*/
  /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 13 }*/
! int resync_parser_1; /*{ dg-error "parse" "" }*/
  
! HASHINCLUDE <somerandomfile> /*{ dg-error "stray" "non-include 2" }*/
! /*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
! int resync_parser_2;
! 
! void g1 ()
! {
! HASH define X 1 /* { dg-error "stray|undeclared|parse|for each" "# from macro" } */
!   int resync_parser_3;
! }
! 
! void g2 ()
  {
! HASHDEFINE  Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
!   int resync_parser_4;
  }
  
  #pragma GCC dependency "direct2.c"
*************** void f ()
*** 34,37 ****
  #define starslash *##/
  
  slashstar starslash /* { dg-error "(parse|syntax) error" "not a comment" } */
! /* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 36 } */
--- 43,46 ----
  #define starslash *##/
  
  slashstar starslash /* { dg-error "(parse|syntax) error" "not a comment" } */
! /* { dg-warning "does not give" "paste warning(s)" { target *-*-* } 45 } */
Index: testsuite/gcc.dg/cpp/direct2s.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/direct2s.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 direct2s.c
*** testsuite/gcc.dg/cpp/direct2s.c	9 May 2002 17:14:21 -0000	1.2
--- testsuite/gcc.dg/cpp/direct2s.c	22 Oct 2004 16:53:01 -0000
***************
*** 12,29 ****
  #define HASHDEFINE #define
  #define HASHINCLUDE #include
  
! HASH include "somerandomfile" /*{ dg-error "syntax|parse" "non-include" }*/
  /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 15 }*/
! HASHINCLUDE <somerandomfile> /*{ dg-error "syntax|parse" "non-include 2" }*/
! /*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 17 }*/
  
! void g ()
  {
! HASH define X 1 /* { dg-error "syntax error" "# from macro" } */
! HASHDEFINE  Y 1 /* { dg-error "syntax error" "#define from macro" } */
  }
  
! #pragma GCC dependency "direct2s.c"
  #
  
  void f ()
--- 12,38 ----
  #define HASHDEFINE #define
  #define HASHINCLUDE #include
  
! HASH include "somerandomfile" /*{ dg-error "stray" "non-include" }*/
  /*{ dg-bogus "No such" "don't execute non-include" { target *-*-* } 15 }*/
! int resync_parser_1; /*{ dg-error "parse" "" }*/
  
! HASHINCLUDE <somerandomfile> /*{ dg-error "stray" "non-include 2" }*/
! /*{ dg-bogus "No such" "don't execute non-include 2" { target *-*-* } 18 }*/
! int resync_parser_2;
! 
! void g1 ()
! {
! HASH define X 1 /* { dg-error "stray|undeclared|parse|for each" "# from macro" } */
!   int resync_parser_3;
! }
! 
! void g2 ()
  {
! HASHDEFINE  Y 1 /* { dg-error "stray|undeclared|parse|for each" "#define from macro" } */
!   int resync_parser_4;
  }
  
! #pragma GCC dependency "direct2.c"
  #
  
  void f ()

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