aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-23 09:52:20 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2008-05-23 09:52:20 +0000
commita23a9ec615e160c9ac008f27d554a79255ca27b0 (patch)
tree799c9119779ace6e17a5fbe3c3fec33b6b447315 /tcg
parent95af5ce5e21d789d3f3a8291585d5e67fc5e6bb5 (diff)
profiler clean up
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4537 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg.c85
-rw-r--r--tcg/tcg.h21
2 files changed, 93 insertions, 13 deletions
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 1c1bb9fabe..31962a9e58 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1156,10 +1156,7 @@ void tcg_liveness_analysis(TCGContext *s)
}
tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
#ifdef CONFIG_PROFILER
- {
- extern int64_t dyngen_tcg_del_op_count;
- dyngen_tcg_del_op_count++;
- }
+ s->del_op_count++;
#endif
} else {
do_not_remove:
@@ -1822,7 +1819,13 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
}
#endif
+#ifdef CONFIG_PROFILER
+ s->la_time -= profile_getclock();
+#endif
tcg_liveness_analysis(s);
+#ifdef CONFIG_PROFILER
+ s->la_time += profile_getclock();
+#endif
#ifdef DEBUG_DISAS
if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {
@@ -1911,10 +1914,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
case 0 ... INDEX_op_end - 1:
/* legacy dyngen ops */
#ifdef CONFIG_PROFILER
- {
- extern int64_t dyngen_old_op_count;
- dyngen_old_op_count++;
- }
+ s->old_op_count++;
#endif
tcg_reg_alloc_bb_end(s);
if (search_pc >= 0) {
@@ -1954,13 +1954,15 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
{
#ifdef CONFIG_PROFILER
{
- extern int64_t dyngen_op_count;
- extern int dyngen_op_count_max;
int n;
n = (gen_opc_ptr - gen_opc_buf);
- dyngen_op_count += n;
- if (n > dyngen_op_count_max)
- dyngen_op_count_max = n;
+ s->op_count += n;
+ if (n > s->op_count_max)
+ s->op_count_max = n;
+
+ s->temp_count += s->nb_temps;
+ if (s->nb_temps > s->temp_count_max)
+ s->temp_count_max = s->nb_temps;
}
#endif
@@ -1980,3 +1982,60 @@ int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
{
return tcg_gen_code_common(s, gen_code_buf, offset);
}
+
+#ifdef CONFIG_PROFILER
+void tcg_dump_info(FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+ TCGContext *s = &tcg_ctx;
+ int64_t tot;
+
+ 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);
+ cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
+ s->tb_count,
+ s->tb_count1 - s->tb_count,
+ s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
+ cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
+ s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
+ cpu_fprintf(f, "old ops/total ops %0.1f%%\n",
+ s->op_count ? (double)s->old_op_count / s->op_count * 100.0 : 0);
+ cpu_fprintf(f, "deleted ops/TB %0.2f\n",
+ s->tb_count ?
+ (double)s->del_op_count / s->tb_count : 0);
+ cpu_fprintf(f, "avg temps/TB %0.2f max=%d\n",
+ s->tb_count ?
+ (double)s->temp_count / s->tb_count : 0,
+ s->temp_count_max);
+
+ cpu_fprintf(f, "cycles/op %0.1f\n",
+ s->op_count ? (double)tot / s->op_count : 0);
+ cpu_fprintf(f, "cycles/in byte %0.1f\n",
+ s->code_in_len ? (double)tot / s->code_in_len : 0);
+ cpu_fprintf(f, "cycles/out byte %0.1f\n",
+ s->code_out_len ? (double)tot / s->code_out_len : 0);
+ if (tot == 0)
+ tot = 1;
+ cpu_fprintf(f, " gen_interm time %0.1f%%\n",
+ (double)s->interm_time / tot * 100.0);
+ cpu_fprintf(f, " gen_code time %0.1f%%\n",
+ (double)s->code_time / tot * 100.0);
+ cpu_fprintf(f, "liveness/code time %0.1f%%\n",
+ (double)s->la_time / (s->code_time ? s->code_time : 1) * 100.0);
+ cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
+ s->restore_count);
+ cpu_fprintf(f, " avg cycles %0.1f\n",
+ s->restore_count ? (double)s->restore_time / s->restore_count : 0);
+ {
+ extern void dump_op_count(void);
+ dump_op_count();
+ }
+}
+#else
+void dump_tcg_info(FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+ cpu_fprintf("[TCG profiler not compiled]\n");
+}
+#endif
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 1c9b5f1224..b29b54825f 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -236,6 +236,25 @@ struct TCGContext {
TCGHelperInfo *helpers;
int nb_helpers;
int allocated_helpers;
+
+#ifdef CONFIG_PROFILER
+ /* profiling info */
+ int64_t tb_count1;
+ int64_t tb_count;
+ int64_t op_count; /* total insn count */
+ int op_count_max; /* max insn per TB */
+ int64_t temp_count;
+ int temp_count_max;
+ int64_t old_op_count;
+ int64_t del_op_count;
+ int64_t code_in_len;
+ int64_t code_out_len;
+ int64_t interm_time;
+ int64_t code_time;
+ int64_t la_time;
+ int64_t restore_count;
+ int64_t restore_time;
+#endif
};
extern TCGContext tcg_ctx;
@@ -281,6 +300,8 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
const char *name);
TCGv tcg_temp_new(TCGType type);
char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
+void tcg_dump_info(FILE *f,
+ int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
#define TCG_CT_ALIAS 0x80
#define TCG_CT_IALIAS 0x40