From 9132fbb788b24bc4b03be723a42b16dd9f65e03f Mon Sep 17 00:00:00 2001
From: Per Bothner <pbothner@apple.com>
Date: Tue, 20 Jan 2004 05:17:48 +0000
Subject: [PATCH] Implement a cache for linemap_lookup.

	* line-map.h (struct_line_maps):  Add cache field.
	* line-map.c (linemap_init):  Zero cache field.
	(linemap_add):  Set cache field to offset of newly allocated map.
	(linemap_lookup):  Use and set cache field.

From-SVN: r76197
---
 gcc/ChangeLog  |  8 ++++++++
 gcc/line-map.c | 30 +++++++++++++++++++++++-------
 gcc/line-map.h |  2 ++
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b12049bf885b..c2ae7ab43807 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2003-01-20  Per Bothner  <pbothner@apple.com>
+
+	Implement a cache for linemap_lookup.
+	* line-map.h (struct_line_maps):  Add cache field.
+	* line-map.c (linemap_init):  Zero cache field.
+	(linemap_add):  Set cache field to offset of newly allocated map.
+	(linemap_lookup):  Use and set cache field.
+
 2004-01-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 
 	PR optimization/13567
diff --git a/gcc/line-map.c b/gcc/line-map.c
index 521c4e5c843e..48e122bddb09 100644
--- a/gcc/line-map.c
+++ b/gcc/line-map.c
@@ -32,12 +32,13 @@ static void trace_include (const struct line_maps *, const struct line_map *);
 void
 linemap_init (struct line_maps *set)
 {
-  set->maps = 0;
+  set->maps = NULL;
   set->allocated = 0;
   set->used = 0;
   set->last_listed = -1;
   set->trace_includes = false;
   set->depth = 0;
+  set->cache = 0;
 }
 
 /* Free a line map set.  */
@@ -89,7 +90,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
       set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map));
     }
 
-  map = &set->maps[set->used++];
+  map = &set->maps[set->used];
 
   if (to_file && *to_file == '\0')
     to_file = "<stdin>";
@@ -108,7 +109,6 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
 	  if (to_file == NULL)
 	    {
 	      set->depth--;
-	      set->used--;
 	      return NULL;
 	    }
 	  error = true;
@@ -141,6 +141,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
   map->from_line = from_line;
   map->to_file = to_file;
   map->to_line = to_line;
+  set->cache = set->used++;
 
   if (reason == LC_ENTER)
     {
@@ -168,10 +169,24 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
 const struct line_map *
 linemap_lookup (struct line_maps *set, source_location line)
 {
-  unsigned int md, mn = 0, mx = set->used;
-
-  if (mx == 0)
-    abort ();
+  unsigned int md, mn, mx;
+  const struct line_map *cached;
+
+  mn = set->cache;
+  mx = set->used;
+  
+  cached = &set->maps[mn];
+  /* We should get a segfault if no line_maps have been added yet. */
+  if (line >= cached->from_line)
+    {
+      if (mn + 1 == mx || line < cached[1].from_line)
+	return cached;
+    }
+  else
+    {
+      mx = mn;
+      mn = 0;
+    }
 
   while (mx - mn > 1)
     {
@@ -182,6 +197,7 @@ linemap_lookup (struct line_maps *set, source_location line)
 	mn = md;
     }
 
+  set->cache = mn;
   return &set->maps[mn];
 }
 
diff --git a/gcc/line-map.h b/gcc/line-map.h
index c57f51a66245..ae1fbdbd4dff 100644
--- a/gcc/line-map.h
+++ b/gcc/line-map.h
@@ -61,6 +61,8 @@ struct line_maps
   unsigned int allocated;
   unsigned int used;
 
+  unsigned int cache;
+
   /* The most recently listed include stack, if any, starts with
      LAST_LISTED as the topmost including file.  -1 indicates nothing
      has been listed yet.  */
-- 
GitLab