Reorg line_map data structures for better packing.
authorNathan Sidwell <nathan@acm.org>
Tue, 3 Jul 2018 14:47:11 +0000 (14:47 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 3 Jul 2018 14:47:11 +0000 (14:47 +0000)
* include/line-map.h (enum lc_reason): Add LC_HWM.
(LINE_MAP_MAX_LOCATION): Define here.
(struct line_map): Move reason field to line_map_ordinary.  Adjust
GTY tagging.
(struct line_map_ordinary): Reorder fields for less padding.
(struct line_map_macro): Likewise.
(MAP_ORDINARY_P): New.
(linemap_check_ordinary, linemap_check_macro): Adjust.
* line-map.c (LINE_MAP_MAX_SOURCE_LOCATION): Delete.
(new_linemap): Take start_location, not reason.  Adjust.
(linemap_add, linemap_enter_macro): Adjust.
(linemap_line_start): Likewise.
(linemap_macro_expansion_map_p): Use MAP_ORDINARY_P.
(linemap_macro_loc_to_spelling_point): Likewise.
(linemap_macro_loc_to_def_point): Likewise.
(linemap_dump): Likewise.

From-SVN: r262348

libcpp/ChangeLog
libcpp/include/line-map.h
libcpp/line-map.c

index 682903aa837b3f73acd0db02548bf7b961837bcb..7412800afc719864ab33d83c0b73523d03b5954f 100644 (file)
@@ -1,3 +1,23 @@
+2018-07-03  Nathan Sidwell  <nathan@acm.org>
+
+       Reorg line_map data structures for better packing.
+       * include/line-map.h (enum lc_reason): Add LC_HWM.
+       (LINE_MAP_MAX_LOCATION): Define here.
+       (struct line_map): Move reason field to line_map_ordinary.  Adjust
+       GTY tagging.
+       (struct line_map_ordinary): Reorder fields for less padding.
+       (struct line_map_macro): Likewise.
+       (MAP_ORDINARY_P): New.
+       (linemap_check_ordinary, linemap_check_macro): Adjust.
+       * line-map.c (LINE_MAP_MAX_SOURCE_LOCATION): Delete.
+       (new_linemap): Take start_location, not reason.  Adjust.
+       (linemap_add, linemap_enter_macro): Adjust.
+       (linemap_line_start): Likewise.
+       (linemap_macro_expansion_map_p): Use MAP_ORDINARY_P.
+       (linemap_macro_loc_to_spelling_point): Likewise.
+       (linemap_macro_loc_to_def_point): Likewise.
+       (linemap_dump): Likewise.
+
 2018-05-23  Jason Merrill  <jason@redhat.com>
 
        * system.h: #include <new> earlier.
index d6cf81627cc21cbcbd4f1105a4398cd3847a0ae0..ba1750d3cf1bb3535bd1837dcf01cd2033be6cc1 100644 (file)
@@ -74,8 +74,9 @@ enum lc_reason
   LC_LEAVE,
   LC_RENAME,
   LC_RENAME_VERBATIM,
-  LC_ENTER_MACRO
+  LC_ENTER_MACRO,
   /* FIXME: add support for stringize and paste.  */
+  LC_HWM /* High Water Mark.  */
 };
 
 /* The typedef "source_location" is a key within the location database,
@@ -168,7 +169,7 @@ enum lc_reason
              |   Beyond this point, ordinary linemaps have 0 bits per column:
              |   each increment of the value corresponds to a new source line.
              |
-  0x70000000 | LINE_MAP_MAX_SOURCE_LOCATION
+  0x70000000 | LINE_MAP_MAX_LOCATION
              |   Beyond the point, we give up on ordinary maps; attempts to
              |   create locations in them lead to UNKNOWN_LOCATION (0).
              |
@@ -307,6 +308,9 @@ const source_location LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000;
      gcc.dg/plugin/location-overflow-test-*.c.  */
 const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
 
+/* Highest possible source location encoded within an ordinary map.  */
+const source_location LINE_MAP_MAX_LOCATION = 0x70000000;
+
 /* A range of source locations.
 
    Ranges are closed:
@@ -377,11 +381,13 @@ typedef size_t (*line_map_round_alloc_size_func) (size_t);
    location of the expansion point of PLUS. That location is mapped in
    the map that is active right before the location of the invocation
    of PLUS.  */
-struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
+
+/* This contains GTY mark-up to support precompiled headers.
+   line_map is an abstract class, only derived objects exist.  */
+struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 2"))) line_map {
   source_location start_location;
 
-  /* The reason for creation of this line map.  */
-  ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
+  /* Size and alignment is (usually) 4 bytes.  */
 };
 
 /* An ordinary line map encodes physical source locations. Those
@@ -397,13 +403,12 @@ struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
 
    The highest possible source location is MAX_SOURCE_LOCATION.  */
 struct GTY((tag ("1"))) line_map_ordinary : public line_map {
-  const char *to_file;
-  linenum_type to_line;
+  /* Base class is 4 bytes.  */
 
-  /* An index into the set that gives the line mapping at whose end
-     the current one was included.  File(s) at the bottom of the
-     include stack have this set to -1.  */
-  int included_from;
+  /* 4 bytes of integers, each 1 byte for easy extraction/insertion.  */
+
+  /* The reason for creation of this line map.  */
+  ENUM_BITFIELD (lc_reason) reason : 8;
 
   /* SYSP is one for a system header, two for a C system header file
      that therefore needs to be extern "C" protected in C++, and zero
@@ -429,6 +434,18 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
      |                         |    (e.g. 7)           |   (e.g. 5)        |
      +-------------------------+-----------------------+-------------------+ */
   unsigned int m_range_bits : 8;
+
+  /* Pointer alignment boundary on both 32 and 64-bit systems.  */
+
+  const char *to_file;
+  linenum_type to_line;
+
+  /* An index into the set that gives the line mapping at whose end
+     the current one was included.  File(s) at the bottom of the
+     include stack have this set to -1.  */
+  int included_from;
+
+  /* Size is 20 or 24 bytes, no padding  */
 };
 
 /* This is the highest possible source location encoded within an
@@ -443,15 +460,20 @@ struct cpp_hashnode;
    The offset from START_LOCATION is used to index into
    MACRO_LOCATIONS; this holds the original location of the token.  */
 struct GTY((tag ("2"))) line_map_macro : public line_map {
-  /* The cpp macro which expansion gave birth to this macro map.  */
-  struct cpp_hashnode * GTY ((nested_ptr (union tree_node,
-                                  "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
-                                  "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL")))
-    macro;
+  /* Base is 4 bytes.  */
 
   /* The number of tokens inside the replacement-list of MACRO.  */
   unsigned int n_tokens;
 
+  /* Pointer alignment boundary.  */
+
+  /* The cpp macro whose expansion gave birth to this macro map.  */
+  struct cpp_hashnode *
+    GTY ((nested_ptr (union tree_node,
+                     "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+                     "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL")))
+    macro;
+
   /* This array of location is actually an array of pairs of
      locations. The elements inside it thus look like:
 
@@ -513,6 +535,8 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
      could have been either a macro or an ordinary map, depending on
      if we are in a nested expansion context not.  */
   source_location expansion;
+
+  /* Size is 20 or 32 (4 bytes padding on 64-bit).  */
 };
 
 #if CHECKING_P && (GCC_VERSION >= 2007)
@@ -540,6 +564,14 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
 #define linemap_assert_fails(EXPR) (! (EXPR))
 #endif
 
+/* Categorize line map kinds.  */
+
+inline bool
+MAP_ORDINARY_P (const line_map *map)
+{
+  return map->start_location < LINE_MAP_MAX_LOCATION;
+}
+
 /* Return TRUE if MAP encodes locations coming from a macro
    replacement-list at macro expansion point.  */
 bool
@@ -552,7 +584,7 @@ linemap_macro_expansion_map_p (const struct line_map *);
 inline line_map_ordinary *
 linemap_check_ordinary (struct line_map *map)
 {
-  linemap_assert (!linemap_macro_expansion_map_p (map));
+  linemap_assert (MAP_ORDINARY_P (map));
   return (line_map_ordinary *)map;
 }
 
@@ -563,7 +595,7 @@ linemap_check_ordinary (struct line_map *map)
 inline const line_map_ordinary *
 linemap_check_ordinary (const struct line_map *map)
 {
-  linemap_assert (!linemap_macro_expansion_map_p (map));
+  linemap_assert (MAP_ORDINARY_P (map));
   return (const line_map_ordinary *)map;
 }
 
@@ -572,7 +604,7 @@ linemap_check_ordinary (const struct line_map *map)
 
 inline line_map_macro *linemap_check_macro (line_map *map)
 {
-  linemap_assert (linemap_macro_expansion_map_p (map));
+  linemap_assert (!MAP_ORDINARY_P (map));
   return (line_map_macro *)map;
 }
 
@@ -582,7 +614,7 @@ inline line_map_macro *linemap_check_macro (line_map *map)
 inline const line_map_macro *
 linemap_check_macro (const line_map *map)
 {
-  linemap_assert (linemap_macro_expansion_map_p (map));
+  linemap_assert (!MAP_ORDINARY_P (map));
   return (const line_map_macro *)map;
 }
 
index b2ebfeb16d44b4ad1750799d569e15a9c6bd62df..105102268cca6d193bfc09695d95e34863cfe1ac 100644 (file)
@@ -26,10 +26,6 @@ along with this program; see the file COPYING3.  If not see
 #include "internal.h"
 #include "hashtab.h"
 
-/* Highest possible source location encoded within an ordinary or
-   macro map.  */
-const source_location LINE_MAP_MAX_SOURCE_LOCATION = 0x70000000;
-
 static void trace_include (const struct line_maps *, const line_map_ordinary *);
 static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
                                                              source_location);
@@ -378,13 +374,10 @@ linemap_check_files_exited (struct line_maps *set)
    macro maps are allocated in different memory location.  */
 
 static struct line_map *
-new_linemap (struct line_maps *set,
-            enum lc_reason reason)
+new_linemap (struct line_maps *set,  source_location start_location)
 {
-  /* Depending on this variable, a macro map would be allocated in a
-     different memory location than an ordinary map.  */
-  bool macro_map_p = (reason == LC_ENTER_MACRO);
   struct line_map *result;
+  bool macro_map_p = start_location >= LINE_MAP_MAX_LOCATION;
 
   if (LINEMAPS_USED (set, macro_map_p) == LINEMAPS_ALLOCATED (set, macro_map_p))
     {
@@ -455,9 +448,10 @@ new_linemap (struct line_maps *set,
        result = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
     }
 
+  result->start_location = start_location;
+
   LINEMAPS_USED (set, macro_map_p)++;
 
-  result->reason = reason;
   return result;
 }
 
@@ -492,9 +486,9 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
   else
     start_location = set->highest_location + 1;
 
-  linemap_assert (!(LINEMAPS_ORDINARY_USED (set)
-                   && (start_location
-                       < MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))));
+  linemap_assert (!LINEMAPS_ORDINARY_USED (set)
+                 || (start_location
+                     >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
 
   /* When we enter the file for the first time reason cannot be
      LC_RENAME.  */
@@ -510,7 +504,9 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
     }
 
   linemap_assert (reason != LC_ENTER_MACRO);
-  line_map_ordinary *map = linemap_check_ordinary (new_linemap (set, reason));
+  line_map_ordinary *map
+    = linemap_check_ordinary (new_linemap (set, start_location));
+  map->reason = reason;
 
   if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
     to_file = "<stdin>";
@@ -545,7 +541,6 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
     }
 
   map->sysp = sysp;
-  map->start_location = start_location;
   map->to_file = to_file;
   map->to_line = to_line;
   LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1;
@@ -626,14 +621,12 @@ linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
 
   start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
 
-  if (start_location <= set->highest_line
-      || start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
+  if (start_location < LINE_MAP_MAX_LOCATION)
     /* We ran out of macro map space.   */
     return NULL;
 
-  map = linemap_check_macro (new_linemap (set, LC_ENTER_MACRO));
+  map = linemap_check_macro (new_linemap (set, start_location));
 
-  map->start_location = start_location;
   map->macro = macro_node;
   map->n_tokens = num_tokens;
   map->macro_locations
@@ -718,7 +711,7 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
       || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
          && map->m_range_bits > 0)
       || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS
-         && (set->max_column_hint || highest >= LINE_MAP_MAX_SOURCE_LOCATION)))
+         && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION)))
     add_map = true;
   else
     max_column_hint = set->max_column_hint;
@@ -735,7 +728,7 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
          max_column_hint = 0;
          column_bits = 0;
          range_bits = 0;
-         if (highest > LINE_MAP_MAX_SOURCE_LOCATION)
+         if (highest >= LINE_MAP_MAX_LOCATION)
            return 0;
        }
       else
@@ -773,7 +766,7 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
 
   /* Locations of ordinary tokens are always lower than locations of
      macro tokens.  */
-  if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set))
+  if (r >= LINE_MAP_MAX_LOCATION)
     return 0;
 
   set->highest_line = r;
@@ -1049,9 +1042,7 @@ linemap_macro_map_lookup (struct line_maps *set, source_location line)
 bool
 linemap_macro_expansion_map_p (const struct line_map *map)
 {
-  if (!map)
-    return false;
-  return (map->reason == LC_ENTER_MACRO);
+  return map && !MAP_ORDINARY_P (map);
 }
 
 /* If LOCATION is the locus of a token in a replacement-list of a
@@ -1253,12 +1244,7 @@ linemap_location_from_macro_expansion_p (const struct line_maps *set,
     location = set->location_adhoc_data_map.data[location
                                                 & MAX_SOURCE_LOCATION].locus;
 
-  linemap_assert (location <= MAX_SOURCE_LOCATION
-                 && (set->highest_location
-                     < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
-  if (set == NULL)
-    return false;
-  return (location > set->highest_location);
+  return location >= LINE_MAP_MAX_LOCATION;
 }
 
 /* Given two virtual locations *LOC0 and *LOC1, return the first
@@ -1403,23 +1389,22 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
                                     source_location location,
                                     const line_map_ordinary **original_map)
 {
-  struct line_map *map;
   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 
   while (true)
     {
-      map = const_cast <line_map *> (linemap_lookup (set, location));
-      if (!linemap_macro_expansion_map_p (map))
-       break;
+      const struct line_map *map = linemap_lookup (set, location);
+      if (!map || MAP_ORDINARY_P (map))
+       {
+         if (original_map)
+           *original_map = (const line_map_ordinary *)map;
+         break;
+       }
 
-      location
-       = linemap_macro_map_loc_unwind_toward_spelling
-           (set, linemap_check_macro (map),
-            location);
+      location = linemap_macro_map_loc_unwind_toward_spelling
+       (set, linemap_check_macro (map), location);
     }
 
-  if (original_map)
-    *original_map = linemap_check_ordinary (map);
   return location;
 }
 
@@ -1438,29 +1423,26 @@ linemap_macro_loc_to_def_point (struct line_maps *set,
                                source_location location,
                                const line_map_ordinary **original_map)
 {
-  struct line_map *map;
-
   linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
 
-  while (true)
+  for (;;)
     {
-      source_location caret_loc;
-      if (IS_ADHOC_LOC (location))
-       caret_loc = get_location_from_adhoc_loc (set, location);
-      else
-       caret_loc = location;
+      source_location caret_loc = location;
+      if (IS_ADHOC_LOC (caret_loc))
+       caret_loc = get_location_from_adhoc_loc (set, caret_loc);
 
-      map = const_cast <line_map *> (linemap_lookup (set, caret_loc));
-      if (!linemap_macro_expansion_map_p (map))
-       break;
+      const line_map *map = linemap_lookup (set, caret_loc);
+      if (!map || MAP_ORDINARY_P (map))
+       {
+         if (original_map)
+           *original_map = (const line_map_ordinary *)map;
+         break;
+       }
 
-      location =
-       linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
-                                           caret_loc);
+      location = linemap_macro_map_loc_to_def_point
+       (linemap_check_macro (map), caret_loc);
     }
 
-  if (original_map)
-    *original_map = linemap_check_ordinary (map);
   return location;
 }
 
@@ -1770,24 +1752,29 @@ linemap_expand_location (struct line_maps *set,
 void
 linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
 {
-  const char *lc_reasons_v[LC_ENTER_MACRO + 1]
+  const char *const lc_reasons_v[LC_HWM]
       = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
          "LC_ENTER_MACRO" };
-  const char *reason;
   const line_map *map;
+  unsigned reason;
 
   if (stream == NULL)
     stream = stderr;
 
   if (!is_macro)
-    map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
+    {
+      map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
+      reason = linemap_check_ordinary (map)->reason;
+    }
   else
-    map = LINEMAPS_MACRO_MAP_AT (set, ix);
-
-  reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???";
+    {
+      map = LINEMAPS_MACRO_MAP_AT (set, ix);
+      reason = LC_ENTER_MACRO;
+    }
 
   fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n",
-          ix, (void *) map, map->start_location, reason,
+          ix, (void *) map, map->start_location,
+          reason < LC_HWM ? lc_reasons_v[reason] : "???",
           ((!is_macro
             && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
            ? "yes" : "no"));