measure number of guest and host instructions in recc

This commit is contained in:
Anthony Pesch 2016-12-15 22:57:34 -08:00
parent 162bfce38f
commit c783d617a2
6 changed files with 55 additions and 34 deletions

View File

@ -22,8 +22,9 @@ struct jit_backend {
void (*reset)(struct jit_backend *base); void (*reset)(struct jit_backend *base);
void *(*assemble_code)(struct jit_backend *base, struct ir *ir, int *size); void *(*assemble_code)(struct jit_backend *base, struct ir *ir, int *size);
void (*dump_code)(struct jit_backend *base, const uint8_t *host_addr, void (*disassemble_code)(struct jit_backend *base, const uint8_t *code,
int size); int size, int dump, int *num_instrs);
int (*handle_exception)(struct jit_backend *base, struct exception *ex); int (*handle_exception)(struct jit_backend *base, struct exception *ex);
}; };

View File

@ -392,19 +392,22 @@ static void *x64_backend_assemble_code(struct jit_backend *base, struct ir *ir,
return fn; return fn;
} }
static void x64_backend_dump_code(struct jit_backend *base, static void x64_backend_disassemble_code(struct jit_backend *base,
const uint8_t *host_addr, int size) { const uint8_t *code, int size,
int dump, int *num_instrs) {
struct x64_backend *backend = container_of(base, struct x64_backend, base); struct x64_backend *backend = container_of(base, struct x64_backend, base);
cs_insn *insns; cs_insn *insns;
size_t count = size_t count = cs_disasm(backend->capstone_handle, code, size, 0, 0, &insns);
cs_disasm(backend->capstone_handle, host_addr, size, 0, 0, &insns);
CHECK(count); CHECK(count);
*num_instrs = count;
for (size_t i = 0; i < count; i++) { if (dump) {
cs_insn &insn = insns[i]; for (size_t i = 0; i < count; i++) {
LOG_INFO("0x%" PRIx64 ":\t%s\t\t%s", insn.address, insn.mnemonic, cs_insn &insn = insns[i];
insn.op_str); LOG_INFO("0x%" PRIx64 ":\t%s\t\t%s", insn.address, insn.mnemonic,
insn.op_str);
}
} }
cs_free(insns, count); cs_free(insns, count);
@ -1631,7 +1634,7 @@ struct jit_backend *x64_backend_create(struct jit *jit, void *code,
backend->base.num_registers = array_size(x64_registers); backend->base.num_registers = array_size(x64_registers);
backend->base.reset = &x64_backend_reset; backend->base.reset = &x64_backend_reset;
backend->base.assemble_code = &x64_backend_assemble_code; backend->base.assemble_code = &x64_backend_assemble_code;
backend->base.dump_code = &x64_backend_dump_code; backend->base.disassemble_code = &x64_backend_disassemble_code;
backend->base.handle_exception = &x64_backend_handle_exception; backend->base.handle_exception = &x64_backend_handle_exception;
backend->code = code; backend->code = code;

View File

@ -11,8 +11,8 @@ static void armv3_frontend_translate_code(struct jit_frontend *base,
frontend->translate(frontend->data, addr, ir, flags); frontend->translate(frontend->data, addr, ir, flags);
} }
static void armv3_frontend_dump_code(struct jit_frontend *base, uint32_t addr, static void armv3_frontend_disassemble_code(struct jit_frontend *base,
int size) { uint32_t addr, int size) {
struct armv3_frontend *frontend = (struct armv3_frontend *)base; struct armv3_frontend *frontend = (struct armv3_frontend *)base;
struct jit_guest *guest = frontend->jit->guest; struct jit_guest *guest = frontend->jit->guest;
@ -33,7 +33,7 @@ struct jit_frontend *armv3_frontend_create(struct jit *jit) {
frontend->jit = jit; frontend->jit = jit;
frontend->translate_code = &armv3_frontend_translate_code; frontend->translate_code = &armv3_frontend_translate_code;
frontend->dump_code = &armv3_frontend_dump_code; frontend->disassemble_code = &armv3_frontend_disassemble_code;
return (struct jit_frontend *)frontend; return (struct jit_frontend *)frontend;
} }

View File

@ -11,7 +11,7 @@ struct jit_frontend {
struct jit *jit; struct jit *jit;
void (*translate_code)(struct jit_frontend *base, uint32_t addr, void (*translate_code)(struct jit_frontend *base, uint32_t addr,
struct ir *ir, int fastmem, int *size); struct ir *ir, int fastmem, int *size);
void (*dump_code)(struct jit_frontend *base, uint32_t addr, int size); void (*disassemble_code)(struct jit_frontend *base, uint32_t addr, int size);
}; };
#endif #endif

View File

@ -18,8 +18,8 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
PROF_LEAVE(); PROF_LEAVE();
} }
static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr, static void sh4_frontend_disassemble_code(struct jit_frontend *base,
int size) { uint32_t addr, int size) {
struct sh4_frontend *frontend = (struct sh4_frontend *)base; struct sh4_frontend *frontend = (struct sh4_frontend *)base;
struct jit_guest *guest = frontend->jit->guest; struct jit_guest *guest = frontend->jit->guest;
@ -57,7 +57,7 @@ struct jit_frontend *sh4_frontend_create(struct jit *jit) {
frontend->jit = jit; frontend->jit = jit;
frontend->translate_code = &sh4_frontend_translate_code; frontend->translate_code = &sh4_frontend_translate_code;
frontend->dump_code = &sh4_frontend_dump_code; frontend->disassemble_code = &sh4_frontend_disassemble_code;
return (struct jit_frontend *)frontend; return (struct jit_frontend *)frontend;
} }

View File

@ -18,10 +18,10 @@ DEFINE_OPTION_STRING(pass, "lse,cve,esimp,dce,ra",
DEFINE_OPTION_INT(stats, 1, "Print pass stats"); DEFINE_OPTION_INT(stats, 1, "Print pass stats");
DEFINE_OPTION_INT(print_after_all, 1, "Print IR after each pass"); DEFINE_OPTION_INT(print_after_all, 1, "Print IR after each pass");
DEFINE_STAT(frontend_size, "Frontend code size"); DEFINE_STAT(guest_instrs, "Guest instructions");
DEFINE_STAT(backend_size, "Backend code size"); DEFINE_STAT(host_instrs, "Host instructions");
DEFINE_STAT(num_instrs, "Total instructions"); DEFINE_STAT(ir_instrs, "IR instructions");
DEFINE_STAT(num_instrs_removed, "Total instructions removed"); DEFINE_STAT(ir_instrs_removed, "IR instructions removed");
static uint8_t ir_buffer[1024 * 1024]; static uint8_t ir_buffer[1024 * 1024];
static uint8_t code[1024 * 1024]; static uint8_t code[1024 * 1024];
@ -40,7 +40,7 @@ static int get_num_instrs(const struct ir *ir) {
} }
static void process_file(struct jit *jit, const char *filename, static void process_file(struct jit *jit, const char *filename,
int disable_ir_dump) { int disable_dumps) {
struct ir ir = {0}; struct ir ir = {0};
ir.buffer = ir_buffer; ir.buffer = ir_buffer;
ir.capacity = sizeof(ir_buffer); ir.capacity = sizeof(ir_buffer);
@ -52,11 +52,11 @@ static void process_file(struct jit *jit, const char *filename,
fclose(input); fclose(input);
CHECK(r); CHECK(r);
/* calculate frontend input size */ /* calculate number of guest instructions */
int guest_num_instrs = 0;
list_for_each_entry(instr, &ir.instrs, struct ir_instr, it) { list_for_each_entry(instr, &ir.instrs, struct ir_instr, it) {
if (instr->op == OP_DEBUG_INFO) { if (instr->op == OP_DEBUG_INFO) {
struct ir_value *data = instr->arg[1]; guest_num_instrs++;
STAT_frontend_size += ir_type_size(data->type);
} }
} }
@ -83,7 +83,7 @@ static void process_file(struct jit *jit, const char *filename,
} }
/* print ir after each pass if requested */ /* print ir after each pass if requested */
if (!disable_ir_dump && OPTION_print_after_all) { if (!disable_dumps && OPTION_print_after_all) {
LOG_INFO("===-----------------------------------------------------==="); LOG_INFO("===-----------------------------------------------------===");
LOG_INFO("IR after %s", name); LOG_INFO("IR after %s", name);
LOG_INFO("===-----------------------------------------------------==="); LOG_INFO("===-----------------------------------------------------===");
@ -97,17 +97,34 @@ static void process_file(struct jit *jit, const char *filename,
int num_instrs_after = get_num_instrs(&ir); int num_instrs_after = get_num_instrs(&ir);
/* print out the final ir */ /* print out the final ir */
if (!disable_ir_dump && !OPTION_print_after_all) { if (!disable_dumps && !OPTION_print_after_all) {
ir_write(&ir, stdout); ir_write(&ir, stdout);
} }
STAT_num_instrs += num_instrs_before;
STAT_num_instrs_removed += num_instrs_before - num_instrs_after;
/* assemble backend code */ /* assemble backend code */
int backend_size = 0; int host_size = 0;
uint8_t *addr = jit->backend->assemble_code(jit->backend, &ir, &backend_size); int host_num_instrs = 0;
STAT_backend_size += backend_size; uint8_t *host_code = NULL;
jit->backend->reset(jit->backend);
host_code = jit->backend->assemble_code(jit->backend, &ir, &host_size);
if (!disable_dumps) {
LOG_INFO("===-----------------------------------------------------===");
LOG_INFO("X64 code");
LOG_INFO("===-----------------------------------------------------===");
jit->backend->disassemble_code(jit->backend, host_code, host_size, 1,
&host_num_instrs);
} else {
jit->backend->disassemble_code(jit->backend, host_code, host_size, 0,
&host_num_instrs);
}
/* update stats */
STAT_guest_instrs += guest_num_instrs;
STAT_host_instrs += host_num_instrs;
STAT_ir_instrs += num_instrs_before;
STAT_ir_instrs_removed += num_instrs_before - num_instrs_after;
} }
static void process_dir(struct jit *jit, const char *path) { static void process_dir(struct jit *jit, const char *path) {