diff options
Diffstat (limited to 'gcc')
-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 |
18 files changed, 145 insertions, 42 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; } |