diff options
author | Cary Coutant <ccoutant@google.com> | 2009-06-04 23:12:27 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@gcc.gnu.org> | 2009-06-04 16:12:27 -0700 |
commit | 6c52e687e487eb5bfc57399754d72e05845159d8 (patch) | |
tree | 62b2a3883be83cd19685457df195f788da6d5d99 | |
parent | 535ff342b76110501c8673df1ae44db5e6ea55b4 (diff) | |
download | gcc-6c52e687e487eb5bfc57399754d72e05845159d8.zip gcc-6c52e687e487eb5bfc57399754d72e05845159d8.tar.gz gcc-6c52e687e487eb5bfc57399754d72e05845159d8.tar.bz2 |
basic-block.h (struct basic_block_def): Add discriminator field.
* basic-block.h (struct basic_block_def): Add discriminator field.
* dbxout.c (dbxout_source_line): Add new parameter. Change all
callers.
* debug.c (do_nothing_debug_hooks): Add additional entry.
(debug_nothing_int_charstar_int): New function.
* debug.h (struct gcc_debug_hooks): Add parameter to source_line
hook.
(debug_nothing_int_charstar_int): New declaration.
* dwarf2out.c (dwarf2out_source_line): Add new parameter. Write
discriminator value in .loc directive.
* final.c (last_discriminator): New variable.
(discriminator): New variable.
(final_start_function): Initialize above variables, pass current
discriminator to debug hook.
(notice_source_line): Check for discriminator change.
* gimple-pretty-print.c (dump_bb_header): Print discriminator value.
* sdbout.c (sdbout_source_line): New parameter.
* tree-cfg.c (struct locus_discrim_map): New structure type.
(discriminator_per_locus): New hash table.
(build_gimple_cfg): Allocate and free discriminator hash table.
(make_edges): Call assign_discriminator.
(locus_map_hash): New function.
(locus_map_eq): New function.
(next_discriminator_for_locus): New function.
(same_line_p): New function.
(assign_discriminator): New function.
(make_cond_expr_edges): Call assign_discriminator.
(make_gimple_switch_edges): Likewise.
(first_non_label_stmt): New function.
* vmsdbgout.c (vmsdbgout_source_line): Add new parameter. Change
all callers.
* xcoffout.c (xcoffout_source_line): Add new parameter.
* configure.ac (gcc_cv_as_discriminator): New configury check for
gas support for discriminator.
* configure: Regenerate.
* config.in: Regenerate.
From-SVN: r148191
-rw-r--r-- | gcc/ChangeLog | 40 | ||||
-rw-r--r-- | gcc/basic-block.h | 3 | ||||
-rw-r--r-- | gcc/config.in | 6 | ||||
-rwxr-xr-x | gcc/configure | 39 | ||||
-rw-r--r-- | gcc/configure.ac | 9 | ||||
-rw-r--r-- | gcc/dbxout.c | 7 | ||||
-rw-r--r-- | gcc/debug.c | 9 | ||||
-rw-r--r-- | gcc/debug.h | 6 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 14 | ||||
-rw-r--r-- | gcc/final.c | 17 | ||||
-rw-r--r-- | gcc/gimple-pretty-print.c | 6 | ||||
-rw-r--r-- | gcc/sdbout.c | 5 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 130 | ||||
-rw-r--r-- | gcc/vmsdbgout.c | 11 | ||||
-rw-r--r-- | gcc/xcoffout.c | 3 |
15 files changed, 283 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c3de31..2daa2ff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2009-06-04 Cary Coutant <ccoutant@google.com> + + * basic-block.h (struct basic_block_def): Add discriminator field. + * dbxout.c (dbxout_source_line): Add new parameter. Change all + callers. + * debug.c (do_nothing_debug_hooks): Add additional entry. + (debug_nothing_int_charstar_int): New function. + * debug.h (struct gcc_debug_hooks): Add parameter to source_line + hook. + (debug_nothing_int_charstar_int): New declaration. + * dwarf2out.c (dwarf2out_source_line): Add new parameter. Write + discriminator value in .loc directive. + * final.c (last_discriminator): New variable. + (discriminator): New variable. + (final_start_function): Initialize above variables, pass current + discriminator to debug hook. + (notice_source_line): Check for discriminator change. + * gimple-pretty-print.c (dump_bb_header): Print discriminator value. + * sdbout.c (sdbout_source_line): New parameter. + * tree-cfg.c (struct locus_discrim_map): New structure type. + (discriminator_per_locus): New hash table. + (build_gimple_cfg): Allocate and free discriminator hash table. + (make_edges): Call assign_discriminator. + (locus_map_hash): New function. + (locus_map_eq): New function. + (next_discriminator_for_locus): New function. + (same_line_p): New function. + (assign_discriminator): New function. + (make_cond_expr_edges): Call assign_discriminator. + (make_gimple_switch_edges): Likewise. + (first_non_label_stmt): New function. + * vmsdbgout.c (vmsdbgout_source_line): Add new parameter. Change + all callers. + * xcoffout.c (xcoffout_source_line): Add new parameter. + + * configure.ac (gcc_cv_as_discriminator): New configury check for + gas support for discriminator. + * configure: Regenerate. + * config.in: Regenerate. + 2009-06-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> * config/arm/arm.c (thumb2_legitimate_index_p): Initialize diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 41d9f95..901845a 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -249,6 +249,9 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d /* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */ int frequency; + /* The discriminator for this block. */ + int discriminator; + /* Various flags. See BB_* below. */ int flags; }; diff --git a/gcc/config.in b/gcc/config.in index f3c16fe..adccc18 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -869,6 +869,12 @@ #endif +/* Define if your assembler supports the .loc discriminator sub-directive. */ +#ifndef USED_FOR_TARGET +#undef HAVE_GAS_DISCRIMINATOR +#endif + + /* Define if your assembler and linker support .hidden. */ #undef HAVE_GAS_HIDDEN diff --git a/gcc/configure b/gcc/configure index fe13a1f..8713f15 100755 --- a/gcc/configure +++ b/gcc/configure @@ -21823,6 +21823,45 @@ cat >>confdefs.h <<_ACEOF _ACEOF +echo "$as_me:$LINENO: checking assembler for line table discriminator support" >&5 +echo $ECHO_N "checking assembler for line table discriminator support... $ECHO_C" >&6 +if test "${gcc_cv_as_discriminator+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gcc_cv_as_discriminator=no + if test $in_tree_gas = yes; then + if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 51` + then gcc_cv_as_discriminator=yes +fi + elif test x$gcc_cv_as != x; then + echo ' .text + .file 1 "conf.c" + .loc 1 1 0 discriminator 1' > conftest.s + if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } + then + gcc_cv_as_discriminator=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +echo "$as_me:$LINENO: result: $gcc_cv_as_discriminator" >&5 +echo "${ECHO_T}$gcc_cv_as_discriminator" >&6 +if test $gcc_cv_as_discriminator = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GAS_DISCRIMINATOR 1 +_ACEOF + +fi + # Thread-local storage - the check is heavily parameterized. conftest_s= tls_first_major= diff --git a/gcc/configure.ac b/gcc/configure.ac index 0b9851d..f637a11 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2408,6 +2408,15 @@ AC_DEFINE_UNQUOTED(HAVE_COMDAT_GROUP, [`if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`], [Define 0/1 if your assembler and linker support COMDAT groups.]) +gcc_GAS_CHECK_FEATURE([line table discriminator support], + gcc_cv_as_discriminator, + [2,19,51],, +[ .text + .file 1 "conf.c" + .loc 1 1 0 discriminator 1],, +[AC_DEFINE(HAVE_GAS_DISCRIMINATOR, 1, + [Define if your assembler supports the .loc discriminator sub-directive.])]) + # Thread-local storage - the check is heavily parameterized. conftest_s= tls_first_major= diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 9ec0525..17fdf6e 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -333,7 +333,7 @@ static void dbxout_handle_pch (unsigned); /* The debug hooks structure. */ #if defined (DBX_DEBUGGING_INFO) -static void dbxout_source_line (unsigned int, const char *); +static void dbxout_source_line (unsigned int, const char *, int); static void dbxout_begin_prologue (unsigned int, const char *); static void dbxout_source_file (const char *); static void dbxout_function_end (tree); @@ -1265,7 +1265,7 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename) /* pre-increment the scope counter */ scope_labelno++; - dbxout_source_line (lineno, filename); + dbxout_source_line (lineno, filename, 0); /* Output function begin block at function scope, referenced by dbxout_block, dbxout_source_line and dbxout_function_end. */ emit_pending_bincls_if_required (); @@ -1276,7 +1276,8 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename) number LINENO. */ static void -dbxout_source_line (unsigned int lineno, const char *filename) +dbxout_source_line (unsigned int lineno, const char *filename, + int discriminator ATTRIBUTE_UNUSED) { dbxout_source_file (filename); diff --git a/gcc/debug.c b/gcc/debug.c index 3946deb..c8e80a8 100644 --- a/gcc/debug.c +++ b/gcc/debug.c @@ -34,7 +34,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks = debug_nothing_int_int, /* begin_block */ debug_nothing_int_int, /* end_block */ debug_true_const_tree, /* ignore_block */ - debug_nothing_int_charstar, /* source_line */ + debug_nothing_int_charstar_int, /* source_line */ debug_nothing_int_charstar, /* begin_prologue */ debug_nothing_int_charstar, /* end_prologue */ debug_nothing_int_charstar, /* end_epilogue */ @@ -104,6 +104,13 @@ debug_nothing_int_charstar (unsigned int line ATTRIBUTE_UNUSED, } void +debug_nothing_int_charstar_int (unsigned int line ATTRIBUTE_UNUSED, + const char *text ATTRIBUTE_UNUSED, + int discriminator ATTRIBUTE_UNUSED) +{ +} + +void debug_nothing_int (unsigned int line ATTRIBUTE_UNUSED) { } diff --git a/gcc/debug.h b/gcc/debug.h index 6d49113..8f76aff 100644 --- a/gcc/debug.h +++ b/gcc/debug.h @@ -59,8 +59,9 @@ struct gcc_debug_hooks though the BLOCK information is messed up. Defaults to true. */ bool (* ignore_block) (const_tree); - /* Record a source file location at (FILE, LINE). */ - void (* source_line) (unsigned int line, const char *file); + /* Record a source file location at (FILE, LINE, DISCRIMINATOR). */ + void (* source_line) (unsigned int line, const char *file, + int discriminator); /* Called at start of prologue code. LINE is the first line in the function. This has been given the same prototype as source_line, @@ -141,6 +142,7 @@ extern const struct gcc_debug_hooks *debug_hooks; extern void debug_nothing_void (void); extern void debug_nothing_charstar (const char *); extern void debug_nothing_int_charstar (unsigned int, const char *); +extern void debug_nothing_int_charstar_int (unsigned int, const char *, int); extern void debug_nothing_int (unsigned int); extern void debug_nothing_int_int (unsigned int, unsigned int); extern void debug_nothing_tree (tree); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 63ec0a6..21f2aed 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -91,7 +91,7 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #ifdef DWARF2_DEBUGGING_INFO -static void dwarf2out_source_line (unsigned int, const char *); +static void dwarf2out_source_line (unsigned int, const char *, int); #endif #ifndef DWARF2_FRAME_INFO @@ -3608,7 +3608,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, prologue case, not the eh frame case. */ #ifdef DWARF2_DEBUGGING_INFO if (file) - dwarf2out_source_line (line, file); + dwarf2out_source_line (line, file, 0); #endif if (dwarf2out_do_cfi_asm ()) @@ -16207,7 +16207,8 @@ dwarf2out_begin_function (tree fun) 'line_info_table' for later output of the .debug_line section. */ static void -dwarf2out_source_line (unsigned int line, const char *filename) +dwarf2out_source_line (unsigned int line, const char *filename, + int discriminator) { if (debug_info_level >= DINFO_LEVEL_NORMAL && line != 0) @@ -16224,7 +16225,12 @@ dwarf2out_source_line (unsigned int line, const char *filename) if (DWARF2_ASM_LINE_DEBUG_INFO) { /* Emit the .loc directive understood by GNU as. */ - fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line); + fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line); +#ifdef HAVE_GAS_DISCRIMINATOR + if (discriminator != 0) + fprintf (asm_out_file, " discriminator %d", discriminator); +#endif /* HAVE_GAS_DISCRIMINATOR */ + fputc ('\n', asm_out_file); /* Indicate that line number info exists. */ line_info_table_in_use++; diff --git a/gcc/final.c b/gcc/final.c index 785b0906..1fae1b4 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -130,6 +130,12 @@ rtx current_output_insn; /* Line number of last NOTE. */ static int last_linenum; +/* Last discriminator written to assembly. */ +static int last_discriminator; + +/* Discriminator of current block. */ +static int discriminator; + /* Highest line number in current block. */ static int high_block_linenum; @@ -1496,6 +1502,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, last_filename = locator_file (prologue_locator); last_linenum = locator_line (prologue_locator); + last_discriminator = discriminator = 0; high_block_linenum = high_function_linenum = last_linenum; @@ -1852,6 +1859,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, else *seen |= SEEN_BB; + discriminator = NOTE_BASIC_BLOCK (insn)->discriminator; + break; case NOTE_INSN_EH_REGION_BEG: @@ -2183,7 +2192,9 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, note in a row. */ if (notice_source_line (insn)) { - (*debug_hooks->source_line) (last_linenum, last_filename); + (*debug_hooks->source_line) (last_linenum, + last_filename, + last_discriminator); } if (GET_CODE (body) == ASM_INPUT) @@ -2709,11 +2720,13 @@ notice_source_line (rtx insn) if (filename && (force_source_line || filename != last_filename - || last_linenum != linenum)) + || last_linenum != linenum + || last_discriminator != discriminator)) { force_source_line = false; last_filename = filename; last_linenum = linenum; + last_discriminator = discriminator; high_block_linenum = MAX (last_linenum, high_block_linenum); high_function_linenum = MAX (last_linenum, high_function_linenum); return true; diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 6a5190e..6490a65 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1558,6 +1558,12 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags) pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi))); break; } + + if (bb->discriminator) + { + pp_string (buffer, ", discriminator "); + pp_decimal_int (buffer, bb->discriminator); + } } newline_and_indent (buffer, indent); diff --git a/gcc/sdbout.c b/gcc/sdbout.c index 818ff63..cc86874 100644 --- a/gcc/sdbout.c +++ b/gcc/sdbout.c @@ -117,7 +117,7 @@ static void sdbout_start_source_file (unsigned int, const char *); static void sdbout_end_source_file (unsigned int); static void sdbout_begin_block (unsigned int, unsigned int); static void sdbout_end_block (unsigned int, unsigned int); -static void sdbout_source_line (unsigned int, const char *); +static void sdbout_source_line (unsigned int, const char *, int); static void sdbout_end_epilogue (unsigned int, const char *); static void sdbout_global_decl (tree); #ifndef MIPS_DEBUGGING_INFO @@ -1541,7 +1541,8 @@ sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED) number LINE. */ static void -sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED) +sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED, + int discriminator ATTRIBUTE_UNUSED) { /* COFF relative line numbers must be positive. */ if ((int) line > sdb_begin_function_line) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 875dd8e..26a082d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -82,6 +82,14 @@ static struct cfg_stats_d cfg_stats; /* Nonzero if we found a computed goto while building basic blocks. */ static bool found_computed_goto; +/* Hash table to store last discriminator assigned for each locus. */ +struct locus_discrim_map +{ + location_t locus; + int discriminator; +}; +static htab_t discriminator_per_locus; + /* Basic blocks and flowgraphs. */ static void make_blocks (gimple_seq); static void factor_computed_gotos (void); @@ -91,6 +99,9 @@ static void make_edges (void); static void make_cond_expr_edges (basic_block); static void make_gimple_switch_edges (basic_block); static void make_goto_expr_edges (basic_block); +static unsigned int locus_map_hash (const void *); +static int locus_map_eq (const void *, const void *); +static void assign_discriminator (location_t, basic_block); static edge gimple_redirect_edge_and_branch (edge, basic_block); static edge gimple_try_redirect_by_replacing_jump (edge, basic_block); static unsigned int split_critical_edges (void); @@ -100,6 +111,7 @@ static inline bool stmt_starts_bb_p (gimple, gimple); static int gimple_verify_flow_info (void); static void gimple_make_forwarder_block (edge); static void gimple_cfg2vcg (FILE *); +static gimple first_non_label_stmt (basic_block); /* Flowgraph optimization and cleanup. */ static void gimple_merge_blocks (basic_block, basic_block); @@ -193,8 +205,11 @@ build_gimple_cfg (gimple_seq seq) group_case_labels (); /* Create the edges of the flowgraph. */ + discriminator_per_locus = htab_create (13, locus_map_hash, locus_map_eq, + free); make_edges (); cleanup_dead_labels (); + htab_delete (discriminator_per_locus); /* Debugging dumps. */ @@ -650,7 +665,11 @@ make_edges (void) fallthru = true; if (fallthru) - make_edge (bb, bb->next_bb, EDGE_FALLTHRU); + { + make_edge (bb, bb->next_bb, EDGE_FALLTHRU); + if (last) + assign_discriminator (gimple_location (last), bb->next_bb); + } } if (root_omp_region) @@ -660,6 +679,91 @@ make_edges (void) fold_cond_expr_cond (); } +/* Trivial hash function for a location_t. ITEM is a pointer to + a hash table entry that maps a location_t to a discriminator. */ + +static unsigned int +locus_map_hash (const void *item) +{ + return ((const struct locus_discrim_map *) item)->locus; +} + +/* Equality function for the locus-to-discriminator map. VA and VB + point to the two hash table entries to compare. */ + +static int +locus_map_eq (const void *va, const void *vb) +{ + const struct locus_discrim_map *a = (const struct locus_discrim_map *) va; + const struct locus_discrim_map *b = (const struct locus_discrim_map *) vb; + return a->locus == b->locus; +} + +/* Find the next available discriminator value for LOCUS. The + discriminator distinguishes among several basic blocks that + share a common locus, allowing for more accurate sample-based + profiling. */ + +static int +next_discriminator_for_locus (location_t locus) +{ + struct locus_discrim_map item; + struct locus_discrim_map **slot; + + item.locus = locus; + item.discriminator = 0; + slot = (struct locus_discrim_map **) + htab_find_slot_with_hash (discriminator_per_locus, (void *) &item, + (hashval_t) locus, INSERT); + gcc_assert (slot); + if (*slot == HTAB_EMPTY_ENTRY) + { + *slot = XNEW (struct locus_discrim_map); + gcc_assert (*slot); + (*slot)->locus = locus; + (*slot)->discriminator = 0; + } + (*slot)->discriminator++; + return (*slot)->discriminator; +} + +/* Return TRUE if LOCUS1 and LOCUS2 refer to the same source line. */ + +static bool +same_line_p (location_t locus1, location_t locus2) +{ + expanded_location from, to; + + if (locus1 == locus2) + return true; + + from = expand_location (locus1); + to = expand_location (locus2); + + if (from.line != to.line) + return false; + if (from.file == to.file) + return true; + return (from.file != NULL + && to.file != NULL + && strcmp (from.file, to.file) == 0); +} + +/* Assign a unique discriminator value to block BB if it begins at the same + LOCUS as its predecessor block. */ + +static void +assign_discriminator (location_t locus, basic_block bb) +{ + gimple to_stmt; + + if (locus == 0 || bb->discriminator != 0) + return; + + to_stmt = first_non_label_stmt (bb); + if (to_stmt && same_line_p (locus, gimple_location (to_stmt))) + bb->discriminator = next_discriminator_for_locus (locus); +} /* Create the edges for a GIMPLE_COND starting at block BB. */ @@ -671,10 +775,13 @@ make_cond_expr_edges (basic_block bb) basic_block then_bb, else_bb; tree then_label, else_label; edge e; + location_t entry_locus; gcc_assert (entry); gcc_assert (gimple_code (entry) == GIMPLE_COND); + entry_locus = gimple_location (entry); + /* Entry basic blocks for each component. */ then_label = gimple_cond_true_label (entry); else_label = gimple_cond_false_label (entry); @@ -684,12 +791,14 @@ make_cond_expr_edges (basic_block bb) else_stmt = first_stmt (else_bb); e = make_edge (bb, then_bb, EDGE_TRUE_VALUE); + assign_discriminator (entry_locus, then_bb); e->goto_locus = gimple_location (then_stmt); if (e->goto_locus) e->goto_block = gimple_block (then_stmt); e = make_edge (bb, else_bb, EDGE_FALSE_VALUE); if (e) { + assign_discriminator (entry_locus, else_bb); e->goto_locus = gimple_location (else_stmt); if (e->goto_locus) e->goto_block = gimple_block (else_stmt); @@ -799,8 +908,11 @@ static void make_gimple_switch_edges (basic_block bb) { gimple entry = last_stmt (bb); + location_t entry_locus; size_t i, n; + entry_locus = gimple_location (entry); + n = gimple_switch_num_labels (entry); for (i = 0; i < n; ++i) @@ -808,6 +920,7 @@ make_gimple_switch_edges (basic_block bb) tree lab = CASE_LABEL (gimple_switch_label (entry, i)); basic_block label_bb = label_to_block (lab); make_edge (bb, label_bb, 0); + assign_discriminator (entry_locus, label_bb); } } @@ -880,8 +993,10 @@ make_goto_expr_edges (basic_block bb) if (simple_goto_p (goto_t)) { tree dest = gimple_goto_dest (goto_t); - edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU); + basic_block label_bb = label_to_block (dest); + edge e = make_edge (bb, label_bb, EDGE_FALLTHRU); e->goto_locus = gimple_location (goto_t); + assign_discriminator (e->goto_locus, label_bb); if (e->goto_locus) e->goto_block = gimple_block (goto_t); gsi_remove (&last, true); @@ -2690,6 +2805,17 @@ first_stmt (basic_block bb) return !gsi_end_p (i) ? gsi_stmt (i) : NULL; } +/* Return the first non-label statement in basic block BB. */ + +static gimple +first_non_label_stmt (basic_block bb) +{ + gimple_stmt_iterator i = gsi_start_bb (bb); + while (!gsi_end_p (i) && gimple_code (gsi_stmt (i)) == GIMPLE_LABEL) + gsi_next (&i); + return !gsi_end_p (i) ? gsi_stmt (i) : NULL; +} + /* Return the last statement in basic block BB. */ gimple diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c index 134c7d9..41a3420 100644 --- a/gcc/vmsdbgout.c +++ b/gcc/vmsdbgout.c @@ -173,7 +173,7 @@ static void vmsdbgout_end_source_file (unsigned int); static void vmsdbgout_begin_block (unsigned int, unsigned int); static void vmsdbgout_end_block (unsigned int, unsigned int); static bool vmsdbgout_ignore_block (const_tree); -static void vmsdbgout_source_line (unsigned int, const char *); +static void vmsdbgout_source_line (unsigned int, const char *, int); static void vmsdbgout_begin_prologue (unsigned int, const char *); static void vmsdbgout_end_prologue (unsigned int, const char *); static void vmsdbgout_end_function (unsigned int); @@ -1297,7 +1297,7 @@ vmsdbgout_end_prologue (unsigned int line, const char *file) ASM_OUTPUT_LABEL (asm_out_file, label); /* VMS PCA expects every PC range to correlate to some line and file. */ - vmsdbgout_source_line (line, file); + vmsdbgout_source_line (line, file, 0); } } @@ -1331,7 +1331,7 @@ vmsdbgout_end_epilogue (unsigned int line, const char *file) ASM_OUTPUT_LABEL (asm_out_file, label); /* VMS PCA expects every PC range to correlate to some line and file. */ - vmsdbgout_source_line (line, file); + vmsdbgout_source_line (line, file, 0); } } @@ -1533,10 +1533,11 @@ lookup_filename (const char *file_name) 'line_info_table' for later output of the .debug_line section. */ static void -vmsdbgout_source_line (register unsigned line, register const char *filename) +vmsdbgout_source_line (register unsigned line, register const char *filename, + int discriminator) { if (write_symbols == VMS_AND_DWARF2_DEBUG) - (*dwarf2_debug_hooks.source_line) (line, filename); + (*dwarf2_debug_hooks.source_line) (line, filename, discriminator); if (debug_info_level >= DINFO_LEVEL_TERSE) { diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c index 8859b40..3c85354 100644 --- a/gcc/xcoffout.c +++ b/gcc/xcoffout.c @@ -321,7 +321,8 @@ xcoffout_source_file (FILE *file, const char *filename, int inline_p) /* Output a line number symbol entry for location (FILENAME, LINE). */ void -xcoffout_source_line (unsigned int line, const char *filename) +xcoffout_source_line (unsigned int line, const char *filename, + int discriminator ATTRIBUTE_UNUSED) { bool inline_p = (strcmp (xcoff_current_function_file, filename) != 0 || (int) line < xcoff_begin_function_line); |