diff options
author | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-30 19:23:34 +0000 |
---|---|---|
committer | rakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-30 19:23:34 +0000 |
commit | cf40db41ee40522222ef279f708710d580c944ad (patch) | |
tree | 3736c245736a667b97a048cf693be5fe11ae12ef /gcc | |
parent | 5aecb2e6ee34db3e30866d9407c1156be5ff04fd (diff) | |
download | gcc-cf40db41ee40522222ef279f708710d580c944ad.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@69969 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/combine.c | 4 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 4 | ||||
-rw-r--r-- | gcc/gcov-io.h | 11 | ||||
-rw-r--r-- | gcc/profile.c | 58 | ||||
-rw-r--r-- | gcc/rtl.c | 2 | ||||
-rw-r--r-- | gcc/rtl.h | 5 | ||||
-rw-r--r-- | gcc/value-prof.c | 11 | ||||
-rw-r--r-- | gcc/value-prof.h | 4 |
9 files changed, 108 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3f88a9b19a3..8fadb8d7767 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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__. diff --git a/gcc/combine.c b/gcc/combine.c index de7ace43a2b..e3c1cf6ec7a 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index f1cd6f0e7b3..ada9e3d7d06 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index fd5755fea78..59b202bc0a4 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -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"} diff --git a/gcc/profile.c b/gcc/profile.c index dd23628c708..37a5ecb5c11 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -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 diff --git a/gcc/rtl.c b/gcc/rtl.c index a92ca4b502e..54b7476c738 100644 --- 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", diff --git a/gcc/rtl.h b/gcc/rtl.h index 9d3b0dc1b9b..8fb2574ad51 100644 --- 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, diff --git a/gcc/value-prof.c b/gcc/value-prof.c index e843ddbe56b..171b30481e4 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -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 **); diff --git a/gcc/value-prof.h b/gcc/value-prof.h index 74b754a25d6..233895e4a31 100644 --- a/gcc/value-prof.h +++ b/gcc/value-prof.h @@ -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 { |