* Tom Tromey, 2012-11-29 : > Thomas> Now, an alternative might be to have an array of instance IDs stored > at > Thomas> the struct line_maps level, with the same indices at the set of > ordinary > Thomas> maps, which would be allocated only when flag_debug_instances is used; > Thomas> when it is not used the cost would then be a single NULL pointer in > Thomas> struct line_maps. Would that be acceptable? > > I thought there was already a similar approach in place. > See location_adhoc_data. > The proliferation of ways to do this is mildly worrying.
Tom, location_adhoc_data is not really appropriate as it associates data with a single locus, whereas we need an instance identifier for all loci covered by a given line map entry. Attached to this message is an update patch based on an alternative approach, consisting in maintaining the instance ids in a parallel map that is allocated only when actually used. In this way, the cost when not using the option is reduced to a single NULL pointer in struct line_maps. This change also attempts to better document the new flag, as pointed out by Richard, and fixes a few style nits. The LTO streaming part is still missing. The updated ChangeLog is: gcc/ * common.opt (flag_debug_instances): Define new internal flag. * final.c (notice_source_line): If flag_debug_instances is set, set discriminator to current instance id. * emit-rtl.c (insn_instance): New subprogram, retrieves instance identifier from insn. * rtl.h (insn_instance): Declare. * input.h (LOCATION_INSTANCE): Define. * tree-cfg.c (assign_discriminator): If flag_debug_instances is set, nothing to do here. libcpp/ * include/line_map.h (struct line_maps): Add instance_ids field (table for use under flag_debug_instances). (expanded_location): Add instance id field. (LINEMAPS_INSTANCE_IDS): Define. (ORDINARY_MAP_INSTANCE): Define. * line-map.c (linemap_expand_location): Set instance field in expanded location from same in set. Index: gcc/rtl.h =================================================================== --- gcc/rtl.h (révision 193884) +++ gcc/rtl.h (copie de travail) @@ -1917,6 +1917,7 @@ /* In emit-rtl.c */ extern int insn_line (const_rtx); extern const char * insn_file (const_rtx); +extern int insn_instance (const_rtx); extern tree insn_scope (const_rtx); extern location_t prologue_location, epilogue_location; Index: gcc/final.c =================================================================== --- gcc/final.c (révision 193884) +++ gcc/final.c (copie de travail) @@ -2894,6 +2894,8 @@ { filename = insn_file (insn); linenum = insn_line (insn); + if (flag_debug_instances) + discriminator = insn_instance (insn); } if (filename == NULL) Index: gcc/input.h =================================================================== --- gcc/input.h (révision 193884) +++ gcc/input.h (copie de travail) @@ -51,6 +51,7 @@ #define LOCATION_FILE(LOC) ((expand_location (LOC)).file) #define LOCATION_LINE(LOC) ((expand_location (LOC)).line) #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column) +#define LOCATION_INSTANCE(LOC) ((expand_location (LOC)).instance) #define LOCATION_LOCUS(LOC) \ ((IS_ADHOC_LOC(LOC)) ? get_location_from_adhoc_loc (line_table, LOC) : (LOC)) #define LOCATION_BLOCK(LOC) \ Index: gcc/emit-rtl.c =================================================================== --- gcc/emit-rtl.c (révision 193884) +++ gcc/emit-rtl.c (copie de travail) @@ -6007,6 +6007,14 @@ return LOCATION_FILE (INSN_LOCATION (insn)); } +/* Return source instance of the statement that produced this insn. */ + +int +insn_instance (const_rtx insn) +{ + return LOCATION_INSTANCE (INSN_LOCATION (insn)); +} + /* Return true if memory model MODEL requires a pre-operation (release-style) barrier or a post-operation (acquire-style) barrier. While not universal, this function matches behavior of several targets. */ Index: gcc/common.opt =================================================================== --- gcc/common.opt (révision 193884) +++ gcc/common.opt (copie de travail) @@ -158,6 +158,15 @@ Variable int flag_debug_asm +; Language front-ends that support multiple instantiations of a given +; source template (such as Ada with generics) may enable this flag, and +; provide instance identifiers in the line map, so that discriminators in +; DWARF debugging information carry these instance identifiers, allowing +; external tools to identify which instance a given object instruction comes +; from. +Variable +int flag_debug_instances = 0 + ; -dP causes the rtl to be emitted as a comment in assembly. Variable int flag_dump_rtl_in_asm Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (révision 193884) +++ gcc/tree-cfg.c (copie de travail) @@ -768,7 +768,7 @@ { gimple first_in_to_bb, last_in_to_bb; - if (locus == 0 || bb->discriminator != 0) + if (locus == 0 || bb->discriminator != 0 || flag_debug_instances) return; first_in_to_bb = first_non_label_stmt (bb); Index: libcpp/include/line-map.h =================================================================== --- libcpp/include/line-map.h (révision 193884) +++ libcpp/include/line-map.h (copie de travail) @@ -230,6 +230,12 @@ #define ORDINARY_MAP_NUMBER_OF_COLUMN_BITS(MAP) \ linemap_check_ordinary (MAP)->d.ordinary.column_bits +#define ORDINARY_MAP_INSTANCE(SET,MAP) \ + (LINEMAPS_INSTANCE_IDS(SET) != NULL ? \ + LINEMAPS_INSTANCE_IDS(SET)[linemap_check_ordinary (MAP) - \ + LINEMAPS_ORDINARY_MAP_AT(SET, 0)] : \ + 0) + #define MACRO_MAP_MACRO(MAP) (MAP)->d.macro.macro #define MACRO_MAP_NUM_MACRO_TOKENS(MAP) (MAP)->d.macro.n_tokens @@ -291,6 +297,13 @@ struct maps_info info_macro; + /* For languages that have the notion of instantiating a given template + multiple times, different line_maps can be allocated for each instance, + which are distinguished by an instance identifier. When + flag_debug_instaces is enabled, this table (which has the same indices + as the ordinary linemaps in this set) stores these instance ids. */ + int * GTY((atomic)) instance_ids; + /* Depth of the include stack, including the current file. */ unsigned int depth; @@ -369,6 +382,11 @@ #define LINEMAPS_ORDINARY_MAPS(SET) \ LINEMAPS_MAPS (SET, false) +/* Returns the vector of instance identifiers associated to ordinary maps in + the line table SET. */ +#define LINEMAPS_INSTANCE_IDS(SET) \ + (SET)->instance_ids + /* Returns the INDEXth ordinary map. */ #define LINEMAPS_ORDINARY_MAP_AT(SET, INDEX) \ LINEMAPS_MAP_AT (SET, false, INDEX) @@ -638,6 +656,9 @@ /* In a system header?. */ bool sysp; + + /* Instance id. */ + int instance; } expanded_location; /* This is enum is used by the function linemap_resolve_location Index: libcpp/line-map.c =================================================================== --- libcpp/line-map.c (révision 193884) +++ libcpp/line-map.c (copie de travail) @@ -1395,6 +1395,7 @@ xloc.line = SOURCE_LINE (map, loc); xloc.column = SOURCE_COLUMN (map, loc); xloc.sysp = LINEMAP_SYSP (map) != 0; + xloc.instance = ORDINARY_MAP_INSTANCE (set, map); } return xloc;