|
@@ -3033,10 +3033,6 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
|
|
|
QTAILQ_REMOVE(&s->ops, op, link);
|
|
|
QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
|
|
|
s->nb_ops--;
|
|
|
-
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- qatomic_set(&s->prof.del_op_count, s->prof.del_op_count + 1);
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
void tcg_remove_ops_after(TCGOp *op)
|
|
@@ -5906,143 +5902,16 @@ static void tcg_out_st_helper_args(TCGContext *s, const TCGLabelQemuLdst *ldst,
|
|
|
tcg_out_helper_load_common_args(s, ldst, parm, info, next_arg);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
-
|
|
|
-/* avoid copy/paste errors */
|
|
|
-#define PROF_ADD(to, from, field) \
|
|
|
- do { \
|
|
|
- (to)->field += qatomic_read(&((from)->field)); \
|
|
|
- } while (0)
|
|
|
-
|
|
|
-#define PROF_MAX(to, from, field) \
|
|
|
- do { \
|
|
|
- typeof((from)->field) val__ = qatomic_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 n_ctxs = qatomic_read(&tcg_cur_ctxs);
|
|
|
- unsigned int i;
|
|
|
-
|
|
|
- for (i = 0; i < n_ctxs; i++) {
|
|
|
- TCGContext *s = qatomic_read(&tcg_ctxs[i]);
|
|
|
- const TCGProfile *orig = &s->prof;
|
|
|
-
|
|
|
- if (counters) {
|
|
|
- PROF_ADD(prof, orig, cpu_exec_time);
|
|
|
- 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(GString *buf)
|
|
|
-{
|
|
|
- TCGProfile prof = {};
|
|
|
- int i;
|
|
|
-
|
|
|
- tcg_profile_snapshot_table(&prof);
|
|
|
- for (i = 0; i < NB_OPS; i++) {
|
|
|
- g_string_append_printf(buf, "%s %" PRId64 "\n", tcg_op_defs[i].name,
|
|
|
- prof.table_op_count[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int64_t tcg_cpu_exec_time(void)
|
|
|
-{
|
|
|
- unsigned int n_ctxs = qatomic_read(&tcg_cur_ctxs);
|
|
|
- unsigned int i;
|
|
|
- int64_t ret = 0;
|
|
|
-
|
|
|
- for (i = 0; i < n_ctxs; i++) {
|
|
|
- const TCGContext *s = qatomic_read(&tcg_ctxs[i]);
|
|
|
- const TCGProfile *prof = &s->prof;
|
|
|
-
|
|
|
- ret += qatomic_read(&prof->cpu_exec_time);
|
|
|
- }
|
|
|
- return ret;
|
|
|
-}
|
|
|
-#else
|
|
|
void tcg_dump_op_count(GString *buf)
|
|
|
{
|
|
|
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
|
|
|
}
|
|
|
|
|
|
-int64_t tcg_cpu_exec_time(void)
|
|
|
-{
|
|
|
- error_report("%s: TCG profiler not compiled", __func__);
|
|
|
- exit(EXIT_FAILURE);
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-
|
|
|
int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
|
|
{
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- TCGProfile *prof = &s->prof;
|
|
|
-#endif
|
|
|
int i, start_words, num_insns;
|
|
|
TCGOp *op;
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- {
|
|
|
- int n = 0;
|
|
|
-
|
|
|
- QTAILQ_FOREACH(op, &s->ops, link) {
|
|
|
- n++;
|
|
|
- }
|
|
|
- qatomic_set(&prof->op_count, prof->op_count + n);
|
|
|
- if (n > prof->op_count_max) {
|
|
|
- qatomic_set(&prof->op_count_max, n);
|
|
|
- }
|
|
|
-
|
|
|
- n = s->nb_temps;
|
|
|
- qatomic_set(&prof->temp_count, prof->temp_count + n);
|
|
|
- if (n > prof->temp_count_max) {
|
|
|
- qatomic_set(&prof->temp_count_max, n);
|
|
|
- }
|
|
|
- }
|
|
|
-#endif
|
|
|
-
|
|
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
|
|
|
&& qemu_log_in_addr_range(pc_start))) {
|
|
|
FILE *logfile = qemu_log_trylock();
|
|
@@ -6071,17 +5940,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
|
|
|
-#endif
|
|
|
-
|
|
|
tcg_optimize(s);
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- qatomic_set(&prof->opt_time, prof->opt_time + profile_getclock());
|
|
|
- qatomic_set(&prof->la_time, prof->la_time - profile_getclock());
|
|
|
-#endif
|
|
|
-
|
|
|
reachable_code_pass(s);
|
|
|
liveness_pass_0(s);
|
|
|
liveness_pass_1(s);
|
|
@@ -6105,10 +5965,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- qatomic_set(&prof->la_time, prof->la_time + profile_getclock());
|
|
|
-#endif
|
|
|
-
|
|
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
|
|
|
&& qemu_log_in_addr_range(pc_start))) {
|
|
|
FILE *logfile = qemu_log_trylock();
|
|
@@ -6151,10 +6007,6 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
|
|
QTAILQ_FOREACH(op, &s->ops, link) {
|
|
|
TCGOpcode opc = op->opc;
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
- qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
|
|
|
-#endif
|
|
|
-
|
|
|
switch (opc) {
|
|
|
case INDEX_op_mov_i32:
|
|
|
case INDEX_op_mov_i64:
|
|
@@ -6249,76 +6101,10 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
|
|
return tcg_current_code_size(s);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_PROFILER
|
|
|
-void tcg_dump_info(GString *buf)
|
|
|
-{
|
|
|
- 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;
|
|
|
-
|
|
|
- g_string_append_printf(buf, "JIT cycles %" PRId64
|
|
|
- " (%0.3f s at 2.4 GHz)\n",
|
|
|
- tot, tot / 2.4e9);
|
|
|
- g_string_append_printf(buf, "translated TBs %" PRId64
|
|
|
- " (aborted=%" PRId64 " %0.1f%%)\n",
|
|
|
- tb_count, s->tb_count1 - tb_count,
|
|
|
- (double)(s->tb_count1 - s->tb_count)
|
|
|
- / (s->tb_count1 ? s->tb_count1 : 1) * 100.0);
|
|
|
- g_string_append_printf(buf, "avg ops/TB %0.1f max=%d\n",
|
|
|
- (double)s->op_count / tb_div_count, s->op_count_max);
|
|
|
- g_string_append_printf(buf, "deleted ops/TB %0.2f\n",
|
|
|
- (double)s->del_op_count / tb_div_count);
|
|
|
- g_string_append_printf(buf, "avg temps/TB %0.2f max=%d\n",
|
|
|
- (double)s->temp_count / tb_div_count,
|
|
|
- s->temp_count_max);
|
|
|
- g_string_append_printf(buf, "avg host code/TB %0.1f\n",
|
|
|
- (double)s->code_out_len / tb_div_count);
|
|
|
- g_string_append_printf(buf, "avg search data/TB %0.1f\n",
|
|
|
- (double)s->search_out_len / tb_div_count);
|
|
|
-
|
|
|
- g_string_append_printf(buf, "cycles/op %0.1f\n",
|
|
|
- s->op_count ? (double)tot / s->op_count : 0);
|
|
|
- g_string_append_printf(buf, "cycles/in byte %0.1f\n",
|
|
|
- s->code_in_len ? (double)tot / s->code_in_len : 0);
|
|
|
- g_string_append_printf(buf, "cycles/out byte %0.1f\n",
|
|
|
- s->code_out_len ? (double)tot / s->code_out_len : 0);
|
|
|
- g_string_append_printf(buf, "cycles/search byte %0.1f\n",
|
|
|
- s->search_out_len ?
|
|
|
- (double)tot / s->search_out_len : 0);
|
|
|
- if (tot == 0) {
|
|
|
- tot = 1;
|
|
|
- }
|
|
|
- g_string_append_printf(buf, " gen_interm time %0.1f%%\n",
|
|
|
- (double)s->interm_time / tot * 100.0);
|
|
|
- g_string_append_printf(buf, " gen_code time %0.1f%%\n",
|
|
|
- (double)s->code_time / tot * 100.0);
|
|
|
- g_string_append_printf(buf, "optim./code time %0.1f%%\n",
|
|
|
- (double)s->opt_time / (s->code_time ?
|
|
|
- s->code_time : 1)
|
|
|
- * 100.0);
|
|
|
- g_string_append_printf(buf, "liveness/code time %0.1f%%\n",
|
|
|
- (double)s->la_time / (s->code_time ?
|
|
|
- s->code_time : 1) * 100.0);
|
|
|
- g_string_append_printf(buf, "cpu_restore count %" PRId64 "\n",
|
|
|
- s->restore_count);
|
|
|
- g_string_append_printf(buf, " avg cycles %0.1f\n",
|
|
|
- s->restore_count ?
|
|
|
- (double)s->restore_time / s->restore_count : 0);
|
|
|
-}
|
|
|
-#else
|
|
|
void tcg_dump_info(GString *buf)
|
|
|
{
|
|
|
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
#ifdef ELF_HOST_MACHINE
|
|
|
/* In order to use this feature, the backend needs to do three things:
|