svn commit: r258205 - head/contrib/gcclibs/libcpp

Pedro F. Giffuni pfg at FreeBSD.org
Sat Nov 16 01:07:03 UTC 2013


Author: pfg
Date: Sat Nov 16 01:07:02 2013
New Revision: 258205
URL: http://svnweb.freebsd.org/changeset/base/258205

Log:
  libcpp: preprocessor speedup patches from mainline.
  
  * 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.
  
  * internal.h (struct cpp_reader): Add new fields:
  nonexistent_file_hash and nonexistent_file_ob.
  * files.c: Include "obstack.h".
  (find_file_in_dir): Before trying to open the file, look up the
  path name in the hash table of nonexistent files.  After failing
  to open the file, add the path name to the hash table.
  (_cpp_find_file): Cache the results of looking up the file name
  starting with the quote and bracket chain heads, if we can.
  (nonexistent_file_hash_eq): New static function.
  (_cpp_init_files): Initialize pfile->nonexistent_file_hash and
  pfile->nonexistent_file_ob.
  (_cpp_cleanup_files): Free pfile->nonexistent_file_hash and
  pfile->nonexistent_file_ob.
  
  Obtained from:	gcc 4.3 (rev. 120263, 124929 ; GPLv2)
  MFC after:	3 weeks

Modified:
  head/contrib/gcclibs/libcpp/files.c
  head/contrib/gcclibs/libcpp/internal.h
  head/contrib/gcclibs/libcpp/lex.c

Modified: head/contrib/gcclibs/libcpp/files.c
==============================================================================
--- head/contrib/gcclibs/libcpp/files.c	Sat Nov 16 01:03:56 2013	(r258204)
+++ head/contrib/gcclibs/libcpp/files.c	Sat Nov 16 01:07:02 2013	(r258205)
@@ -1,6 +1,7 @@
 /* Part of CPP library.  File handling.
    Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    Written by Per Bothner, 1994.
    Based on CCCP program by Paul Rubin, June 1986
    Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -26,6 +27,7 @@ Foundation, 51 Franklin Street, Fifth Fl
 #include "cpplib.h"
 #include "internal.h"
 #include "mkdeps.h"
+#include "obstack.h"
 #include "hashtab.h"
 #include "md5.h"
 #include <dirent.h>
@@ -322,6 +324,16 @@ find_file_in_dir (cpp_reader *pfile, _cp
 
   if (path)
     {
+      hashval_t hv = htab_hash_string (path);
+      char *copy;
+      void **pp;
+
+      if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL)
+	{
+	  file->err_no = ENOENT;
+	  return false;
+	}
+
       file->path = path;
       if (pch_open_file (pfile, file, invalid_pch))
 	return true;
@@ -335,7 +347,16 @@ find_file_in_dir (cpp_reader *pfile, _cp
 	  return true;
 	}
 
+      /* We copy the path name onto an obstack partly so that we don't
+	 leak the memory, but mostly so that we don't fragment the
+	 heap.  */
+      copy = obstack_copy0 (&pfile->nonexistent_file_ob, path,
+			    strlen (path));
       free (path);
+      pp = htab_find_slot_with_hash (pfile->nonexistent_file_hash,
+				     copy, hv, INSERT);
+      *pp = copy;
+
       file->path = file->name;
     }
   else
@@ -396,6 +417,9 @@ _cpp_find_file (cpp_reader *pfile, const
   struct file_hash_entry *entry, **hash_slot;
   _cpp_file *file;
   bool invalid_pch = false;
+  bool saw_bracket_include = false;
+  bool saw_quote_include = false;
+  struct cpp_dir *found_in_cache = NULL;
 
   /* Ensure we get no confusion between cached files and directories.  */
   if (start_dir == NULL)
@@ -448,13 +472,19 @@ _cpp_find_file (cpp_reader *pfile, const
       /* Only check the cache for the starting location (done above)
 	 and the quote and bracket chain heads because there are no
 	 other possible starting points for searches.  */
-      if (file->dir != pfile->bracket_include
-	  && file->dir != pfile->quote_include)
+      if (file->dir == pfile->bracket_include)
+	saw_bracket_include = true;
+      else if (file->dir == pfile->quote_include)
+	saw_quote_include = true;
+      else
 	continue;
 
       entry = search_cache (*hash_slot, file->dir);
       if (entry)
-	break;
+	{
+	  found_in_cache = file->dir;
+	  break;
+	}
     }
 
   if (entry)
@@ -478,6 +508,29 @@ _cpp_find_file (cpp_reader *pfile, const
   entry->u.file = file;
   *hash_slot = entry;
 
+  /* If we passed the quote or bracket chain heads, cache them also.
+     This speeds up processing if there are lots of -I options.  */
+  if (saw_bracket_include
+      && pfile->bracket_include != start_dir
+      && found_in_cache != pfile->bracket_include)
+    {
+      entry = new_file_hash_entry (pfile);
+      entry->next = *hash_slot;
+      entry->start_dir = pfile->bracket_include;
+      entry->u.file = file;
+      *hash_slot = entry;
+    }
+  if (saw_quote_include
+      && pfile->quote_include != start_dir
+      && found_in_cache != pfile->quote_include)
+    {
+      entry = new_file_hash_entry (pfile);
+      entry->next = *hash_slot;
+      entry->start_dir = pfile->quote_include;
+      entry->u.file = file;
+      *hash_slot = entry;
+    }
+
   return file;
 }
 
@@ -997,6 +1050,14 @@ file_hash_eq (const void *p, const void 
   return strcmp (hname, fname) == 0;
 }
 
+/* Compare entries in the nonexistent file hash table.  These are just
+   strings.  */
+static int
+nonexistent_file_hash_eq (const void *p, const void *q)
+{
+  return strcmp (p, q) == 0;
+}
+
 /* Initialize everything in this source file.  */
 void
 _cpp_init_files (cpp_reader *pfile)
@@ -1006,6 +1067,12 @@ _cpp_init_files (cpp_reader *pfile)
   pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
 					NULL, xcalloc, free);
   allocate_file_hash_entries (pfile);
+  pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string,
+						    nonexistent_file_hash_eq,
+						    NULL, xcalloc, free);
+  _obstack_begin (&pfile->nonexistent_file_ob, 0, 0,
+		  (void *(*) (long)) xmalloc,
+		  (void (*) (void *)) free);
 }
 
 /* Finalize everything in this source file.  */
@@ -1014,6 +1081,8 @@ _cpp_cleanup_files (cpp_reader *pfile)
 {
   htab_delete (pfile->file_hash);
   htab_delete (pfile->dir_hash);
+  htab_delete (pfile->nonexistent_file_hash);
+  obstack_free (&pfile->nonexistent_file_ob, 0);
 }
 
 /* Enter a file name in the hash for the sake of cpp_included.  */

Modified: head/contrib/gcclibs/libcpp/internal.h
==============================================================================
--- head/contrib/gcclibs/libcpp/internal.h	Sat Nov 16 01:03:56 2013	(r258204)
+++ head/contrib/gcclibs/libcpp/internal.h	Sat Nov 16 01:07:02 2013	(r258205)
@@ -355,6 +355,10 @@ struct cpp_reader
   struct file_hash_entry *file_hash_entries;
   unsigned int file_hash_entries_allocated, file_hash_entries_used;
 
+  /* Negative path lookup hash table.  */
+  struct htab *nonexistent_file_hash;
+  struct obstack nonexistent_file_ob;
+
   /* Nonzero means don't look for #include "foo" the source-file
      directory.  */
   bool quote_ignores_source_dir;

Modified: head/contrib/gcclibs/libcpp/lex.c
==============================================================================
--- head/contrib/gcclibs/libcpp/lex.c	Sat Nov 16 01:03:56 2013	(r258204)
+++ head/contrib/gcclibs/libcpp/lex.c	Sat Nov 16 01:07:02 2013	(r258205)
@@ -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', false)
+	      || __builtin_expect (c == '\r', false))
 	    {
 	      d = (uchar *) s;
 
-	      if (s == buffer->rlimit)
+	      if (__builtin_expect (s == buffer->rlimit, false))
 		goto done;
 
 	      /* DOS line ending? */
-	      if (c == '\r' && s[1] == '\n')
-		s++;
+	      if (__builtin_expect (c == '\r', false)
+		  && s[1] == '\n')
+		{
+		  s++;
+		  if (s == buffer->rlimit)
+		    goto done;
+		}
 
-	      if (s == buffer->rlimit)
+	      if (__builtin_expect (pbackslash == NULL, true))
 		goto done;
 
-	      /* check for escaped newline */
+	      /* 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 == '\\', false))
+	    pbackslash = s;
+	  else if (__builtin_expect (c == '?', false)
+		   && __builtin_expect (s[1] == '?', false)
+		   && _cpp_trigraph_map[s[2]])
 	    {
 	      /* Have a trigraph.  We may or may not have to convert
 		 it.  Add a line note regardless, for -Wtrigraphs.  */


More information about the svn-src-head mailing list