]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
combine.c (distribute_notes): Cancel REG_VALUE_PROFILE notes.
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Wed, 30 Jul 2003 19:23:34 +0000 (21:23 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Wed, 30 Jul 2003 19:23:34 +0000 (19:23 +0000)
* combine.c (distribute_notes): Cancel REG_VALUE_PROFILE notes.
* gcov-io.h (GCOV_FIRST_VALUE_COUNTER, GCOV_LAST_VALUE_COUNTER,
GCOV_N_VALUE_COUNTERS): New.
* profile.c (compute_value_histograms): New static function.
(branch_prob): Read back the value histograms.
* rtl.c (reg_note_name): Add name for REG_VALUE_PROFILE note.
* rtl.h (enum reg_note): Add REG_VALUE_PROFILE note.
* value-prof.c: Add comment on reading the profile.
* value-prof.h (COUNTER_FOR_HIST_TYPE, HIST_TYPE_FOR_COUNTER): New.
* doc/invoke.texi (-fprofile-values): Document behavior with
-fbranch-probabilities.

From-SVN: r69969

gcc/ChangeLog
gcc/combine.c
gcc/doc/invoke.texi
gcc/gcov-io.h
gcc/profile.c
gcc/rtl.c
gcc/rtl.h
gcc/value-prof.c
gcc/value-prof.h

index 3f88a9b19a3c531d3efe6711608d6858139c3052..8fadb8d77676ed7655eee9ccc260b530280d6af2 100644 (file)
@@ -1,3 +1,17 @@
+2003-07-30  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+
+       * combine.c (distribute_notes): Cancel REG_VALUE_PROFILE notes.
+       * gcov-io.h (GCOV_FIRST_VALUE_COUNTER, GCOV_LAST_VALUE_COUNTER,
+       GCOV_N_VALUE_COUNTERS): New.
+       * profile.c (compute_value_histograms): New static function.
+       (branch_prob): Read back the value histograms.
+       * rtl.c (reg_note_name): Add name for REG_VALUE_PROFILE note.
+       * rtl.h (enum reg_note): Add REG_VALUE_PROFILE note.
+       * value-prof.c: Add comment on reading the profile.
+       * value-prof.h (COUNTER_FOR_HIST_TYPE, HIST_TYPE_FOR_COUNTER): New.
+       * doc/invoke.texi (-fprofile-values): Document behavior with
+       -fbranch-probabilities.
+
 2003-07-30  David Edelsohn  <edelsohn@gnu.org>
 
        * longlong.h (PowerPC umul_ppmm): Do not test __vxworks__.
index de7ace43a2b1ec87f4570463b9ff112a1b3a9ab0..e3c1cf6ec7ae6d282d732d658d6bf8ad1b4321f6 100644 (file)
@@ -12456,6 +12456,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
          place = i3;
          break;
 
+       case REG_VALUE_PROFILE:
+         /* Just get rid of this note, as it is unused later anyway.  */
+         break;
+
        case REG_VTABLE_REF:
          /* ??? Should remain with *a particular* memory load.  Given the
             nature of vtable data, the last insn seems relatively safe.  */
index f1cd6f0e7b353169f0313b23f5f008c23da6af87..ada9e3d7d06100ea948c73e8bfcaa2e16c19f404 100644 (file)
@@ -4355,6 +4355,10 @@ exactly determine which path is taken more often.
 If combined with @option{-fprofile-arcs}, it adds code so that some
 data about values of expressions in the program is gathered.
 
+With @option{-fbranch-probabilities}, it reads back the data gathered
+from profiling values of expressions and adds @samp{REG_VALUE_PROFILE}
+notes to instructions for their later usage in optimizations.
+
 @item -fnew-ra
 @opindex fnew-ra
 Use a graph coloring register allocator.  Currently this option is meant
index fd5755fea78e28769cab8bfd926498867f10972a..59b202bc0a4e4a7fe10b86ceebbea1f9131c8018 100644 (file)
@@ -286,13 +286,24 @@ typedef HOST_WIDEST_INT gcov_type;
 #define GCOV_COUNTER_ARCS      0  /* Arc transitions.  */
 #define GCOV_COUNTERS_SUMMABLE 1  /* Counters which can be
                                      summaried.  */
+#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
+                                     profiling.  They must form a consecutive
+                                     interval and their order must match
+                                     the order of HIST_TYPEs in
+                                     value-prof.h.  */
 #define GCOV_COUNTER_V_INTERVAL        1  /* Histogram of value inside an interval.  */
 #define GCOV_COUNTER_V_POW2    2  /* Histogram of exact power2 logarithm
                                      of a value.  */
 #define GCOV_COUNTER_V_SINGLE  3  /* The most common value of expression.  */
 #define GCOV_COUNTER_V_DELTA   4  /* The most common difference between
                                      consecutive values of expression.  */
+#define GCOV_LAST_VALUE_COUNTER 4  /* The last of counters used for value
+                                     profiling.  */
 #define GCOV_COUNTERS          5
+
+/* Number of counters used for value profiling.  */
+#define GCOV_N_VALUE_COUNTERS \
+  (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
   
   /* A list of human readable names of the counters */
 #define GCOV_COUNTER_NAMES     {"arcs", "interval", "pow2", "single", "delta"}
index dd23628c70875de93d5f3ca73f851d37fe92d3dc..37a5ecb5c11275a6ddfe685b3365a2eea51b63bf 100644 (file)
@@ -117,6 +117,7 @@ static rtx gen_const_delta_profiler (struct histogram_value *, unsigned,
 static unsigned instrument_edges (struct edge_list *);
 static void instrument_values (unsigned, struct histogram_value *);
 static void compute_branch_probabilities (void);
+static void compute_value_histograms (unsigned, struct histogram_value *);
 static gcov_type * get_exec_counts (void);
 static basic_block find_group (basic_block);
 static void union_groups (basic_block, basic_block);
@@ -601,6 +602,57 @@ compute_branch_probabilities (void)
   free_aux_for_blocks ();
 }
 
+/* Load value histograms for N_VALUES values whose description is stored
+   in VALUES array from .da file.  */
+static void
+compute_value_histograms (unsigned n_values, struct histogram_value *values)
+{
+  unsigned i, j, t, any;
+  unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
+  gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
+  gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
+  gcov_type *aact_count;
+  for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+    n_histogram_counters[t] = 0;
+
+  for (i = 0; i < n_values; i++)
+    n_histogram_counters[(int) (values[i].type)] += values[i].n_counters;
+
+  any = 0;
+  for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+    {
+      histogram_counts[t] =
+       get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
+                            n_histogram_counters[t], &profile_info);
+      if (histogram_counts[t])
+       any = 1;
+      act_count[t] = histogram_counts[t];
+    }
+  if (!any)
+    return;
+
+  for (i = 0; i < n_values; i++)
+    {
+      rtx hist_list = NULL_RTX;
+      t = (int) (values[i].type);
+
+      aact_count = act_count[t];
+      act_count[t] += values[i].n_counters;
+      for (j = values[i].n_counters; j > 0; j--)
+       hist_list = alloc_EXPR_LIST (0, GEN_INT (aact_count[j - 1]), hist_list);
+      hist_list = alloc_EXPR_LIST (0, copy_rtx (values[i].value), hist_list);
+      hist_list = alloc_EXPR_LIST (0, GEN_INT (values[i].type), hist_list);
+      REG_NOTES (values[i].insn) =
+             alloc_EXPR_LIST (REG_VALUE_PROFILE, hist_list,
+                              REG_NOTES (values[i].insn));
+    }
+
+  for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+    if (histogram_counts[t])
+      free (histogram_counts[t]);
+}
+
 /* 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.
@@ -886,7 +938,11 @@ branch_prob (void)
     }
 
   if (flag_branch_probabilities)
-    compute_branch_probabilities ();
+    {
+      compute_branch_probabilities ();
+      if (flag_profile_values)
+       compute_value_histograms (n_values, values);
+    }
 
   /* For each edge not on the spanning tree, add counting code as rtl.  */
   if (profile_arc_flag
index a92ca4b502e4f1f6adc0483c54698a6991a9a042..54b7476c738def61f83eff25be88122b996e94a7 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -228,7 +228,7 @@ const char * const reg_note_name[] =
   "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG",
   "REG_NO_CONFLICT", "REG_UNUSED", "REG_CC_SETTER", "REG_CC_USER",
   "REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
-  "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
+  "REG_VALUE_PROFILE", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
   "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
   "REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN",
   "REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN",
index 9d3b0dc1b9b14b14f0fb8e3c169ff487a4e5c157..8fb2574ad51697a18df734aea9f33ad3bc845327 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -684,6 +684,11 @@ enum reg_note
      return.  */
   REG_BR_PROB,
 
+  /* REG_VALUE_PROFILE is attached when the profile is read in to an insn
+     before that the code to profile the value is inserted.  It contains
+     the results of profiling.  */
+  REG_VALUE_PROFILE,
+
   /* Attached to a call insn; indicates that the call is malloc-like and
      that the pointer returned cannot alias anything else.  */
   REG_NOALIAS,
index e843ddbe56b6d9289a5042c9a89bd69dda668ee6..171b30481e42f82230bcabdcc031335b805cd570 100644 (file)
@@ -40,9 +40,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    insn_values_to_profile function.  This function is called from branch_prob
    in profile.c and the requested values are instrumented by it in the first
    compilation with -fprofile-arcs.  The optimization may then read the
-   gathered data in the second compilation with -fbranch-probabilities (the
-   description of an exact way how to do it will be added here once the
-   code responsible for reading of the data is merged).  */
+   gathered data in the second compilation with -fbranch-probablities.
+   The measured data is appended as REG_VALUE_PROFILE note to the instrumented
+   insn.  The argument to the note consists of an EXPR_LIST where its
+   members have the following meaning (from the first to the last):
+   
+   -- type of information gathered (HIST_TYPE*)
+   -- the expression that is profiled
+   -- list of counters starting from the first one.  */
 
 static void insn_values_to_profile (rtx, unsigned *, struct histogram_value **);
 \f
index 74b754a25d6641236b6c82e2a65327072617a9c2..233895e4a31996f2ec2335972193e007ae1b2052 100644 (file)
@@ -30,6 +30,10 @@ enum hist_type
                           difference between two evaluations of a value.  */
 };
 
+#define COUNTER_FOR_HIST_TYPE(TYPE) ((int) (TYPE) + GCOV_FIRST_VALUE_COUNTER)
+#define HIST_TYPE_FOR_COUNTER(COUNTER) \
+  ((enum hist_type) ((COUNTER) - GCOV_FIRST_VALUE_COUNTER))
+
 /* The value to measure.  */
 struct histogram_value
 {