accel/tcg: remove CONFIG_PROFILER
TBStats will be introduced to replace CONFIG_PROFILER totally, here remove all CONFIG_PROFILER related stuffs first. Signed-off-by: Vanderson M. do Rosario <vandersonmr2@gmail.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Fei Wu <fei2.wu@intel.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230607122411.3394702-2-fei2.wu@intel.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
ea185a557b
commit
1b65b4f54c
|
@ -81,37 +81,6 @@ HumanReadableText *qmp_x_query_opcount(Error **errp)
|
||||||
return human_readable_text_from_str(buf);
|
return human_readable_text_from_str(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
|
|
||||||
int64_t dev_time;
|
|
||||||
|
|
||||||
HumanReadableText *qmp_x_query_profile(Error **errp)
|
|
||||||
{
|
|
||||||
g_autoptr(GString) buf = g_string_new("");
|
|
||||||
static int64_t last_cpu_exec_time;
|
|
||||||
int64_t cpu_exec_time;
|
|
||||||
int64_t delta;
|
|
||||||
|
|
||||||
cpu_exec_time = tcg_cpu_exec_time();
|
|
||||||
delta = cpu_exec_time - last_cpu_exec_time;
|
|
||||||
|
|
||||||
g_string_append_printf(buf, "async time %" PRId64 " (%0.3f)\n",
|
|
||||||
dev_time, dev_time / (double)NANOSECONDS_PER_SECOND);
|
|
||||||
g_string_append_printf(buf, "qemu time %" PRId64 " (%0.3f)\n",
|
|
||||||
delta, delta / (double)NANOSECONDS_PER_SECOND);
|
|
||||||
last_cpu_exec_time = cpu_exec_time;
|
|
||||||
dev_time = 0;
|
|
||||||
|
|
||||||
return human_readable_text_from_str(buf);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
HumanReadableText *qmp_x_query_profile(Error **errp)
|
|
||||||
{
|
|
||||||
error_setg(errp, "Internal profiler not compiled");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void hmp_tcg_register(void)
|
static void hmp_tcg_register(void)
|
||||||
{
|
{
|
||||||
monitor_register_hmp_info_hrt("jit", qmp_x_query_jit);
|
monitor_register_hmp_info_hrt("jit", qmp_x_query_jit);
|
||||||
|
|
|
@ -70,20 +70,10 @@ void tcg_cpus_destroy(CPUState *cpu)
|
||||||
int tcg_cpus_exec(CPUState *cpu)
|
int tcg_cpus_exec(CPUState *cpu)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
int64_t ti;
|
|
||||||
#endif
|
|
||||||
assert(tcg_enabled());
|
assert(tcg_enabled());
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
ti = profile_getclock();
|
|
||||||
#endif
|
|
||||||
cpu_exec_start(cpu);
|
cpu_exec_start(cpu);
|
||||||
ret = cpu_exec(cpu);
|
ret = cpu_exec(cpu);
|
||||||
cpu_exec_end(cpu);
|
cpu_exec_end(cpu);
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&tcg_ctx->prof.cpu_exec_time,
|
|
||||||
tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
|
|
||||||
#endif
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -202,10 +202,6 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
||||||
uintptr_t host_pc)
|
uintptr_t host_pc)
|
||||||
{
|
{
|
||||||
uint64_t data[TARGET_INSN_START_WORDS];
|
uint64_t data[TARGET_INSN_START_WORDS];
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
TCGProfile *prof = &tcg_ctx->prof;
|
|
||||||
int64_t ti = profile_getclock();
|
|
||||||
#endif
|
|
||||||
int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data);
|
int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data);
|
||||||
|
|
||||||
if (insns_left < 0) {
|
if (insns_left < 0) {
|
||||||
|
@ -222,12 +218,6 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data);
|
cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data);
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&prof->restore_time,
|
|
||||||
prof->restore_time + profile_getclock() - ti);
|
|
||||||
qatomic_set(&prof->restore_count, prof->restore_count + 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
|
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc)
|
||||||
|
@ -290,13 +280,6 @@ static int setjmp_gen_code(CPUArchState *env, TranslationBlock *tb,
|
||||||
tcg_ctx->cpu = NULL;
|
tcg_ctx->cpu = NULL;
|
||||||
*max_insns = tb->icount;
|
*max_insns = tb->icount;
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&tcg_ctx->prof.tb_count, tcg_ctx->prof.tb_count + 1);
|
|
||||||
qatomic_set(&tcg_ctx->prof.interm_time,
|
|
||||||
tcg_ctx->prof.interm_time + profile_getclock() - *ti);
|
|
||||||
*ti = profile_getclock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return tcg_gen_code(tcg_ctx, tb, pc);
|
return tcg_gen_code(tcg_ctx, tb, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,9 +293,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||||
tb_page_addr_t phys_pc;
|
tb_page_addr_t phys_pc;
|
||||||
tcg_insn_unit *gen_code_buf;
|
tcg_insn_unit *gen_code_buf;
|
||||||
int gen_code_size, search_size, max_insns;
|
int gen_code_size, search_size, max_insns;
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
TCGProfile *prof = &tcg_ctx->prof;
|
|
||||||
#endif
|
|
||||||
int64_t ti;
|
int64_t ti;
|
||||||
void *host_pc;
|
void *host_pc;
|
||||||
|
|
||||||
|
@ -371,12 +351,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||||
|
|
||||||
tb_overflow:
|
tb_overflow:
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
/* includes aborted translations because of exceptions */
|
|
||||||
qatomic_set(&prof->tb_count1, prof->tb_count1 + 1);
|
|
||||||
ti = profile_getclock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
trace_translate_block(tb, pc, tb->tc.ptr);
|
trace_translate_block(tb, pc, tb->tc.ptr);
|
||||||
|
|
||||||
gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti);
|
gen_code_size = setjmp_gen_code(env, tb, pc, host_pc, &max_insns, &ti);
|
||||||
|
@ -431,13 +405,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||||
*/
|
*/
|
||||||
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
|
perf_report_code(pc, tb, tcg_splitwx_to_rx(gen_code_buf));
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&prof->code_time, prof->code_time + profile_getclock() - ti);
|
|
||||||
qatomic_set(&prof->code_in_len, prof->code_in_len + tb->size);
|
|
||||||
qatomic_set(&prof->code_out_len, prof->code_out_len + gen_code_size);
|
|
||||||
qatomic_set(&prof->search_out_len, prof->search_out_len + search_size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
|
if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) &&
|
||||||
qemu_log_in_addr_range(pc)) {
|
qemu_log_in_addr_range(pc)) {
|
||||||
FILE *logfile = qemu_log_trylock();
|
FILE *logfile = qemu_log_trylock();
|
||||||
|
|
|
@ -360,21 +360,6 @@ SRST
|
||||||
Show host USB devices.
|
Show host USB devices.
|
||||||
ERST
|
ERST
|
||||||
|
|
||||||
#if defined(CONFIG_TCG)
|
|
||||||
{
|
|
||||||
.name = "profile",
|
|
||||||
.args_type = "",
|
|
||||||
.params = "",
|
|
||||||
.help = "show profiling information",
|
|
||||||
.cmd_info_hrt = qmp_x_query_profile,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SRST
|
|
||||||
``info profile``
|
|
||||||
Show profiling information.
|
|
||||||
ERST
|
|
||||||
|
|
||||||
{
|
{
|
||||||
.name = "capture",
|
.name = "capture",
|
||||||
.args_type = "",
|
.args_type = "",
|
||||||
|
|
|
@ -989,13 +989,4 @@ static inline int64_t cpu_get_host_ticks(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
static inline int64_t profile_getclock(void)
|
|
||||||
{
|
|
||||||
return get_clock();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int64_t dev_time;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -478,27 +478,6 @@ static inline TCGRegSet output_pref(const TCGOp *op, unsigned i)
|
||||||
return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0;
|
return i < ARRAY_SIZE(op->output_pref) ? op->output_pref[i] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct TCGProfile {
|
|
||||||
int64_t cpu_exec_time;
|
|
||||||
int64_t tb_count1;
|
|
||||||
int64_t tb_count;
|
|
||||||
int64_t op_count; /* total insn count */
|
|
||||||
int op_count_max; /* max insn per TB */
|
|
||||||
int temp_count_max;
|
|
||||||
int64_t temp_count;
|
|
||||||
int64_t del_op_count;
|
|
||||||
int64_t code_in_len;
|
|
||||||
int64_t code_out_len;
|
|
||||||
int64_t search_out_len;
|
|
||||||
int64_t interm_time;
|
|
||||||
int64_t code_time;
|
|
||||||
int64_t la_time;
|
|
||||||
int64_t opt_time;
|
|
||||||
int64_t restore_count;
|
|
||||||
int64_t restore_time;
|
|
||||||
int64_t table_op_count[NB_OPS];
|
|
||||||
} TCGProfile;
|
|
||||||
|
|
||||||
struct TCGContext {
|
struct TCGContext {
|
||||||
uint8_t *pool_cur, *pool_end;
|
uint8_t *pool_cur, *pool_end;
|
||||||
TCGPool *pool_first, *pool_current, *pool_first_large;
|
TCGPool *pool_first, *pool_current, *pool_first_large;
|
||||||
|
@ -528,10 +507,6 @@ struct TCGContext {
|
||||||
tcg_insn_unit *code_buf; /* pointer for start of tb */
|
tcg_insn_unit *code_buf; /* pointer for start of tb */
|
||||||
tcg_insn_unit *code_ptr; /* pointer for running end of tb */
|
tcg_insn_unit *code_ptr; /* pointer for running end of tb */
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
TCGProfile prof;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_TCG
|
#ifdef CONFIG_DEBUG_TCG
|
||||||
int goto_tb_issue_mask;
|
int goto_tb_issue_mask;
|
||||||
const TCGOpcode *vecop_list;
|
const TCGOpcode *vecop_list;
|
||||||
|
@ -871,7 +846,6 @@ static inline TCGv_ptr tcg_temp_new_ptr(void)
|
||||||
return temp_tcgv_ptr(t);
|
return temp_tcgv_ptr(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tcg_cpu_exec_time(void);
|
|
||||||
void tcg_dump_info(GString *buf);
|
void tcg_dump_info(GString *buf);
|
||||||
void tcg_dump_op_count(GString *buf);
|
void tcg_dump_op_count(GString *buf);
|
||||||
|
|
||||||
|
|
|
@ -2121,7 +2121,6 @@ if numa.found()
|
||||||
dependencies: numa))
|
dependencies: numa))
|
||||||
endif
|
endif
|
||||||
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
config_host_data.set('CONFIG_OPENGL', opengl.found())
|
||||||
config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
|
|
||||||
config_host_data.set('CONFIG_RBD', rbd.found())
|
config_host_data.set('CONFIG_RBD', rbd.found())
|
||||||
config_host_data.set('CONFIG_RDMA', rdma.found())
|
config_host_data.set('CONFIG_RDMA', rdma.found())
|
||||||
config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
|
config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack'))
|
||||||
|
@ -4087,7 +4086,6 @@ if 'objc' in all_languages
|
||||||
summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
|
summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)}
|
||||||
endif
|
endif
|
||||||
summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
|
summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
|
||||||
summary_info += {'profiler': get_option('profiler')}
|
|
||||||
summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
|
summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
|
||||||
summary_info += {'PIE': get_option('b_pie')}
|
summary_info += {'PIE': get_option('b_pie')}
|
||||||
summary_info += {'static build': get_option('prefer_static')}
|
summary_info += {'static build': get_option('prefer_static')}
|
||||||
|
|
|
@ -345,8 +345,6 @@ option('qom_cast_debug', type: 'boolean', value: true,
|
||||||
option('gprof', type: 'boolean', value: false,
|
option('gprof', type: 'boolean', value: false,
|
||||||
description: 'QEMU profiling with gprof',
|
description: 'QEMU profiling with gprof',
|
||||||
deprecated: true)
|
deprecated: true)
|
||||||
option('profiler', type: 'boolean', value: false,
|
|
||||||
description: 'profiler support')
|
|
||||||
option('slirp_smbd', type : 'feature', value : 'auto',
|
option('slirp_smbd', type : 'feature', value : 'auto',
|
||||||
description: 'use smbd (at path --smbd=*) in slirp networking')
|
description: 'use smbd (at path --smbd=*) in slirp networking')
|
||||||
|
|
||||||
|
|
|
@ -1575,24 +1575,6 @@
|
||||||
'if': 'CONFIG_TCG',
|
'if': 'CONFIG_TCG',
|
||||||
'features': [ 'unstable' ] }
|
'features': [ 'unstable' ] }
|
||||||
|
|
||||||
##
|
|
||||||
# @x-query-profile:
|
|
||||||
#
|
|
||||||
# Query TCG profiling information
|
|
||||||
#
|
|
||||||
# Features:
|
|
||||||
#
|
|
||||||
# @unstable: This command is meant for debugging.
|
|
||||||
#
|
|
||||||
# Returns: profile information
|
|
||||||
#
|
|
||||||
# Since: 6.2
|
|
||||||
##
|
|
||||||
{ 'command': 'x-query-profile',
|
|
||||||
'returns': 'HumanReadableText',
|
|
||||||
'if': 'CONFIG_TCG',
|
|
||||||
'features': [ 'unstable' ] }
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# @x-query-ramblock:
|
# @x-query-ramblock:
|
||||||
#
|
#
|
||||||
|
|
|
@ -39,7 +39,6 @@ meson_options_help() {
|
||||||
printf "%s\n" ' jemalloc/system/tcmalloc)'
|
printf "%s\n" ' jemalloc/system/tcmalloc)'
|
||||||
printf "%s\n" ' --enable-module-upgrades try to load modules from alternate paths for'
|
printf "%s\n" ' --enable-module-upgrades try to load modules from alternate paths for'
|
||||||
printf "%s\n" ' upgrades'
|
printf "%s\n" ' upgrades'
|
||||||
printf "%s\n" ' --enable-profiler profiler support'
|
|
||||||
printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and'
|
printf "%s\n" ' --enable-rng-none dummy RNG, avoid using /dev/(u)random and'
|
||||||
printf "%s\n" ' getrandom()'
|
printf "%s\n" ' getrandom()'
|
||||||
printf "%s\n" ' --enable-safe-stack SafeStack Stack Smash Protection (requires'
|
printf "%s\n" ' --enable-safe-stack SafeStack Stack Smash Protection (requires'
|
||||||
|
@ -401,8 +400,6 @@ _meson_option_parse() {
|
||||||
--with-pkgversion=*) quote_sh "-Dpkgversion=$2" ;;
|
--with-pkgversion=*) quote_sh "-Dpkgversion=$2" ;;
|
||||||
--enable-png) printf "%s" -Dpng=enabled ;;
|
--enable-png) printf "%s" -Dpng=enabled ;;
|
||||||
--disable-png) printf "%s" -Dpng=disabled ;;
|
--disable-png) printf "%s" -Dpng=disabled ;;
|
||||||
--enable-profiler) printf "%s" -Dprofiler=true ;;
|
|
||||||
--disable-profiler) printf "%s" -Dprofiler=false ;;
|
|
||||||
--enable-pvrdma) printf "%s" -Dpvrdma=enabled ;;
|
--enable-pvrdma) printf "%s" -Dpvrdma=enabled ;;
|
||||||
--disable-pvrdma) printf "%s" -Dpvrdma=disabled ;;
|
--disable-pvrdma) printf "%s" -Dpvrdma=disabled ;;
|
||||||
--enable-qcow1) printf "%s" -Dqcow1=enabled ;;
|
--enable-qcow1) printf "%s" -Dqcow1=enabled ;;
|
||||||
|
|
|
@ -727,18 +727,9 @@ static bool main_loop_should_exit(int *status)
|
||||||
int qemu_main_loop(void)
|
int qemu_main_loop(void)
|
||||||
{
|
{
|
||||||
int status = EXIT_SUCCESS;
|
int status = EXIT_SUCCESS;
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
int64_t ti;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (!main_loop_should_exit(&status)) {
|
while (!main_loop_should_exit(&status)) {
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
ti = profile_getclock();
|
|
||||||
#endif
|
|
||||||
main_loop_wait(false);
|
main_loop_wait(false);
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
dev_time += profile_getclock() - ti;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
214
tcg/tcg.c
214
tcg/tcg.c
|
@ -3033,10 +3033,6 @@ void tcg_op_remove(TCGContext *s, TCGOp *op)
|
||||||
QTAILQ_REMOVE(&s->ops, op, link);
|
QTAILQ_REMOVE(&s->ops, op, link);
|
||||||
QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
|
QTAILQ_INSERT_TAIL(&s->free_ops, op, link);
|
||||||
s->nb_ops--;
|
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)
|
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);
|
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)
|
void tcg_dump_op_count(GString *buf)
|
||||||
{
|
{
|
||||||
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
|
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)
|
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;
|
int i, start_words, num_insns;
|
||||||
TCGOp *op;
|
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)
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)
|
||||||
&& qemu_log_in_addr_range(pc_start))) {
|
&& qemu_log_in_addr_range(pc_start))) {
|
||||||
FILE *logfile = qemu_log_trylock();
|
FILE *logfile = qemu_log_trylock();
|
||||||
|
@ -6071,17 +5940,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&prof->opt_time, prof->opt_time - profile_getclock());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tcg_optimize(s);
|
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);
|
reachable_code_pass(s);
|
||||||
liveness_pass_0(s);
|
liveness_pass_0(s);
|
||||||
liveness_pass_1(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)
|
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT)
|
||||||
&& qemu_log_in_addr_range(pc_start))) {
|
&& qemu_log_in_addr_range(pc_start))) {
|
||||||
FILE *logfile = qemu_log_trylock();
|
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) {
|
QTAILQ_FOREACH(op, &s->ops, link) {
|
||||||
TCGOpcode opc = op->opc;
|
TCGOpcode opc = op->opc;
|
||||||
|
|
||||||
#ifdef CONFIG_PROFILER
|
|
||||||
qatomic_set(&prof->table_op_count[opc], prof->table_op_count[opc] + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case INDEX_op_mov_i32:
|
case INDEX_op_mov_i32:
|
||||||
case INDEX_op_mov_i64:
|
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);
|
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)
|
void tcg_dump_info(GString *buf)
|
||||||
{
|
{
|
||||||
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
|
g_string_append_printf(buf, "[TCG profiler not compiled]\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ELF_HOST_MACHINE
|
#ifdef ELF_HOST_MACHINE
|
||||||
/* In order to use this feature, the backend needs to do three things:
|
/* In order to use this feature, the backend needs to do three things:
|
||||||
|
|
|
@ -46,9 +46,6 @@ static int query_error_class(const char *cmd)
|
||||||
{ "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE },
|
{ "query-balloon", ERROR_CLASS_DEVICE_NOT_ACTIVE },
|
||||||
{ "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR },
|
{ "query-hotpluggable-cpus", ERROR_CLASS_GENERIC_ERROR },
|
||||||
{ "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR },
|
{ "query-vm-generation-id", ERROR_CLASS_GENERIC_ERROR },
|
||||||
#ifndef CONFIG_PROFILER
|
|
||||||
{ "x-query-profile", ERROR_CLASS_GENERIC_ERROR },
|
|
||||||
#endif
|
|
||||||
/* Only valid with a USB bus added */
|
/* Only valid with a USB bus added */
|
||||||
{ "x-query-usb", ERROR_CLASS_GENERIC_ERROR },
|
{ "x-query-usb", ERROR_CLASS_GENERIC_ERROR },
|
||||||
/* Only valid with accel=tcg */
|
/* Only valid with accel=tcg */
|
||||||
|
|
Loading…
Reference in a new issue