From: Jan Hubicka Date: Sat, 11 Sep 2004 19:50:21 +0000 (+0200) Subject: profile.c (BB_TO_GCOV_INDEX): move more to the front. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f43329a5ae7245add8191783724d9bb99006f3b3;p=gcc.git profile.c (BB_TO_GCOV_INDEX): move more to the front. * profile.c (BB_TO_GCOV_INDEX): move more to the front. (output_location): Break out from .... (branch_prob): ... here; handle gcov output on trees. * toplev.c (process_options): No longer be sorry about coverage for trees. From-SVN: r87364 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c469e2712bd..7429882c3c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2004-09-11 Jan Hubicka + + * profile.c (BB_TO_GCOV_INDEX): move more to the front. + (output_location): Break out from .... + (branch_prob): ... here; handle gcov output on trees. + * toplev.c (process_options): No longer be sorry about coverage for + trees. + 2004-09-11 Steven Bosscher PR c++/17412 diff --git a/gcc/profile.c b/gcc/profile.c index 2200e76399d..7b0a667b1fe 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -684,6 +684,53 @@ compute_value_histograms (histogram_values values) free (histogram_counts[t]); } +#define BB_TO_GCOV_INDEX(bb) ((bb)->index + 1) +/* When passed NULL as file_name, initialize. + When passed something else, output the neccesary commands to change + line to LINE and offset to FILE_NAME. */ +static void +output_location (char const *file_name, int line, + gcov_position_t *offset, basic_block bb) +{ + static char const *prev_file_name; + static int prev_line; + bool name_differs, line_differs; + + if (!file_name) + { + prev_file_name = NULL; + prev_line = -1; + return; + } + + name_differs = !prev_file_name || strcmp (file_name, prev_file_name); + line_differs = prev_line != line; + + if (name_differs || line_differs) + { + if (!*offset) + { + *offset = gcov_write_tag (GCOV_TAG_LINES); + gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)); + name_differs = line_differs=true; + } + + /* If this is a new source file, then output the + file's name to the .bb file. */ + if (name_differs) + { + prev_file_name = file_name; + gcov_write_unsigned (0); + gcov_write_string (prev_file_name); + } + if (line_differs) + { + gcov_write_unsigned (line); + prev_line = line; + } + } +} + /* Instrument and/or analyze program behavior based on program flow graph. In either case, this function builds a flow graph for the function being compiled. The flow graph is stored in BB_GRAPH. @@ -850,7 +897,6 @@ branch_prob (void) */ ENTRY_BLOCK_PTR->index = -1; EXIT_BLOCK_PTR->index = last_basic_block; -#define BB_TO_GCOV_INDEX(bb) ((bb)->index + 1) /* Arcs */ if (coverage_begin_output ()) @@ -877,6 +923,12 @@ branch_prob (void) flag_bits |= GCOV_ARC_FAKE; if (e->flags & EDGE_FALLTHRU) flag_bits |= GCOV_ARC_FALLTHROUGH; + /* On trees we don't have fallthru flags, but we can + recompute them from CFG shape. */ + if (ir_type () + && e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE) + && e->src->next_bb == e->dest) + flag_bits |= GCOV_ARC_FALLTHROUGH; gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest)); gcov_write_unsigned (flag_bits); @@ -888,78 +940,112 @@ branch_prob (void) } /* Line numbers. */ - /* FIXME: make this work for trees. (Line numbers are in location_t - objects, but aren't always attached to the obvious tree...) */ - if (coverage_begin_output () && !ir_type ()) + if (coverage_begin_output ()) { - char const *prev_file_name = NULL; - gcov_position_t offset; + /* Initialize the output. */ + output_location (NULL, 0, NULL, NULL); - FOR_EACH_BB (bb) + if (!ir_type ()) { - rtx insn = BB_HEAD (bb); - int ignore_next_note = 0; - - offset = 0; - - /* We are looking for line number notes. Search backward - before basic block to find correct ones. */ - insn = prev_nonnote_insn (insn); - if (!insn) - insn = get_insns (); - else - insn = NEXT_INSN (insn); + gcov_position_t offset; - while (insn != BB_END (bb)) + FOR_EACH_BB (bb) { - if (NOTE_P (insn)) - { - /* Must ignore the line number notes that - immediately follow the end of an inline function - to avoid counting it twice. There is a note - before the call, and one after the call. */ - if (NOTE_LINE_NUMBER (insn) - == NOTE_INSN_REPEATED_LINE_NUMBER) - ignore_next_note = 1; - else if (NOTE_LINE_NUMBER (insn) <= 0) - /*NOP*/; - else if (ignore_next_note) - ignore_next_note = 0; - else - { - expanded_location s; + rtx insn = BB_HEAD (bb); + int ignore_next_note = 0; - if (!offset) - { - offset = gcov_write_tag (GCOV_TAG_LINES); - gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)); - } + offset = 0; - NOTE_EXPANDED_LOCATION (s, insn); + /* We are looking for line number notes. Search backward + before basic block to find correct ones. */ + insn = prev_nonnote_insn (insn); + if (!insn) + insn = get_insns (); + else + insn = NEXT_INSN (insn); - /* If this is a new source file, then output the - file's name to the .bb file. */ - if (!prev_file_name - || strcmp (s.file, prev_file_name)) + while (insn != BB_END (bb)) + { + if (NOTE_P (insn)) + { + /* Must ignore the line number notes that + immediately follow the end of an inline function + to avoid counting it twice. There is a note + before the call, and one after the call. */ + if (NOTE_LINE_NUMBER (insn) + == NOTE_INSN_REPEATED_LINE_NUMBER) + ignore_next_note = 1; + else if (NOTE_LINE_NUMBER (insn) <= 0) + /*NOP*/; + else if (ignore_next_note) + ignore_next_note = 0; + else { - prev_file_name = s.file; - gcov_write_unsigned (0); - gcov_write_string (prev_file_name); + expanded_location s; + NOTE_EXPANDED_LOCATION (s, insn); + output_location (s.file, NOTE_LINE_NUMBER (insn), &offset, bb); } - gcov_write_unsigned (s.line); } + insn = NEXT_INSN (insn); + } + + if (offset) + { + /* A file of NULL indicates the end of run. */ + gcov_write_unsigned (0); + gcov_write_string (NULL); + gcov_write_length (offset); } - insn = NEXT_INSN (insn); } + } + else + { + gcov_position_t offset; + location_t *curr_location = NULL; - if (offset) + FOR_EACH_BB (bb) { - /* A file of NULL indicates the end of run. */ - gcov_write_unsigned (0); - gcov_write_string (NULL); - gcov_write_length (offset); + block_stmt_iterator bsi; + + offset = 0; + + if (bb == ENTRY_BLOCK_PTR->next_bb) + { + curr_location = &DECL_SOURCE_LOCATION (current_function_decl); + output_location (curr_location->file, curr_location->line, + &offset, bb); + } + + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + tree stmt = bsi_stmt (bsi); +#ifdef USE_MAPPED_LOCATION + curr_location = EXPR_LOCATION (stmt); +#else + curr_location = EXPR_LOCUS (stmt); +#endif + if (curr_location) + output_location (curr_location->file, curr_location->line, + &offset, bb); + } + + /* Notice GOTO expressions we elliminated while constructing the + CFG. */ + if (bb->succ && !bb->succ->succ_next && bb->succ->goto_locus) + { + curr_location = bb->succ->goto_locus; + output_location (curr_location->file, curr_location->line, &offset, bb); + } + + if (offset) + { + /* A file of NULL indicates the end of run. */ + gcov_write_unsigned (0); + gcov_write_string (NULL); + gcov_write_length (offset); + } } - } + } } ENTRY_BLOCK_PTR->index = ENTRY_BLOCK; diff --git a/gcc/toplev.c b/gcc/toplev.c index bf7ae20b0d9..f63e80ba48e 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1752,8 +1752,6 @@ process_options (void) warning ("this target machine does not have delayed branches"); #endif - if (flag_tree_based_profiling && flag_test_coverage) - sorry ("test-coverage not yet implemented in trees."); if (flag_tree_based_profiling && flag_profile_values) sorry ("value-based profiling not yet implemented in trees.");