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]

cpplib: small speedups


This patch implements a neat idea of Zacks: to treat _Pragma as a
builtin-macro, so we can remove an "if" from the cpp_get_token()
function.

On the subject of builtins, they were taking up another if statement
in cpp_get_token, because to test if a macro was disabled we needed
first to check that it wasn't a builtin, since builtins don't have a
cpp_macro structure that contains the disabled flag.

So to avoid this extra check, I moved the disabled flag to the
hashnode.  Then builtins don't need to be special cased, and they are
handled outside cpp_get_token completely.

Also, there are quite a few out-of-date comments in cpplib; this patch
starts to update them.

Bootstrapped x86 Linux, making check.

Neil.

	* cpphash.h: Update comments.
	(cpp_context): Update.
	(spec_nodes): Remove n__Pragma.
	* cppinit.c (cpp_create_reader): Update.
	(builtin_array): Add _Pragma.
	* cpplib.h: Update comments.
	(NODE_DISABLED, BT_PRAGMA): New.
	(cpp_start_lookahead, cpp_stop_lookahead): Remove prototypes.
	* cppmacro.c (struct cpp_macro): Remove disabled.
	(builtin_macro): Return int, handle _Pragma, push the new token
	on the context stack.
	(funlike_invocation_p): Unconstify, update.
	(enter_macro_context): Handle builtins here.
	(replace_args, push_token_context, push_ptoken_context):
	Update for prototype changes.
	(_cpp_pop_context): Update.
	(cpp_get_token): Don't handle buitins, nor _Pragma here.
	(cpp_sys_macro_p): Update.
	(_cpp_free_definition): Clear disabled flag.
	(_cpp_create_definition): Upate.
	* cppmain.c: Update comments.

Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.134
diff -u -p -r1.134 cpphash.h
--- cpphash.h	2001/09/30 10:03:08	1.134
+++ cpphash.h	2001/10/02 11:19:53
@@ -42,7 +42,7 @@ struct directive;		/* Deliberately incom
    efficiency, and partly to limit runaway recursion.  */
 #define CPP_STACK_MAX 200
 
-/* A generic memory buffer.  */
+/* A generic memory buffer, and operations on it.  */
 
 typedef struct _cpp_buff _cpp_buff;
 struct _cpp_buff
@@ -59,6 +59,7 @@ extern _cpp_buff *_cpp_append_extend_buf
 extern void _cpp_free_buff PARAMS ((_cpp_buff *));
 extern unsigned char *_cpp_aligned_alloc PARAMS ((cpp_reader *, size_t));
 extern unsigned char *_cpp_unaligned_alloc PARAMS ((cpp_reader *, size_t));
+
 #define BUFF_ROOM(BUFF) (size_t) ((BUFF)->limit - (BUFF)->cur)
 #define BUFF_FRONT(BUFF) ((BUFF)->cur)
 #define BUFF_LIMIT(BUFF) ((BUFF)->limit)
@@ -114,8 +115,8 @@ struct cpp_context
      When the context is popped, the buffer is released.  */
   _cpp_buff *buff;
 
-  /* For a macro context, these are the macro and its arguments.  */
-  cpp_macro *macro;
+  /* For a macro context, the macro node, otherwise NULL.  */
+  cpp_hashnode *macro;
 
   /* True if utoken element is token, else ptoken.  */
   bool direct_p;
@@ -162,7 +163,6 @@ struct spec_nodes
   cpp_hashnode *n_defined;		/* defined operator */
   cpp_hashnode *n_true;			/* C++ keyword true */
   cpp_hashnode *n_false;		/* C++ keyword false */
-  cpp_hashnode *n__Pragma;		/* _Pragma operator */
   cpp_hashnode *n__STRICT_ANSI__;	/* STDC_0_IN_SYSTEM_HEADERS */
   cpp_hashnode *n__CHAR_UNSIGNED__;	/* plain char is unsigned */
   cpp_hashnode *n__VA_ARGS__;		/* C99 vararg macros */
@@ -178,7 +178,7 @@ struct cpp_buffer
 
   struct cpp_buffer *prev;
 
-  const unsigned char *buf;	 /* Entire buffer.  */
+  const unsigned char *buf;	 /* Entire character buffer.  */
 
   /* Pointer into the include table; non-NULL if this is a file
      buffer.  Used for include_next and to record control macros.  */
Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.187
diff -u -p -r1.187 cppinit.c
--- cppinit.c	2001/09/30 10:03:09	1.187
+++ cppinit.c	2001/10/02 11:19:58
@@ -547,7 +547,6 @@ cpp_create_reader (table, lang)
   s->n_defined		= cpp_lookup (pfile, DSC("defined"));
   s->n_true		= cpp_lookup (pfile, DSC("true"));
   s->n_false		= cpp_lookup (pfile, DSC("false"));
-  s->n__Pragma		= cpp_lookup (pfile, DSC("_Pragma"));
   s->n__STRICT_ANSI__   = cpp_lookup (pfile, DSC("__STRICT_ANSI__"));
   s->n__CHAR_UNSIGNED__ = cpp_lookup (pfile, DSC("__CHAR_UNSIGNED__"));
   s->n__VA_ARGS__       = cpp_lookup (pfile, DSC("__VA_ARGS__"));
@@ -658,6 +657,7 @@ static const struct builtin builtin_arra
   B("__BASE_FILE__",	 BT_BASE_FILE),
   B("__LINE__",		 BT_SPECLINE),
   B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL),
+  B("_Pragma",		 BT_PRAGMA),
 
   X("__VERSION__",		VERS),
   X("__USER_LABEL_PREFIX__",	ULP),
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.193
diff -u -p -r1.193 cpplib.h
--- cpplib.h	2001/09/27 12:59:37	1.193
+++ cpplib.h	2001/10/02 11:19:59
@@ -168,7 +168,7 @@ struct cpp_string
 #define BOL		(1 << 6) /* Token at beginning of line.  */
 
 /* A preprocessing token.  This has been carefully packed and should
-   occupy 12 bytes on 32-bit hosts and 16 bytes on 64-bit hosts.  */
+   occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
 struct cpp_token
 {
   unsigned int line;		/* Logical line of first char of token.  */
@@ -353,7 +353,7 @@ struct cpp_options
   /* Print column number in error messages.  */
   unsigned char show_column;
 
-  /* Treat C++ alternate operator names special.  */
+  /* Nonzero means handle C++ alternate operator names.  */
   unsigned char operator_names;
 
   /* True if --help, --version or --target-help appeared in the
@@ -400,6 +400,7 @@ extern const char *progname;
 #define NODE_BUILTIN	(1 << 2)	/* Builtin macro.  */
 #define NODE_DIAGNOSTIC (1 << 3)	/* Possible diagnostic when lexed.  */
 #define NODE_WARN	(1 << 4)	/* Warn if redefined or undefined.  */
+#define NODE_DISABLED	(1 << 5)	/* A disabled macro.  */
 
 /* Different flavors of hash node.  */
 enum node_type
@@ -409,7 +410,8 @@ enum node_type
   NT_ASSERTION	   /* Predicate for #assert.  */
 };
 
-/* Different flavors of builtin macro.  */
+/* Different flavors of builtin macro.  _Pragma is an operator, but we
+   handle it with the builtin code for efficiency reasons.  */
 enum builtin_type
 {
   BT_SPECLINE = 0,		/* `__LINE__' */
@@ -418,7 +420,8 @@ enum builtin_type
   BT_BASE_FILE,			/* `__BASE_FILE__' */
   BT_INCLUDE_LEVEL,		/* `__INCLUDE_LEVEL__' */
   BT_TIME,			/* `__TIME__' */
-  BT_STDC			/* `__STDC__' */
+  BT_STDC,			/* `__STDC__' */
+  BT_PRAGMA			/* `_Pragma' operator */
 };
 
 #define CPP_HASHNODE(HNODE)	((cpp_hashnode *) (HNODE))
@@ -568,8 +571,6 @@ extern void cpp_forall_identifiers	PARAM
 
 /* In cppmacro.c */
 extern void cpp_scan_nooutput		PARAMS ((cpp_reader *));
-extern void cpp_start_lookahead		PARAMS ((cpp_reader *));
-extern void cpp_stop_lookahead		PARAMS ((cpp_reader *, int));
 extern int  cpp_sys_macro_p		PARAMS ((cpp_reader *));
 
 /* In cppfiles.c */
Index: cppmacro.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmacro.c,v
retrieving revision 1.77
diff -u -p -r1.77 cppmacro.c
--- cppmacro.c	2001/09/30 10:03:10	1.77
+++ cppmacro.c	2001/10/02 11:20:03
@@ -38,7 +38,6 @@ struct cpp_macro
   unsigned short paramc;	/* Number of parameters.  */
   unsigned int fun_like : 1;	/* If a function-like macro.  */
   unsigned int variadic : 1;	/* If a variadic macro.  */
-  unsigned int disabled : 1;	/* If macro is disabled.  */
   unsigned int syshdr   : 1;	/* If macro defined in system header.  */
 };
 
@@ -55,11 +54,11 @@ struct macro_arg
 /* Macro expansion.  */
 
 static int enter_macro_context PARAMS ((cpp_reader *, cpp_hashnode *));
-static const cpp_token *builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
+static int builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
 static void push_token_context
-  PARAMS ((cpp_reader *, cpp_macro *, const cpp_token *, unsigned int));
+  PARAMS ((cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int));
 static void push_ptoken_context
-  PARAMS ((cpp_reader *, cpp_macro *, _cpp_buff *,
+  PARAMS ((cpp_reader *, cpp_hashnode *, _cpp_buff *,
 	   const cpp_token **, unsigned int));
 static _cpp_buff *collect_args PARAMS ((cpp_reader *, const cpp_hashnode *));
 static cpp_context *next_context PARAMS ((cpp_reader *));
@@ -76,8 +75,8 @@ static const cpp_token *stringify_arg PA
 static void paste_all_tokens PARAMS ((cpp_reader *, const cpp_token *));
 static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
 				  const cpp_token *));
-static int funlike_invocation_p PARAMS ((cpp_reader *, const cpp_hashnode *));
-static void replace_args PARAMS ((cpp_reader *, cpp_macro *, macro_arg *));
+static int funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
+static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_arg *));
 
 /* #define directive parsing and handling.  */
 
@@ -132,17 +131,22 @@ static const char * const monthnames[] =
   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 };
 
-/* Handle builtin macros like __FILE__.  */
-static const cpp_token *
+/* Handle builtin macros like __FILE__, and push the resulting token
+   on the context stack.  Also handles _Pragma, for which no new token
+   is created.  Returns 1 on success, 0 to return the token to the
+   caller.  */
+static int
 builtin_macro (pfile, node)
      cpp_reader *pfile;
      cpp_hashnode *node;
 {
+  const cpp_token *result;
+
   switch (node->value.builtin)
     {
     default:
       cpp_ice (pfile, "invalid builtin macro \"%s\"", NODE_NAME (node));
-      return new_number_token (pfile, 1);
+      return 0;
 
     case BT_FILE:
     case BT_BASE_FILE:
@@ -161,28 +165,33 @@ builtin_macro (pfile, node)
 	buf = _cpp_unaligned_alloc (pfile, len * 4 + 1);
 	len = quote_string (buf, (const unsigned char *) name, len) - buf;
 
-	return new_string_token (pfile, buf, len);
+	result = new_string_token (pfile, buf, len);
       }
-	
+      break;
+
     case BT_INCLUDE_LEVEL:
       /* The line map depth counts the primary source as level 1, but
 	 historically __INCLUDE_DEPTH__ has called the primary source
 	 level 0.  */
-      return new_number_token (pfile, pfile->line_maps.depth - 1);
+      result = new_number_token (pfile, pfile->line_maps.depth - 1);
+      break;
 
     case BT_SPECLINE:
       /* If __LINE__ is embedded in a macro, it must expand to the
 	 line of the macro's invocation, not its definition.
 	 Otherwise things like assert() will not work properly.  */
-      return new_number_token (pfile, SOURCE_LINE (pfile->map,
-						   pfile->cur_token[-1].line));
+      result = new_number_token (pfile,
+				 SOURCE_LINE (pfile->map,
+					      pfile->cur_token[-1].line));
+      break;
 
     case BT_STDC:
       {
 	int stdc = (!CPP_IN_SYSTEM_HEADER (pfile)
 		    || pfile->spec_nodes.n__STRICT_ANSI__->type != NT_VOID);
-	return new_number_token (pfile, stdc);
+	result = new_number_token (pfile, stdc);
       }
+      break;
 
     case BT_DATE:
     case BT_TIME:
@@ -211,9 +220,25 @@ builtin_macro (pfile, node)
 	  sprintf ((char *) pfile->time.val.str.text, "%02d:%02d:%02d",
 		   tb->tm_hour, tb->tm_min, tb->tm_sec);
 	}
+
+      if (node->value.builtin == BT_DATE)
+	result = &pfile->date;
+      else
+	result = &pfile->time;
+      break;
+
+    case BT_PRAGMA:
+      /* Don't interpret _Pragma within directives.  The standard is
+         not clear on this, but to me this makes most sense.  */
+      if (pfile->state.in_directive)
+	return 0;
 
-      return node->value.builtin == BT_DATE ? &pfile->date: &pfile->time;
+      _cpp_do__Pragma (pfile);
+      return 1;
     }
+
+  push_token_context (pfile, NULL, result, 1);
+  return 1;
 }
 
 /* Adds backslashes before all backslashes and double quotes appearing
@@ -594,7 +619,7 @@ collect_args (pfile, node)
 static int
 funlike_invocation_p (pfile, node)
      cpp_reader *pfile;
-     const cpp_hashnode *node;
+     cpp_hashnode *node;
 {
   const cpp_token *maybe_paren;
   _cpp_buff *buff = NULL;
@@ -626,7 +651,7 @@ funlike_invocation_p (pfile, node)
   if (buff)
     {
       if (node->value.macro->paramc > 0)
-	replace_args (pfile, node->value.macro, (macro_arg *) buff->base);
+	replace_args (pfile, node, (macro_arg *) buff->base);
       _cpp_release_buff (pfile, buff);
     }
 
@@ -642,9 +667,11 @@ enter_macro_context (pfile, node)
      cpp_reader *pfile;
      cpp_hashnode *node;
 {
-  if (node->flags & NODE_BUILTIN)
-    push_token_context (pfile, NULL, builtin_macro (pfile, node), 1);
-  else
+  /* Macros invalidate controlling macros.  */
+  pfile->mi_valid = false;
+
+  /* Handle macros and the _Pragma operator.  */
+  if (! (node->flags & NODE_BUILTIN))
     {
       cpp_macro *macro = node->value.macro;
 
@@ -652,22 +679,24 @@ enter_macro_context (pfile, node)
 	return 0;
 
       /* Disable the macro within its expansion.  */
-      macro->disabled = 1;
+      node->flags |= NODE_DISABLED;
 
       if (macro->paramc == 0)
-	push_token_context (pfile, macro, macro->expansion, macro->count);
+	push_token_context (pfile, node, macro->expansion, macro->count);
+
+      return 1;
     }
- 
-  return 1;
+
+  return builtin_macro (pfile, node);
 }
 
 /* Take the expansion of a function-like MACRO, replacing parameters
    with the actual arguments.  Each argument is macro-expanded before
    replacement, unless operated upon by the # or ## operators.  */
 static void
-replace_args (pfile, macro, args)
+replace_args (pfile, node, args)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *node;
      macro_arg *args;
 {
   unsigned int i, total;
@@ -675,11 +704,13 @@ replace_args (pfile, macro, args)
   const cpp_token **dest, **first;
   macro_arg *arg;
   _cpp_buff *buff;
+  cpp_macro *macro;
 
   /* First, fully macro-expand arguments, calculating the number of
      tokens in the final expansion as we go.  The ordering of the if
      statements below is subtle; we must handle stringification before
      pasting.  */
+  macro = node->value.macro;
   total = macro->count;
   limit = macro->expansion + macro->count;
 
@@ -797,7 +828,7 @@ replace_args (pfile, macro, args)
     if (args[i].expanded)
       free (args[i].expanded);
 
-  push_ptoken_context (pfile, macro, buff, first, dest - first);
+  push_ptoken_context (pfile, node, buff, first, dest - first);
 }
 
 /* Return a special padding token, with padding inherited from SOURCE.  */
@@ -837,7 +868,7 @@ next_context (pfile)
 static void
 push_ptoken_context (pfile, macro, buff, first, count)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *macro;
      _cpp_buff *buff;
      const cpp_token **first;
      unsigned int count;
@@ -855,7 +886,7 @@ push_ptoken_context (pfile, macro, buff,
 static void
 push_token_context (pfile, macro, first, count)
      cpp_reader *pfile;
-     cpp_macro *macro;
+     cpp_hashnode *macro;
      const cpp_token *first;
      unsigned int count;
 {
@@ -914,7 +945,7 @@ _cpp_pop_context (pfile)
 
   /* Re-enable a macro when leaving its expansion.  */
   if (context->macro)
-    context->macro->disabled = 0;
+    context->macro->flags &= ~NODE_DISABLED;
 
   if (context->buff)
     _cpp_release_buff (pfile, context->buff);
@@ -975,39 +1006,30 @@ cpp_get_token (pfile)
 
       node = result->val.node;
 
-      /* Handle macros and the _Pragma operator.  */
-      if (node->type == NT_MACRO && !(result->flags & NO_EXPAND))
+      if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
+	break;
+      
+      if (!(node->flags & NODE_DISABLED))
 	{
-	  /* Macros invalidate controlling macros.  */
-	  pfile->mi_valid = false;
-
-	  if (!(node->flags & NODE_BUILTIN) && node->value.macro->disabled)
+	  if (!pfile->state.prevent_expansion
+	      && enter_macro_context (pfile, node))
 	    {
-	      /* Flag this token as always unexpandable.  */
-	      cpp_token *t = _cpp_temp_token (pfile);
-	      t->type = result->type;
-	      t->flags = result->flags | NO_EXPAND;
-	      t->val.str = result->val.str;
-	      result = t;
-	    }
-	  else if (!pfile->state.prevent_expansion
-		   && enter_macro_context (pfile, node))
-	    {
 	      if (pfile->state.in_directive)
 		continue;
 	      return padding_token (pfile, result);
 	    }
 	}
-
-      /* Don't interpret _Pragma within directives.  The standard is
-         not clear on this, but to me this makes most sense.  */
-      if (node != pfile->spec_nodes.n__Pragma
-	  || pfile->state.in_directive)
-	break;
+      else
+	{
+	  /* Flag this token as always unexpandable.  */
+	  cpp_token *t = _cpp_temp_token (pfile);
+	  t->type = result->type;
+	  t->flags = result->flags | NO_EXPAND;
+	  t->val.str = result->val.str;
+	  result = t;
+	}
 
-      /* Handle it, and loop back for another token.  MI is cleared
-         since this token came from either the lexer or a macro.  */
-      _cpp_do__Pragma (pfile);
+      break;
     }
 
   return result;
@@ -1020,9 +1042,9 @@ int
 cpp_sys_macro_p (pfile)
      cpp_reader *pfile;
 {
-  cpp_macro *macro = pfile->context->macro;
+  cpp_hashnode *node = pfile->context->macro;
 
-  return macro && macro->syshdr;
+  return node && node->value.macro && node->value.macro->syshdr;
 }
 
 /* Read each token in, until EOF.  Directives are transparently
@@ -1117,8 +1139,8 @@ _cpp_free_definition (h)
 {
   /* Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
-  /* Clear builtin flag in case of redefinition.  */
-  h->flags &= ~NODE_BUILTIN;
+  /* Clear builtin and disabled flags in case of redefinition.  */
+  h->flags &= ~(NODE_BUILTIN | NODE_DISABLED);
 }
 
 /* Save parameter NODE to the parameter list of macro MACRO.  Returns
@@ -1360,9 +1382,10 @@ _cpp_create_definition (pfile, node)
   BUFF_FRONT (pfile->a_buff) = (U_CHAR *) &macro->expansion[macro->count];
 
   /* Implement the macro-defined-to-itself optimisation.  */
-  macro->disabled = (macro->count == 1 && !macro->fun_like
-		     && macro->expansion[0].type == CPP_NAME
-		     && macro->expansion[0].val.node == node);
+  if (macro->count == 1 && !macro->fun_like
+      && macro->expansion[0].type == CPP_NAME
+      && macro->expansion[0].val.node == node)
+    node->flags |= NODE_DISABLED;
 
   /* To suppress some diagnostics.  */
   macro->syshdr = pfile->map->sysp != 0;
Index: cppmain.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmain.c,v
retrieving revision 1.81
diff -u -p -r1.81 cppmain.c
--- cppmain.c	2001/09/24 22:53:06	1.81
+++ cppmain.c	2001/10/02 11:20:06
@@ -215,8 +215,8 @@ setup_callbacks ()
     }
 }
 
-/* Writes out the preprocessed file.  Alternates between two tokens,
-   so that we can avoid accidental token pasting.  */
+/* Writes out the preprocessed file, handling spacing and paste
+   avoidance issues.  */
 static void
 scan_translation_unit (pfile)
      cpp_reader *pfile;
@@ -334,7 +334,7 @@ print_line (map, line, special_flags)
 }
 
 /* Called when a line of output is started.  TOKEN is the first token
-   of the line, and maybe be CPP_EOF.  */
+   of the line, and may be CPP_EOF.  */
 
 static void
 cb_line_change (pfile, token, parsing_args)


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