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:
parent
42addb5adf
commit
42a98b43bb
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in New Issue