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 *(*assemble_code)(struct jit_backend *base, struct ir *ir, int *size);
void (*dump_code)(struct jit_backend *base, const uint8_t *host_addr,
int size);
void (*disassemble_code)(struct jit_backend *base, const uint8_t *code,
int size, int dump, int *num_instrs);
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;
}
static void x64_backend_dump_code(struct jit_backend *base,
const uint8_t *host_addr, int size) {
static void x64_backend_disassemble_code(struct jit_backend *base,
const uint8_t *code, int size,
int dump, int *num_instrs) {
struct x64_backend *backend = container_of(base, struct x64_backend, base);
cs_insn *insns;
size_t count =
cs_disasm(backend->capstone_handle, host_addr, size, 0, 0, &insns);
size_t count = cs_disasm(backend->capstone_handle, code, size, 0, 0, &insns);
CHECK(count);
*num_instrs = count;
for (size_t i = 0; i < count; i++) {
cs_insn &insn = insns[i];
LOG_INFO("0x%" PRIx64 ":\t%s\t\t%s", insn.address, insn.mnemonic,
insn.op_str);
if (dump) {
for (size_t i = 0; i < count; i++) {
cs_insn &insn = insns[i];
LOG_INFO("0x%" PRIx64 ":\t%s\t\t%s", insn.address, insn.mnemonic,
insn.op_str);
}
}
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.reset = &x64_backend_reset;
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->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);
}
static void armv3_frontend_dump_code(struct jit_frontend *base, uint32_t addr,
int size) {
static void armv3_frontend_disassemble_code(struct jit_frontend *base,
uint32_t addr, int size) {
struct armv3_frontend *frontend = (struct armv3_frontend *)base;
struct jit_guest *guest = frontend->jit->guest;
@ -33,7 +33,7 @@ struct jit_frontend *armv3_frontend_create(struct jit *jit) {
frontend->jit = jit;
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;
}

View File

@ -11,7 +11,7 @@ struct jit_frontend {
struct jit *jit;
void (*translate_code)(struct jit_frontend *base, uint32_t addr,
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

View File

@ -18,8 +18,8 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
PROF_LEAVE();
}
static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr,
int size) {
static void sh4_frontend_disassemble_code(struct jit_frontend *base,
uint32_t addr, int size) {
struct sh4_frontend *frontend = (struct sh4_frontend *)base;
struct jit_guest *guest = frontend->jit->guest;
@ -57,7 +57,7 @@ struct jit_frontend *sh4_frontend_create(struct jit *jit) {
frontend->jit = jit;
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;
}

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(print_after_all, 1, "Print IR after each pass");
DEFINE_STAT(frontend_size, "Frontend code size");
DEFINE_STAT(backend_size, "Backend code size");
DEFINE_STAT(num_instrs, "Total instructions");
DEFINE_STAT(num_instrs_removed, "Total instructions removed");
DEFINE_STAT(guest_instrs, "Guest instructions");
DEFINE_STAT(host_instrs, "Host instructions");
DEFINE_STAT(ir_instrs, "IR instructions");
DEFINE_STAT(ir_instrs_removed, "IR instructions removed");
static uint8_t ir_buffer[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,
int disable_ir_dump) {
int disable_dumps) {
struct ir ir = {0};
ir.buffer = ir_buffer;
ir.capacity = sizeof(ir_buffer);
@ -52,11 +52,11 @@ static void process_file(struct jit *jit, const char *filename,
fclose(input);
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) {
if (instr->op == OP_DEBUG_INFO) {
struct ir_value *data = instr->arg[1];
STAT_frontend_size += ir_type_size(data->type);
guest_num_instrs++;
}
}
@ -83,7 +83,7 @@ static void process_file(struct jit *jit, const char *filename,
}
/* 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("IR after %s", name);
LOG_INFO("===-----------------------------------------------------===");
@ -97,17 +97,34 @@ static void process_file(struct jit *jit, const char *filename,
int num_instrs_after = get_num_instrs(&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);
}
STAT_num_instrs += num_instrs_before;
STAT_num_instrs_removed += num_instrs_before - num_instrs_after;
/* assemble backend code */
int backend_size = 0;
uint8_t *addr = jit->backend->assemble_code(jit->backend, &ir, &backend_size);
STAT_backend_size += backend_size;
int host_size = 0;
int host_num_instrs = 0;
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) {