This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[commited] output gcov files for -ftree-based-profiling too
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 11 Sep 2004 02:46:30 +0200
- Subject: [commited] output gcov files for -ftree-based-profiling too
Hi,
this patch merge some of boring bits from tree profiling branch to get
coverage sorta working on -ftree-profiling-branch. It still can get
messed up with cfgcleanup executed earlier. I will post separate patch
for this later.
The code is still disabled by default now.
Bootstrapped/regtested i686-pc-gnu-linux and commited.
Honza
2004-09-11 Jan Hubicka <jh@suse.cz>
* 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.
Index: profile.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.c,v
retrieving revision 1.136
retrieving revision 1.93.2.25.2.7
diff -c -3 -p -r1.136 -r1.93.2.25.2.7
*** profile.c 4 Aug 2004 21:37:05 -0000 1.136
--- profile.c 6 Aug 2004 06:54:26 -0000 1.93.2.25.2.7
*************** compute_value_histograms (unsigned n_val
*** 676,681 ****
--- 677,729 ----
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.
*************** branch_prob (void)
*** 843,849 ****
*/
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 ())
--- 887,892 ----
*************** branch_prob (void)
*** 870,875 ****
--- 913,924 ----
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);
*************** branch_prob (void)
*** 881,958 ****
}
/* 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 ())
{
! char const *prev_file_name = NULL;
! gcov_position_t offset;
! FOR_EACH_BB (bb)
{
! 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);
!
! 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
! {
! expanded_location s;
! if (!offset)
! {
! offset = gcov_write_tag (GCOV_TAG_LINES);
! gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
! }
! NOTE_EXPANDED_LOCATION (s, 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))
{
! prev_file_name = s.file;
! gcov_write_unsigned (0);
! gcov_write_string (prev_file_name);
}
- 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);
}
! }
}
ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
--- 930,1041 ----
}
/* Line numbers. */
! if (coverage_begin_output ())
{
! /* Initialize the output. */
! output_location (NULL, 0, NULL, NULL);
! if (!ir_type ())
{
! gcov_position_t offset;
! FOR_EACH_BB (bb)
{
! 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);
! 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
{
! expanded_location s;
! NOTE_EXPANDED_LOCATION (s, insn);
! output_location (s.file, NOTE_LINE_NUMBER (insn), &offset, bb);
}
}
+ 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);
}
}
+ }
+ else
+ {
+ gcov_position_t offset;
+ location_t *curr_location = NULL;
! FOR_EACH_BB (bb)
{
! 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;
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.923
diff -c -3 -p -r1.923 toplev.c
*** toplev.c 10 Sep 2004 19:03:07 -0000 1.923
--- toplev.c 11 Sep 2004 00:36:42 -0000
*************** process_options (void)
*** 1752,1759 ****
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.");
--- 1752,1757 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.923
diff -c -3 -p -r1.923 toplev.c
*** toplev.c 10 Sep 2004 19:03:07 -0000 1.923
--- toplev.c 11 Sep 2004 00:41:36 -0000
*************** process_options (void)
*** 1752,1759 ****
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.");
--- 1752,1757 ----