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.

From-SVN: r262348
This commit is contained in:
Nathan Sidwell 2018-07-03 14:47:11 +00:00 committed by Nathan Sidwell
parent 42addb5adf
commit 42a98b43bb
3 changed files with 123 additions and 84 deletions

View 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> 2018-05-23 Jason Merrill <jason@redhat.com>
* system.h: #include <new> earlier. * system.h: #include <new> earlier.

View File

@ -74,8 +74,9 @@ enum lc_reason
LC_LEAVE, LC_LEAVE,
LC_RENAME, LC_RENAME,
LC_RENAME_VERBATIM, LC_RENAME_VERBATIM,
LC_ENTER_MACRO LC_ENTER_MACRO,
/* FIXME: add support for stringize and paste. */ /* FIXME: add support for stringize and paste. */
LC_HWM /* High Water Mark. */
}; };
/* The typedef "source_location" is a key within the location database, /* 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: | Beyond this point, ordinary linemaps have 0 bits per column:
| each increment of the value corresponds to a new source line. | 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 | Beyond the point, we give up on ordinary maps; attempts to
| create locations in them lead to UNKNOWN_LOCATION (0). | 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. */ gcc.dg/plugin/location-overflow-test-*.c. */
const source_location LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000; 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. /* A range of source locations.
Ranges are closed: 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 location of the expansion point of PLUS. That location is mapped in
the map that is active right before the location of the invocation the map that is active right before the location of the invocation
of PLUS. */ 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; source_location start_location;
/* The reason for creation of this line map. */ /* Size and alignment is (usually) 4 bytes. */
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
}; };
/* An ordinary line map encodes physical source locations. Those /* 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. */ The highest possible source location is MAX_SOURCE_LOCATION. */
struct GTY((tag ("1"))) line_map_ordinary : public line_map { struct GTY((tag ("1"))) line_map_ordinary : public line_map {
const char *to_file; /* Base class is 4 bytes. */
linenum_type to_line;
/* An index into the set that gives the line mapping at whose end /* 4 bytes of integers, each 1 byte for easy extraction/insertion. */
the current one was included. File(s) at the bottom of the
include stack have this set to -1. */ /* The reason for creation of this line map. */
int included_from; ENUM_BITFIELD (lc_reason) reason : 8;
/* SYSP is one for a system header, two for a C system header file /* 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 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) | | | (e.g. 7) | (e.g. 5) |
+-------------------------+-----------------------+-------------------+ */ +-------------------------+-----------------------+-------------------+ */
unsigned int m_range_bits : 8; 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 /* 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 The offset from START_LOCATION is used to index into
MACRO_LOCATIONS; this holds the original location of the token. */ MACRO_LOCATIONS; this holds the original location of the token. */
struct GTY((tag ("2"))) line_map_macro : public line_map { struct GTY((tag ("2"))) line_map_macro : public line_map {
/* The cpp macro which expansion gave birth to this macro map. */ /* Base is 4 bytes. */
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;
/* The number of tokens inside the replacement-list of MACRO. */ /* The number of tokens inside the replacement-list of MACRO. */
unsigned int n_tokens; 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 /* This array of location is actually an array of pairs of
locations. The elements inside it thus look like: 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 could have been either a macro or an ordinary map, depending on
if we are in a nested expansion context not. */ if we are in a nested expansion context not. */
source_location expansion; source_location expansion;
/* Size is 20 or 32 (4 bytes padding on 64-bit). */
}; };
#if CHECKING_P && (GCC_VERSION >= 2007) #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)) #define linemap_assert_fails(EXPR) (! (EXPR))
#endif #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 /* Return TRUE if MAP encodes locations coming from a macro
replacement-list at macro expansion point. */ replacement-list at macro expansion point. */
bool bool
@ -552,7 +584,7 @@ linemap_macro_expansion_map_p (const struct line_map *);
inline line_map_ordinary * inline line_map_ordinary *
linemap_check_ordinary (struct line_map *map) 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; return (line_map_ordinary *)map;
} }
@ -563,7 +595,7 @@ linemap_check_ordinary (struct line_map *map)
inline const line_map_ordinary * inline const line_map_ordinary *
linemap_check_ordinary (const struct line_map *map) 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; 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) 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; return (line_map_macro *)map;
} }
@ -582,7 +614,7 @@ inline line_map_macro *linemap_check_macro (line_map *map)
inline const line_map_macro * inline const line_map_macro *
linemap_check_macro (const line_map *map) 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; return (const line_map_macro *)map;
} }

View File

@ -26,10 +26,6 @@ along with this program; see the file COPYING3. If not see
#include "internal.h" #include "internal.h"
#include "hashtab.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 void trace_include (const struct line_maps *, const line_map_ordinary *);
static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *, static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
source_location); source_location);
@ -378,13 +374,10 @@ linemap_check_files_exited (struct line_maps *set)
macro maps are allocated in different memory location. */ macro maps are allocated in different memory location. */
static struct line_map * static struct line_map *
new_linemap (struct line_maps *set, new_linemap (struct line_maps *set, source_location start_location)
enum lc_reason reason)
{ {
/* 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; 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)) 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 = &set->info_ordinary.maps[LINEMAPS_USED (set, macro_map_p)];
} }
result->start_location = start_location;
LINEMAPS_USED (set, macro_map_p)++; LINEMAPS_USED (set, macro_map_p)++;
result->reason = reason;
return result; return result;
} }
@ -492,9 +486,9 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
else else
start_location = set->highest_location + 1; start_location = set->highest_location + 1;
linemap_assert (!(LINEMAPS_ORDINARY_USED (set) linemap_assert (!LINEMAPS_ORDINARY_USED (set)
&& (start_location || (start_location
< MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))))); >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set))));
/* When we enter the file for the first time reason cannot be /* When we enter the file for the first time reason cannot be
LC_RENAME. */ LC_RENAME. */
@ -510,7 +504,9 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
} }
linemap_assert (reason != LC_ENTER_MACRO); 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) if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM)
to_file = "<stdin>"; to_file = "<stdin>";
@ -545,7 +541,6 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
} }
map->sysp = sysp; map->sysp = sysp;
map->start_location = start_location;
map->to_file = to_file; map->to_file = to_file;
map->to_line = to_line; map->to_line = to_line;
LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1; 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; start_location = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens;
if (start_location <= set->highest_line if (start_location < LINE_MAP_MAX_LOCATION)
|| start_location > LINEMAPS_MACRO_LOWEST_LOCATION (set))
/* We ran out of macro map space. */ /* We ran out of macro map space. */
return NULL; 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->macro = macro_node;
map->n_tokens = num_tokens; map->n_tokens = num_tokens;
map->macro_locations 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 || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES
&& map->m_range_bits > 0) && map->m_range_bits > 0)
|| (highest > LINE_MAP_MAX_LOCATION_WITH_COLS || (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; add_map = true;
else else
max_column_hint = set->max_column_hint; 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; max_column_hint = 0;
column_bits = 0; column_bits = 0;
range_bits = 0; range_bits = 0;
if (highest > LINE_MAP_MAX_SOURCE_LOCATION) if (highest >= LINE_MAP_MAX_LOCATION)
return 0; return 0;
} }
else 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 /* Locations of ordinary tokens are always lower than locations of
macro tokens. */ macro tokens. */
if (r >= LINEMAPS_MACRO_LOWEST_LOCATION (set)) if (r >= LINE_MAP_MAX_LOCATION)
return 0; return 0;
set->highest_line = r; set->highest_line = r;
@ -1049,9 +1042,7 @@ linemap_macro_map_lookup (struct line_maps *set, source_location line)
bool bool
linemap_macro_expansion_map_p (const struct line_map *map) linemap_macro_expansion_map_p (const struct line_map *map)
{ {
if (!map) return map && !MAP_ORDINARY_P (map);
return false;
return (map->reason == LC_ENTER_MACRO);
} }
/* If LOCATION is the locus of a token in a replacement-list of a /* 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 location = set->location_adhoc_data_map.data[location
& MAX_SOURCE_LOCATION].locus; & MAX_SOURCE_LOCATION].locus;
linemap_assert (location <= MAX_SOURCE_LOCATION return location >= LINE_MAP_MAX_LOCATION;
&& (set->highest_location
< LINEMAPS_MACRO_LOWEST_LOCATION (set)));
if (set == NULL)
return false;
return (location > set->highest_location);
} }
/* Given two virtual locations *LOC0 and *LOC1, return the first /* 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, source_location location,
const line_map_ordinary **original_map) const line_map_ordinary **original_map)
{ {
struct line_map *map;
linemap_assert (set && location >= RESERVED_LOCATION_COUNT); linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true) while (true)
{ {
map = const_cast <line_map *> (linemap_lookup (set, location)); const struct line_map *map = linemap_lookup (set, location);
if (!linemap_macro_expansion_map_p (map)) if (!map || MAP_ORDINARY_P (map))
{
if (original_map)
*original_map = (const line_map_ordinary *)map;
break; break;
location
= linemap_macro_map_loc_unwind_toward_spelling
(set, linemap_check_macro (map),
location);
} }
if (original_map) location = linemap_macro_map_loc_unwind_toward_spelling
*original_map = linemap_check_ordinary (map); (set, linemap_check_macro (map), location);
}
return location; return location;
} }
@ -1438,29 +1423,26 @@ linemap_macro_loc_to_def_point (struct line_maps *set,
source_location location, source_location location,
const line_map_ordinary **original_map) const line_map_ordinary **original_map)
{ {
struct line_map *map;
linemap_assert (set && location >= RESERVED_LOCATION_COUNT); linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true) for (;;)
{ {
source_location caret_loc; source_location caret_loc = location;
if (IS_ADHOC_LOC (location)) if (IS_ADHOC_LOC (caret_loc))
caret_loc = get_location_from_adhoc_loc (set, location); caret_loc = get_location_from_adhoc_loc (set, caret_loc);
else
caret_loc = location;
map = const_cast <line_map *> (linemap_lookup (set, caret_loc)); const line_map *map = linemap_lookup (set, caret_loc);
if (!linemap_macro_expansion_map_p (map)) if (!map || MAP_ORDINARY_P (map))
{
if (original_map)
*original_map = (const line_map_ordinary *)map;
break; break;
location =
linemap_macro_map_loc_to_def_point (linemap_check_macro (map),
caret_loc);
} }
if (original_map) location = linemap_macro_map_loc_to_def_point
*original_map = linemap_check_ordinary (map); (linemap_check_macro (map), caret_loc);
}
return location; return location;
} }
@ -1770,24 +1752,29 @@ linemap_expand_location (struct line_maps *set,
void void
linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro) 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", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
"LC_ENTER_MACRO" }; "LC_ENTER_MACRO" };
const char *reason;
const line_map *map; const line_map *map;
unsigned reason;
if (stream == NULL) if (stream == NULL)
stream = stderr; stream = stderr;
if (!is_macro) if (!is_macro)
{
map = LINEMAPS_ORDINARY_MAP_AT (set, ix); map = LINEMAPS_ORDINARY_MAP_AT (set, ix);
reason = linemap_check_ordinary (map)->reason;
}
else else
{
map = LINEMAPS_MACRO_MAP_AT (set, ix); map = LINEMAPS_MACRO_MAP_AT (set, ix);
reason = LC_ENTER_MACRO;
reason = (map->reason <= LC_ENTER_MACRO) ? lc_reasons_v[map->reason] : "???"; }
fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n", 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 ((!is_macro
&& ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map))) && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map)))
? "yes" : "no")); ? "yes" : "no"));