summaryrefslogtreecommitdiff
path: root/tcg/tcg.c
diff options
context:
space:
mode:
authorEmilio G. Cota <cota@braap.org>2017-07-05 19:35:06 -0400
committerRichard Henderson <richard.henderson@linaro.org>2017-10-24 13:53:42 -0700
commitc3fac1138e13f8074168ee32a46afd6f3ff49059 (patch)
treed75702ab689a9879a0ce1de16fd42733a56c8f8b /tcg/tcg.c
parentdf2cce2968069526553d82331ce9817eaca6b03a (diff)
downloadqemu-c3fac1138e13f8074168ee32a46afd6f3ff49059.tar.gz
tcg: distribute profiling counters across TCGContext's
This is groundwork for supporting multiple TCG contexts. To avoid scalability issues when profiling info is enabled, this patch makes the profiling info counters distributed via the following changes: 1) Consolidate profile info into its own struct, TCGProfile, which TCGContext also includes. Note that tcg_table_op_count is brought into TCGProfile after dropping the tcg_ prefix. 2) Iterate over the TCG contexts in the system to obtain the total counts. This change also requires updating the accessors to TCGProfile fields to use atomic_read/set whenever there may be conflicting accesses (as defined in C11) to them. Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Emilio G. Cota <cota@braap.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/tcg.c')
-rw-r--r--tcg/tcg.c110
1 files changed, 92 insertions, 18 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 24ef6df6b5..f1bbfe37ff 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1547,7 +1547,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
memset(op, 0, sizeof(*op));
#ifdef CONFIG_PROFILER
- s->del_op_count++;
+ atomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
#endif
}
@@ -2715,15 +2715,79 @@ static void tcg_reg_alloc_call(TCGContext *s, TCGOp *op)
#ifdef CONFIG_PROFILER
-static int64_t tcg_table_op_count[NB_OPS];
+/* avoid copy/paste errors */
+#define PROF_ADD(to, from, field) \
+ do { \
+ (to)->field += atomic_read(&((from)->field)); \
+ } while (0)
+
+#define PROF_MAX(to, from, field) \
+ do { \
+ typeof((from)->field) val__ = atomic_read(&((from)->field)); \
+ if (val__ > (to)->field) { \
+ (to)->field = val__; \
+ } \
+ } while (0)
+
+/* Pass in a zero'ed @prof */
+static inline
+void tcg_profile_snapshot(TCGProfile *prof, bool counters, bool table)
+{
+ unsigned int i;
+
+ for (i = 0; i < n_tcg_ctxs; i++) {
+ const TCGProfile *orig = &tcg_ctxs[i]->prof;
+
+ if (counters) {
+ PROF_ADD(prof, orig, tb_count1);
+ PROF_ADD(prof, orig, tb_count);
+ PROF_ADD(prof, orig, op_count);
+ PROF_MAX(prof, orig, op_count_max);
+ PROF_ADD(prof, orig, temp_count);
+ PROF_MAX(prof, orig, temp_count_max);
+ PROF_ADD(prof, orig, del_op_count);
+ PROF_ADD(prof, orig, code_in_len);
+ PROF_ADD(prof, orig, code_out_len);
+ PROF_ADD(prof, orig, search_out_len);
+ PROF_ADD(prof, orig, interm_time);
+ PROF_ADD(prof, orig, code_time);
+ PROF_ADD(prof, orig, la_time);
+ PROF_ADD(prof, orig, opt_time);
+ PROF_ADD(prof, orig, restore_count);
+ PROF_ADD(prof, orig, restore_time);
+ }
+ if (table) {
+ int i;
+
+ for (i = 0; i < NB_OPS; i++) {
+ PROF_ADD(prof, orig, table_op_count[i]);
+ }
+ }
+ }
+}
+
+#undef PROF_ADD
+#undef PROF_MAX
+
+static void tcg_profile_snapshot_counters(TCGProfile *prof)
+{
+ tcg_profile_snapshot(prof, true, false);
+}
+
+static void tcg_profile_snapshot_table(TCGProfile *prof)
+{
+ tcg_profile_snapshot(prof, false, true);
+}
void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
{
+ TCGProfile prof = {};
int i;
+ tcg_profile_snapshot_table(&prof);
for (i = 0; i < NB_OPS; i++) {
cpu_fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name,
- tcg_table_op_count[i]);
+ prof.table_op_count[i]);
}
}
#else
@@ -2736,6 +2800,9 @@ void tcg_dump_op_count(FILE *f, fprintf_function cpu_fprintf)
int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
{
+#ifdef CONFIG_PROFILER
+ TCGProfile *prof = &s->prof;
+#endif
int i, oi, oi_next, num_insns;
#ifdef CONFIG_PROFILER
@@ -2743,15 +2810,15 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
int n;
n = s->gen_op_buf[0].prev + 1;
- s->op_count += n;
- if (n > s->op_count_max) {
- s->op_count_max = n;
+ atomic_set(&prof->op_count, prof->op_count + n);
+ if (n > prof->op_count_max) {
+ atomic_set(&prof->op_count_max, n);
}
n = s->nb_temps;
- s->temp_count += n;
- if (n > s->temp_count_max) {
- s->temp_count_max = n;
+ atomic_set(&prof->temp_count, prof->temp_count + n);
+ if (n > prof->temp_count_max) {
+ atomic_set(&prof->temp_count_max, n);
}
}
#endif
@@ -2768,7 +2835,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
#endif
#ifdef CONFIG_PROFILER
- s->opt_time -= profile_getclock();
+ atomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
#endif
#ifdef USE_TCG_OPTIMIZATIONS
@@ -2776,8 +2843,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
#endif
#ifdef CONFIG_PROFILER
- s->opt_time += profile_getclock();
- s->la_time -= profile_getclock();
+ atomic_set(&prof->opt_time, prof->opt_time + profile_getclock());
+ atomic_set(&prof->la_time, prof->la_time - profile_getclock());
#endif
liveness_pass_1(s);
@@ -2801,7 +2868,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
}
#ifdef CONFIG_PROFILER
- s->la_time += profile_getclock();
+ atomic_set(&prof->la_time, prof->la_time + profile_getclock());
#endif
#ifdef DEBUG_DISAS
@@ -2834,7 +2901,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
oi_next = op->next;
#ifdef CONFIG_PROFILER
- tcg_table_op_count[opc]++;
+ atomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
#endif
switch (opc) {
@@ -2915,10 +2982,17 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
#ifdef CONFIG_PROFILER
void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
{
- TCGContext *s = tcg_ctx;
- int64_t tb_count = s->tb_count;
- int64_t tb_div_count = tb_count ? tb_count : 1;
- int64_t tot = s->interm_time + s->code_time;
+ TCGProfile prof = {};
+ const TCGProfile *s;
+ int64_t tb_count;
+ int64_t tb_div_count;
+ int64_t tot;
+
+ tcg_profile_snapshot_counters(&prof);
+ s = &prof;
+ tb_count = s->tb_count;
+ tb_div_count = tb_count ? tb_count : 1;
+ tot = s->interm_time + s->code_time;
cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
tot, tot / 2.4e9);