public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/kubaneko/heads/histogram)] added modulo histogram and improved garbage collection
@ 2023-04-25 8:10 Ondrej Kubanek
0 siblings, 0 replies; only message in thread
From: Ondrej Kubanek @ 2023-04-25 8:10 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:3b7b26109c35d562ef60fc0cee279039fcbf4749
commit 3b7b26109c35d562ef60fc0cee279039fcbf4749
Author: kubaneko <kubanek0ondrej@gmail.com>
Date: Tue Apr 25 08:09:35 2023 +0000
added modulo histogram and improved garbage collection
Diff:
---
gcc/cfgloop.cc | 33 +++++++++++++++++++++++++++++++--
gcc/cfgloop.h | 1 +
gcc/cfgloopmanip.cc | 2 ++
gcc/lto-streamer-in.cc | 17 ++++++++++++++---
gcc/lto-streamer-out.cc | 13 +++++++++++--
gcc/profile.cc | 22 ++++++++++++++++------
gcc/tree-profile.cc | 3 ++-
gcc/value-prof.cc | 16 ++++++++++++++--
libgcc/libgcov-profiler.c | 25 ++++++++++++++++++-------
9 files changed, 109 insertions(+), 23 deletions(-)
diff --git a/gcc/cfgloop.cc b/gcc/cfgloop.cc
index e2c1bab996f..0f5121117ca 100644
--- a/gcc/cfgloop.cc
+++ b/gcc/cfgloop.cc
@@ -201,6 +201,9 @@ flow_loop_free (class loop *loop)
ggc_free (loop->exits);
if (loop->counters)
{
+ va_heap::release (loop->counters->hist);
+ if (loop->counters->mod)
+ va_heap::release (loop->counters->mod);
ggc_free (loop->counters);
}
ggc_free (loop);
@@ -2219,7 +2222,7 @@ histogram_counters_minus_upper_bound (histogram_counters *&hist_c,
{
if (difference == 0 || !hist_c)
return;
- if (hist_c->sum == 0)
+ if (hist_c->sum == 0 && !hist_c->mod)
{
va_heap::release (hist_c->hist);
ggc_free (hist_c);
@@ -2259,7 +2262,7 @@ histogram_counters_minus_upper_bound (histogram_counters *&hist_c,
pow2 = pow2 << 1;
}
// if there are no more iterations we do not care
- if (hist_c->sum == 0)
+ if (hist_c->sum == 0 && !hist_c->mod)
{
va_heap::release (hist_c->hist);
ggc_free (hist_c);
@@ -2287,6 +2290,21 @@ histogram_counters_minus_upper_bound (histogram_counters *&hist_c,
hist[i] -= diff;
pow2 <<= 1;
}
+ if (hist_c->mod)
+ {
+ auto &mod_h = *(hist_c->mod);
+ unsigned int mod_size = param_profile_histogram_size_mod;
+ // rotate the values by the difference
+ auto_vec<gcov_type> temp;
+ for (unsigned int j = 0; j < mod_size; ++j)
+ {
+ temp.safe_push (mod_h[j]);
+ }
+ for (unsigned int j = 0; j < mod_size; ++j)
+ {
+ mod_h[j] = temp[(mod_size + j - (difference % mod_size)) % mod_size];
+ }
+ }
}
void
@@ -2298,6 +2316,8 @@ histogram_counters_div_upper_bound (histogram_counters *&hist_c,
if (hist_c->sum == 0)
{
va_heap::release (hist_c->hist);
+ if (hist_c->mod)
+ va_heap::release (hist_c->mod);
ggc_free (hist_c);
hist_c = NULL;
return;
@@ -2325,6 +2345,15 @@ histogram_counters_div_upper_bound (histogram_counters *&hist_c,
hist[ind] += hist[MIN (1, i)];
hist[i] = 0;
}
+ // we do not try to maintain modulo info when dividing since it is often
+ // impossible
+ // TODO we can sometimes save this if the divisor and the mod_size are
+ // co-prime
+ if (hist_c->mod)
+ {
+ va_heap::release (hist_c->mod);
+ hist_c->mod = NULL;
+ }
}
// adjust estimates after peeling npeel times
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index f9e20f95f4e..2c3eee123dc 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -99,6 +99,7 @@ struct GTY (()) histogram_counters
bool adjusted;
gcov_type sum;
vec<gcov_type, va_heap, vl_embed> *GTY ((skip)) hist;
+ vec<gcov_type, va_heap, vl_embed> *GTY ((skip)) mod;
};
typedef class loop *loop_p;
diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc
index 1ff9b1f5524..42ce1a529b3 100644
--- a/gcc/cfgloopmanip.cc
+++ b/gcc/cfgloopmanip.cc
@@ -965,6 +965,8 @@ copy_loop_info (class loop *loop, class loop *target)
target->counters->sum = loop->counters->sum;
target->counters->adjusted = loop->counters->adjusted;
target->counters->hist = vec_safe_copy (loop->counters->hist);
+ if (loop->counters->mod)
+ target->counters->mod = vec_safe_copy (loop->counters->mod);
}
}
diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index b08053d7ec3..ccaf10c3e55 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -1132,15 +1132,26 @@ input_cfg (class lto_input_block *ib, class data_in *data_in,
loop->counters = ggc_alloc<histogram_counters> ();
loop->counters->sum = streamer_read_gcov_count (ib);
loop->counters->hist = NULL;
- vec_safe_grow_cleared (loop->counters->hist,
- param_profile_histogram_size_lin
- + param_profile_histogram_size_exp);
+ loop->counters->mod = NULL;
+ vec_safe_grow (loop->counters->hist,
+ param_profile_histogram_size_lin
+ + param_profile_histogram_size_exp);
for (int i = 0; i < param_profile_histogram_size_lin
+ param_profile_histogram_size_exp;
++i)
{
(*loop->counters->hist)[i] = streamer_read_gcov_count (ib);
}
+ // do we have modulos
+ if (streamer_read_hwi (ib))
+ {
+ vec_safe_grow (loop->counters->mod,
+ param_profile_histogram_size_mod);
+ for (int i = 0; i < param_profile_histogram_size_mod; ++i)
+ {
+ (*loop->counters->mod)[i] = streamer_read_gcov_count (ib);
+ }
+ }
}
/* Read OMP SIMD related info. */
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index e6079c62af0..657129080ec 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -2186,12 +2186,21 @@ output_cfg (struct output_block *ob, struct function *fn)
{
streamer_write_gcov_count (ob, loop->counters->sum);
for (unsigned int i = 0;
- i < (unsigned int) param_profile_histogram_size_lin
- + param_profile_histogram_size_exp;
+ i < (unsigned int) (param_profile_histogram_size_lin
+ + param_profile_histogram_size_exp);
++i)
{
streamer_write_gcov_count (ob, (*loop->counters->hist)[i]);
}
+ streamer_write_hwi (ob, loop->counters->mod != NULL);
+ if (loop->counters->mod)
+ {
+ for (unsigned int i = 0;
+ i < (unsigned int) param_profile_histogram_size_mod; ++i)
+ {
+ streamer_write_gcov_count (ob, (*loop->counters->mod)[i]);
+ }
+ }
}
/* Write OMP SIMD related info. */
diff --git a/gcc/profile.cc b/gcc/profile.cc
index 8199ed6350b..d2b8dfcadc1 100644
--- a/gcc/profile.cc
+++ b/gcc/profile.cc
@@ -930,23 +930,33 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
{
lp->counters = ggc_alloc<histogram_counters> ();
gcov_type sum = 0;
+ unsigned int tot_size = param_profile_histogram_size_lin
+ + param_profile_histogram_size_exp;
lp->counters->adjusted = false;
lp->counters->hist = NULL;
- vec_safe_grow_cleared (lp->counters->hist,
- param_profile_histogram_size_lin
- + param_profile_histogram_size_exp);
- for (int i = 0; i < param_profile_histogram_size_lin
- + param_profile_histogram_size_exp;
- ++i)
+ // iteration vector
+ vec_safe_grow_cleared (lp->counters->hist, tot_size);
+ for (int i = 0; i < (int) tot_size; ++i)
{
auto hst = lp->counters->hist;
(*hst)[i] = act_count[t][i];
sum += act_count[t][i];
}
lp->counters->sum = sum;
+
+ // modular vector
+ lp->counters->mod = NULL;
+ vec_safe_grow_cleared (lp->counters->mod,
+ param_profile_histogram_size_mod);
+ for (int j = 0; j < param_profile_histogram_size_mod; ++j)
+ {
+ auto mod = lp->counters->mod;
+ (*mod)[j] = act_count[t][j + tot_size];
+ }
if (sum == 0)
{
va_heap::release (lp->counters->hist);
+ va_heap::release (lp->counters->mod);
ggc_free (lp->counters);
lp->counters = NULL;
}
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index a4ed11f2219..24102320620 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -367,7 +367,8 @@ gimple_gen_histogram_profiler (histogram_value value,
tree ref_ptr = tree_coverage_counter_addr (tag, 0);
tree hist_size = build_int_cst_type (
gcov_type_node, param_profile_histogram_size_lin
- | (gcov_type (param_profile_histogram_size_exp) << 32));
+ | (gcov_type (param_profile_histogram_size_exp) << 10)
+ | (gcov_type (param_profile_histogram_size_mod) << 20));
gcall *call;
auto_vec<edge> exits = get_loop_exit_edges (lp);
for (auto exit : exits)
diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc
index d7d7cd18ce8..5e029c811e2 100644
--- a/gcc/value-prof.cc
+++ b/gcc/value-prof.cc
@@ -283,6 +283,16 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
(int64_t) hist->hvalue
.counters[(param_profile_histogram_size_lin - lin2_log) + i]);
}
+ for (int i = 0; i < param_profile_histogram_size_mod; ++i)
+ {
+ fprintf (dump_file,
+ "Histogram counter histogram%" PRId64 " mod:%" PRId64
+ ".\n",
+ (int64_t) i,
+ (int64_t) hist->hvalue
+ .counters[i + param_profile_histogram_size_lin
+ + param_profile_histogram_size_exp]);
+ }
}
break;
@@ -404,7 +414,8 @@ stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
case HIST_TYPE_HISTOGRAM:
ncounters = param_profile_histogram_size_lin
- + param_profile_histogram_size_exp;
+ + param_profile_histogram_size_exp
+ + param_profile_histogram_size_mod;
break;
case HIST_TYPE_POW2:
case HIST_TYPE_AVERAGE:
@@ -2010,7 +2021,8 @@ gimple_find_values_to_profile (histogram_values *values)
case HIST_TYPE_HISTOGRAM:
hist->n_counters = param_profile_histogram_size_lin
- + param_profile_histogram_size_exp;
+ + param_profile_histogram_size_exp
+ + param_profile_histogram_size_mod;
break;
default:
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 7063af3579f..65427534e91 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -62,10 +62,13 @@ void __gcov_histogram_profiler(gcov_type *counters, gcov_type value,
gcc_assert(hist_sizes >= 0 && value >= 0);
gcov_type_unsigned hist_size = hist_sizes;
gcov_type_unsigned u_value = value;
- gcov_type_unsigned exp_size = hist_size >> 32;
- gcov_type_unsigned lin_size =
- hist_size & ((((gcov_type_unsigned)1) << 32) - 1);
+ // uncode section sizes
+ gcov_type_unsigned mask = (((gcov_type_unsigned)1) << 10) - 1;
+ gcov_type_unsigned lin_size = hist_size & mask;
+ gcov_type_unsigned exp_size = (hist_size >> 10) & mask;
+ gcov_type_unsigned mod_size = hist_size >> 20;
gcov_type_unsigned tot_size = exp_size + lin_size;
+ // add to the regular histogram
if (u_value < lin_size) {
counters[value]++;
} else {
@@ -81,6 +84,8 @@ void __gcov_histogram_profiler(gcov_type *counters, gcov_type value,
}
}
}
+ // add to the modular histogram
+ counters[tot_size + (u_value % mod_size)]++;
}
#endif
@@ -92,10 +97,13 @@ void __gcov_histogram_profiler_atomic(gcov_type *counters, gcov_type value,
gcc_assert(hist_sizes >= 0 && value >= 0);
gcov_type_unsigned hist_size = hist_sizes;
gcov_type_unsigned u_value = value;
- gcov_type_unsigned exp_size = hist_size >> 32;
- gcov_type_unsigned lin_size =
- hist_size & ((((gcov_type_unsigned)1) << 32) - 1);
- gcov_type_unsigned tot_size = lin_size + tot_size;
+ // uncode section sizes
+ gcov_type_unsigned mask = (((gcov_type_unsigned)1) << 10) - 1;
+ gcov_type_unsigned lin_size = hist_size & mask;
+ gcov_type_unsigned exp_size = (hist_size >> 10) & mask;
+ gcov_type_unsigned mod_size = hist_size >> 20;
+ gcov_type_unsigned tot_size = exp_size + lin_size;
+ // add to the regular histogram
if (u_value < lin_size) {
__atomic_fetch_add(&counters[value], 1, __ATOMIC_RELAXED);
} else {
@@ -108,6 +116,9 @@ void __gcov_histogram_profiler_atomic(gcov_type *counters, gcov_type value,
__atomic_fetch_add(&counters[tot_size - 1], 1, __ATOMIC_RELAXED);
}
}
+ // add to the modular histogram
+ __atomic_fetch_add(&counters[tot_size + (u_value % mod_size)], 1,
+ __ATOMIC_RELAXED);
}
#endif
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-04-25 8:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-25 8:10 [gcc(refs/users/kubaneko/heads/histogram)] added modulo histogram and improved garbage collection Ondrej Kubanek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).