profile.c (BB_TO_GCOV_INDEX): move more to the front.
authorJan Hubicka <jh@suse.cz>
Sat, 11 Sep 2004 19:50:21 +0000 (21:50 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 11 Sep 2004 19:50:21 +0000 (19:50 +0000)
* 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

gcc/ChangeLog
gcc/profile.c
gcc/toplev.c

index c469e2712bdad8d1200ca3522a19585d5e592264..7429882c3c19134a6e4072d3c0e0fa68a796673d 100644 (file)
@@ -1,3 +1,11 @@
+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.
+
 2004-09-11  Steven Bosscher  <stevenb@suse.de>
 
        PR c++/17412
index 2200e76399ddf242e1cc2f8169c4adf86ac01449..7b0a667b1fe8dd3ebda0284167248612b9ab344f 100644 (file)
@@ -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;
index bf7ae20b0d93062f23745582b4b4a657bef3e516..f63e80ba48e885f3be495c7240b60366b494ff40 100644 (file)
@@ -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.");