diff options
-rw-r--r-- | gcc/basic-block.h | 5 | ||||
-rw-r--r-- | gcc/cfghooks.cc | 1 | ||||
-rw-r--r-- | gcc/cp/module.cc | 5 | ||||
-rw-r--r-- | gcc/final.cc | 26 | ||||
-rw-r--r-- | gcc/gimple-pretty-print.cc | 2 | ||||
-rw-r--r-- | gcc/gimple-streamer-in.cc | 1 | ||||
-rw-r--r-- | gcc/gimple-streamer-out.cc | 1 | ||||
-rw-r--r-- | gcc/input.cc | 36 | ||||
-rw-r--r-- | gcc/input.h | 4 | ||||
-rw-r--r-- | gcc/lto-streamer-in.cc | 19 | ||||
-rw-r--r-- | gcc/lto-streamer-out.cc | 7 | ||||
-rw-r--r-- | gcc/lto-streamer.h | 3 | ||||
-rw-r--r-- | gcc/print-rtl.cc | 4 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/ubsan/pr85213.c | 7 | ||||
-rw-r--r-- | gcc/tree-cfg.cc | 49 | ||||
-rw-r--r-- | gcc/tree-pretty-print.cc | 6 | ||||
-rw-r--r-- | gcc/tree.cc | 10 | ||||
-rw-r--r-- | libcpp/include/line-map.h | 10 | ||||
-rw-r--r-- | libcpp/lex.cc | 7 | ||||
-rw-r--r-- | libcpp/line-map.cc | 38 |
21 files changed, 187 insertions, 55 deletions
diff --git a/gcc/basic-block.h b/gcc/basic-block.h index c9d1fc9..1eae03d 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -148,11 +148,6 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d /* Expected number of executions: calculated in profile.cc. */ profile_count count; - - /* The discriminator for this block. The discriminator distinguishes - among several basic blocks that share a common locus, allowing for - more accurate sample-based profiling. */ - int discriminator; }; /* This ensures that struct gimple_bb_info is smaller than diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc index c6ac953..29ded57 100644 --- a/gcc/cfghooks.cc +++ b/gcc/cfghooks.cc @@ -541,7 +541,6 @@ split_block_1 (basic_block bb, void *i) return NULL; new_bb->count = bb->count; - new_bb->discriminator = bb->discriminator; if (dom_info_available_p (CDI_DOMINATORS)) { diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 7496df5..d965017 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -15777,6 +15777,8 @@ module_state::write_location (bytes_out &sec, location_t loc) range.m_start = UNKNOWN_LOCATION; write_location (sec, range.m_start); write_location (sec, range.m_finish); + unsigned discriminator = get_discriminator_from_adhoc_loc (line_table, loc); + sec.u (discriminator); } else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table)) { @@ -15902,8 +15904,9 @@ module_state::read_location (bytes_in &sec) const if (range.m_start == UNKNOWN_LOCATION) range.m_start = locus; range.m_finish = read_location (sec); + unsigned discriminator = sec.u (); if (locus != loc && range.m_start != loc && range.m_finish != loc) - locus = get_combined_adhoc_loc (line_table, locus, range, NULL); + locus = get_combined_adhoc_loc (line_table, locus, range, NULL, discriminator); } break; diff --git a/gcc/final.cc b/gcc/final.cc index c0bfdf6..eea5722 100644 --- a/gcc/final.cc +++ b/gcc/final.cc @@ -118,18 +118,10 @@ static int last_columnnum; /* Discriminator written to assembly. */ static int last_discriminator; -/* Discriminator to be written to assembly for current instruction. +/* Compute discriminator to be written to assembly for current instruction. Note: actual usage depends on loc_discriminator_kind setting. */ -static int discriminator; static inline int compute_discriminator (location_t loc); -/* Discriminator identifying current basic block among others sharing - the same locus. */ -static int bb_discriminator; - -/* Basic block discriminator for previous instruction. */ -static int last_bb_discriminator; - /* Highest line number in current block. */ static int high_block_linenum; @@ -1688,8 +1680,7 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen, last_filename = LOCATION_FILE (prologue_location); last_linenum = LOCATION_LINE (prologue_location); last_columnnum = LOCATION_COLUMN (prologue_location); - last_discriminator = discriminator = 0; - last_bb_discriminator = bb_discriminator = 0; + last_discriminator = 0; force_source_line = false; high_block_linenum = high_function_linenum = last_linenum; @@ -2234,7 +2225,6 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, if (targetm.asm_out.unwind_emit) targetm.asm_out.unwind_emit (asm_out_file, insn); - bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; break; case NOTE_INSN_EH_REGION_BEG: @@ -2939,7 +2929,7 @@ compute_discriminator (location_t loc) int discriminator; if (!decl_to_instance_map) - discriminator = bb_discriminator; + discriminator = get_discriminator_from_loc (loc); else { tree block = LOCATION_BLOCK (loc); @@ -2963,6 +2953,13 @@ compute_discriminator (location_t loc) return discriminator; } +/* Return discriminator of the statement that produced this insn. */ +int +insn_discriminator (const rtx_insn *insn) +{ + return compute_discriminator (INSN_LOCATION (insn)); +} + /* Return whether a source line note needs to be emitted before INSN. Sets IS_STMT to TRUE if the line should be marked as a possible breakpoint location. */ @@ -2972,6 +2969,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt) { const char *filename; int linenum, columnnum; + int discriminator; if (NOTE_MARKER_P (insn)) { @@ -3001,7 +2999,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt) filename = xloc.file; linenum = xloc.line; columnnum = xloc.column; - discriminator = compute_discriminator (INSN_LOCATION (insn)); + discriminator = insn_discriminator (insn); } else { diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc index f18baec..a87e2ae 100644 --- a/gcc/gimple-pretty-print.cc +++ b/gcc/gimple-pretty-print.cc @@ -2875,8 +2875,6 @@ dump_gimple_bb_header (FILE *outf, basic_block bb, int indent, indent, "", get_lineno (gsi_stmt (gsi))); break; } - if (bb->discriminator) - fprintf (outf, ", discriminator %i", bb->discriminator); fputc ('\n', outf); } } diff --git a/gcc/gimple-streamer-in.cc b/gcc/gimple-streamer-in.cc index e7f3256..ea8891e 100644 --- a/gcc/gimple-streamer-in.cc +++ b/gcc/gimple-streamer-in.cc @@ -267,7 +267,6 @@ input_bb (class lto_input_block *ib, enum LTO_tags tag, bb->count = bb->count.apply_scale (count_materialization_scale, REG_BR_PROB_BASE); bb->flags = streamer_read_hwi (ib); - bb->discriminator = streamer_read_hwi (ib); /* LTO_bb1 has statements. LTO_bb0 does not. */ if (tag == LTO_bb0) diff --git a/gcc/gimple-streamer-out.cc b/gcc/gimple-streamer-out.cc index 3336525..4583254 100644 --- a/gcc/gimple-streamer-out.cc +++ b/gcc/gimple-streamer-out.cc @@ -208,7 +208,6 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn) streamer_write_uhwi (ob, bb->index); bb->count.stream_out (ob); streamer_write_hwi (ob, bb->flags); - streamer_write_hwi (ob, bb->discriminator); if (!gsi_end_p (bsi) || phi_nodes (bb)) { diff --git a/gcc/input.cc b/gcc/input.cc index 060ca16..a28abfa 100644 --- a/gcc/input.cc +++ b/gcc/input.cc @@ -1082,7 +1082,8 @@ make_location (location_t caret, location_t start, location_t finish) location_t combined_loc = COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, - NULL); + NULL, + 0); return combined_loc; } @@ -1092,7 +1093,7 @@ location_t make_location (location_t caret, source_range src_range) { location_t pure_loc = get_pure_location (caret); - return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, NULL); + return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, NULL, 0); } /* An expanded_location stores the column in byte units. This function @@ -1766,6 +1767,37 @@ get_location_within_string (cpp_reader *pfile, return NULL; } +/* Associate the DISCRIMINATOR with LOCUS, and return a new locus. */ + +location_t +location_with_discriminator (location_t locus, int discriminator) +{ + tree block = LOCATION_BLOCK (locus); + source_range src_range = get_range_from_loc (line_table, locus); + locus = get_pure_location (locus); + + if (locus == UNKNOWN_LOCATION) + return locus; + + return COMBINE_LOCATION_DATA (line_table, locus, src_range, block, discriminator); +} + +/* Return TRUE if LOCUS represents a location with a discriminator. */ + +bool +has_discriminator (location_t locus) +{ + return get_discriminator_from_loc (locus) != 0; +} + +/* Return the discriminator for LOCUS. */ + +int +get_discriminator_from_loc (location_t locus) +{ + return get_discriminator_from_loc (line_table, locus); +} + #if CHECKING_P namespace selftest { diff --git a/gcc/input.h b/gcc/input.h index f1ae3ae..11c571d 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -165,6 +165,10 @@ extern location_t expansion_point_location (location_t); extern location_t input_location; +extern location_t location_with_discriminator (location_t, int); +extern bool has_discriminator (location_t); +extern int get_discriminator_from_loc (location_t); + #define LOCATION_FILE(LOC) ((expand_location (LOC)).file) #define LOCATION_LINE(LOC) ((expand_location (LOC)).line) #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column) diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc index a7dad70..fa89634 100644 --- a/gcc/lto-streamer-in.cc +++ b/gcc/lto-streamer-in.cc @@ -409,6 +409,8 @@ lto_location_cache::cmp_loc (const void *pa, const void *pb) return a->line - b->line; if (a->col != b->col) return a->col - b->col; + if (a->discr != b->discr) + return a->discr - b->discr; if ((a->block == NULL_TREE) != (b->block == NULL_TREE)) return a->block ? 1 : -1; if (a->block) @@ -460,6 +462,8 @@ lto_location_cache::apply_location_cache () current_loc = linemap_position_for_column (line_table, loc.col); if (loc.block) current_loc = set_block (current_loc, loc.block); + if (loc.discr) + current_loc = location_with_discriminator (current_loc, loc.discr); } else if (current_block != loc.block) { @@ -467,12 +471,17 @@ lto_location_cache::apply_location_cache () current_loc = set_block (current_loc, loc.block); else current_loc = LOCATION_LOCUS (current_loc); + if (loc.discr) + current_loc = location_with_discriminator (current_loc, loc.discr); } + else if (current_discr != loc.discr) + current_loc = location_with_discriminator (current_loc, loc.discr); *loc.loc = current_loc; current_line = loc.line; prev_file = current_file = loc.file; current_col = loc.col; current_block = loc.block; + current_discr = loc.discr; } loc_cache.truncate (0); accepted_length = 0; @@ -512,6 +521,7 @@ lto_location_cache::input_location_and_block (location_t *loc, static int stream_col; static bool stream_sysp; static tree stream_block; + static unsigned stream_discr; static const char *stream_relative_path_prefix; gcc_assert (current_cache == this); @@ -538,6 +548,7 @@ lto_location_cache::input_location_and_block (location_t *loc, *loc = RESERVED_LOCATION_COUNT; bool line_change = bp_unpack_value (bp, 1); bool column_change = bp_unpack_value (bp, 1); + bool discr_change = bp_unpack_value (bp, 1); if (file_change) { @@ -563,6 +574,9 @@ lto_location_cache::input_location_and_block (location_t *loc, if (column_change) stream_col = bp_unpack_var_len_unsigned (bp); + if (discr_change) + stream_discr = bp_unpack_var_len_unsigned (bp); + tree block = NULL_TREE; if (ib) { @@ -578,7 +592,8 @@ lto_location_cache::input_location_and_block (location_t *loc, if (current_file == stream_file && current_line == stream_line && current_col == stream_col - && current_sysp == stream_sysp) + && current_sysp == stream_sysp + && current_discr == stream_discr) { if (current_block == block) *loc = current_loc; @@ -590,7 +605,7 @@ lto_location_cache::input_location_and_block (location_t *loc, } struct cached_location entry - = {stream_file, loc, stream_line, stream_col, stream_sysp, block}; + = {stream_file, loc, stream_line, stream_col, stream_sysp, block, stream_discr}; loc_cache.safe_push (entry); } diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc index 1bc3f55..2e7af03 100644 --- a/gcc/lto-streamer-out.cc +++ b/gcc/lto-streamer-out.cc @@ -67,6 +67,7 @@ clear_line_info (struct output_block *ob) so that the first location with block in a function etc. always streams a change_block bit and the first block. */ ob->current_block = void_node; + ob->current_discr = UINT_MAX; } @@ -194,6 +195,7 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp, if (loc >= RESERVED_LOCATION_COUNT) { expanded_location xloc = expand_location (loc); + unsigned discr = get_discriminator_from_loc (orig_loc); if (ob->reset_locus) { @@ -216,6 +218,7 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp, bp_pack_value (bp, ob->current_line != xloc.line, 1); bp_pack_value (bp, ob->current_col != xloc.column, 1); + bp_pack_value (bp, ob->current_discr != discr, 1); if (ob->current_file != xloc.file) { @@ -242,6 +245,10 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp, if (ob->current_col != xloc.column) bp_pack_var_len_unsigned (bp, xloc.column); ob->current_col = xloc.column; + + if (ob->current_discr != discr) + bp_pack_var_len_unsigned (bp, discr); + ob->current_discr = discr; } else bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT + 1, loc); diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 597e9e4..2e3abd9 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -311,6 +311,7 @@ private: int line, col; bool sysp; tree block; + unsigned discr; }; /* The location cache. */ @@ -333,6 +334,7 @@ private: bool current_sysp; location_t current_loc; tree current_block; + unsigned current_discr; }; /* Structure used as buffer for reading an LTO file. */ @@ -723,6 +725,7 @@ struct output_block bool reset_locus; bool emit_pwd; tree current_block; + unsigned current_discr; /* Cache of nodes written in this section. */ struct streamer_tree_cache_d *writer_cache; diff --git a/gcc/print-rtl.cc b/gcc/print-rtl.cc index 60c8454..e115f98 100644 --- a/gcc/print-rtl.cc +++ b/gcc/print-rtl.cc @@ -453,6 +453,10 @@ rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx) expanded_location xloc = insn_location (in_insn); fprintf (m_outfile, " \"%s\":%i:%i", xloc.file, xloc.line, xloc.column); + int discriminator = insn_discriminator (in_insn); + if (discriminator) + fprintf (m_outfile, " discrim %d", discriminator); + } #endif } @@ -3369,6 +3369,7 @@ extern int insn_line (const rtx_insn *); extern const char * insn_file (const rtx_insn *); extern tree insn_scope (const rtx_insn *); extern expanded_location insn_location (const rtx_insn *); +extern int insn_discriminator (const rtx_insn *); extern location_t prologue_location, epilogue_location; /* In jump.cc */ diff --git a/gcc/testsuite/c-c++-common/ubsan/pr85213.c b/gcc/testsuite/c-c++-common/ubsan/pr85213.c index 8a6be81..e903e97 100644 --- a/gcc/testsuite/c-c++-common/ubsan/pr85213.c +++ b/gcc/testsuite/c-c++-common/ubsan/pr85213.c @@ -1,6 +1,11 @@ /* PR sanitizer/85213 */ /* { dg-do compile } */ -/* { dg-options "-O1 -fsanitize=undefined -fcompare-debug" } */ +/* Pass -gno-statement-frontiers to work around + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100733 : + without it the IR coming from the front end may be different with and without + debug information turned on. That may cause e.g., different discriminator values + and -fcompare-debug failures. */ +/* { dg-options "-O1 -fsanitize=undefined -fcompare-debug -gno-statement-frontiers" } */ int foo (int x) diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 53be0c2..ade66c5 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -1166,7 +1166,33 @@ same_line_p (location_t locus1, expanded_location *from, location_t locus2) && filename_cmp (from->file, to.file) == 0); } -/* Assign discriminators to each basic block. */ +/* Assign a unique discriminator value to all statements in block bb that + have the same line number as locus. */ + +static void +assign_discriminator (location_t locus, basic_block bb) +{ + gimple_stmt_iterator gsi; + int discriminator; + + if (locus == UNKNOWN_LOCATION) + return; + + expanded_location locus_e = expand_location (locus); + + discriminator = next_discriminator_for_locus (locus_e.line); + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + location_t stmt_locus = gimple_location (stmt); + if (same_line_p (locus, &locus_e, stmt_locus)) + gimple_set_location (stmt, + location_with_discriminator (stmt_locus, discriminator)); + } +} + +/* Assign discriminators to statement locations. */ static void assign_discriminators (void) @@ -1189,17 +1215,22 @@ assign_discriminators (void) { gimple *first = first_non_label_stmt (e->dest); gimple *last = last_stmt (e->dest); - if ((first && same_line_p (locus, &locus_e, + + gimple *stmt_on_same_line = NULL; + if (first && same_line_p (locus, &locus_e, gimple_location (first))) - || (last && same_line_p (locus, &locus_e, - gimple_location (last)))) + stmt_on_same_line = first; + else if (last && same_line_p (locus, &locus_e, + gimple_location (last))) + stmt_on_same_line = last; + + if (stmt_on_same_line) { - if (e->dest->discriminator != 0 && bb->discriminator == 0) - bb->discriminator - = next_discriminator_for_locus (locus_e.line); + if (has_discriminator (gimple_location (stmt_on_same_line)) + && !has_discriminator (locus)) + assign_discriminator (locus, bb); else - e->dest->discriminator - = next_discriminator_for_locus (locus_e.line); + assign_discriminator (locus, e->dest); } } } diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc index 33b12c7..e7a8c94 100644 --- a/gcc/tree-pretty-print.cc +++ b/gcc/tree-pretty-print.cc @@ -1455,6 +1455,7 @@ void dump_location (pretty_printer *pp, location_t loc) { expanded_location xloc = expand_location (loc); + int discriminator = get_discriminator_from_loc (loc); pp_left_bracket (pp); if (xloc.file) @@ -1465,6 +1466,11 @@ dump_location (pretty_printer *pp, location_t loc) pp_decimal_int (pp, xloc.line); pp_colon (pp); pp_decimal_int (pp, xloc.column); + if (discriminator) + { + pp_string (pp, " discrim "); + pp_decimal_int (pp, discriminator); + } pp_string (pp, "] "); } diff --git a/gcc/tree.cc b/gcc/tree.cc index 756c14f..f8d24b5 100644 --- a/gcc/tree.cc +++ b/gcc/tree.cc @@ -14253,7 +14253,8 @@ set_block (location_t loc, tree block) { location_t pure_loc = get_pure_location (loc); source_range src_range = get_range_from_loc (line_table, loc); - return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block); + unsigned discriminator = get_discriminator_from_loc (line_table, loc); + return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block, discriminator); } location_t @@ -14271,11 +14272,14 @@ set_source_range (tree expr, source_range src_range) if (!EXPR_P (expr)) return UNKNOWN_LOCATION; - location_t pure_loc = get_pure_location (EXPR_LOCATION (expr)); + location_t expr_location = EXPR_LOCATION (expr); + location_t pure_loc = get_pure_location (expr_location); + unsigned discriminator = get_discriminator_from_loc (expr_location); location_t adhoc = COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, - NULL); + NULL, + discriminator); SET_EXPR_LOCATION (expr, adhoc); return adhoc; } diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 9bdd5b9..50207ca 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -757,6 +757,7 @@ struct GTY(()) location_adhoc_data { location_t locus; source_range src_range; void * GTY((skip)) data; + unsigned discriminator; }; struct htab; @@ -1034,12 +1035,14 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set) } extern location_t get_combined_adhoc_loc (line_maps *, location_t, - source_range, void *); + source_range, void *, unsigned); extern void *get_data_from_adhoc_loc (const line_maps *, location_t); +extern unsigned get_discriminator_from_adhoc_loc (const line_maps *, location_t); extern location_t get_location_from_adhoc_loc (const line_maps *, location_t); extern source_range get_range_from_loc (line_maps *set, location_t loc); +extern unsigned get_discriminator_from_loc (line_maps *set, location_t loc); /* Get whether location LOC is a "pure" location, or whether it is an ad-hoc location, or embeds range information. */ @@ -1058,9 +1061,10 @@ inline location_t COMBINE_LOCATION_DATA (class line_maps *set, location_t loc, source_range src_range, - void *block) + void *block, + unsigned discriminator) { - return get_combined_adhoc_loc (set, loc, src_range, block); + return get_combined_adhoc_loc (set, loc, src_range, block, discriminator); } extern void rebuild_location_adhoc_htab (class line_maps *); diff --git a/libcpp/lex.cc b/libcpp/lex.cc index 41f905de..a429a3d 100644 --- a/libcpp/lex.cc +++ b/libcpp/lex.cc @@ -1362,7 +1362,8 @@ get_location_for_byte_range_in_cur_line (cpp_reader *pfile, location_t combined_loc = COMBINE_LOCATION_DATA (pfile->line_table, start_loc, src_range, - NULL); + NULL, + 0); return combined_loc; } @@ -2028,7 +2029,7 @@ warn_about_normalization (cpp_reader *pfile, CPP_BUF_COLUMN (pfile->buffer, pfile->buffer->cur)); loc = COMBINE_LOCATION_DATA (pfile->line_table, - loc, tok_range, NULL); + loc, tok_range, NULL, 0); } encoding_rich_location rich_loc (pfile, loc); @@ -4256,7 +4257,7 @@ _cpp_lex_direct (cpp_reader *pfile) result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table, result->src_loc, - tok_range, NULL); + tok_range, NULL, 0); } return result; diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc index 391f1d4..50e8043 100644 --- a/libcpp/line-map.cc +++ b/libcpp/line-map.cc @@ -67,7 +67,8 @@ location_adhoc_data_hash (const void *l) return ((hashval_t) lb->locus + (hashval_t) lb->src_range.m_start + (hashval_t) lb->src_range.m_finish - + (size_t) lb->data); + + (size_t) lb->data + + lb->discriminator); } /* Compare function for location_adhoc_data hashtable. */ @@ -82,7 +83,8 @@ location_adhoc_data_eq (const void *l1, const void *l2) return (lb1->locus == lb2->locus && lb1->src_range.m_start == lb2->src_range.m_start && lb1->src_range.m_finish == lb2->src_range.m_finish - && lb1->data == lb2->data); + && lb1->data == lb2->data + && lb1->discriminator == lb2->discriminator); } /* Update the hashtable when location_adhoc_data_map::data is reallocated. @@ -127,13 +129,17 @@ static bool can_be_stored_compactly_p (line_maps *set, location_t locus, source_range src_range, - void *data) + void *data, + unsigned discriminator) { /* If there's an ad-hoc pointer, we can't store it directly in the location_t, we need the lookaside. */ if (data) return false; + if (discriminator != 0) + return false; + /* We only store ranges that begin at the locus and that are sufficiently "sane". */ if (src_range.m_start != locus) @@ -168,7 +174,8 @@ location_t get_combined_adhoc_loc (line_maps *set, location_t locus, source_range src_range, - void *data) + void *data, + unsigned discriminator) { struct location_adhoc_data lb; struct location_adhoc_data **slot; @@ -186,7 +193,7 @@ get_combined_adhoc_loc (line_maps *set, || pure_location_p (set, locus)); /* Consider short-range optimization. */ - if (can_be_stored_compactly_p (set, locus, src_range, data)) + if (can_be_stored_compactly_p (set, locus, src_range, data, discriminator)) { /* The low bits ought to be clear. */ linemap_assert (pure_location_p (set, locus)); @@ -206,15 +213,16 @@ get_combined_adhoc_loc (line_maps *set, when locus == start == finish (and data is NULL). */ if (locus == src_range.m_start && locus == src_range.m_finish - && !data) + && !data && discriminator == 0) return locus; - if (!data) + if (!data && discriminator == 0) set->num_unoptimized_ranges++; lb.locus = locus; lb.src_range = src_range; lb.data = data; + lb.discriminator = discriminator; slot = (struct location_adhoc_data **) htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT); if (*slot == NULL) @@ -261,6 +269,13 @@ get_data_from_adhoc_loc (const class line_maps *set, location_t loc) return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data; } +unsigned +get_discriminator_from_adhoc_loc (const class line_maps *set, location_t loc) +{ + linemap_assert (IS_ADHOC_LOC (loc)); + return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].discriminator; +} + /* Return the location for the adhoc loc. */ location_t @@ -306,6 +321,15 @@ get_range_from_loc (line_maps *set, return source_range::from_location (loc); } +unsigned +get_discriminator_from_loc (line_maps *set, + location_t loc) +{ + if (IS_ADHOC_LOC (loc)) + return get_discriminator_from_adhoc_loc (set, loc); + return 0; +} + /* Get whether location LOC is a "pure" location, or whether it is an ad-hoc location, or embeds range information. */ |