mirror of https://github.com/inolen/redream.git
measure number of guest and host instructions in recc
This commit is contained in:
parent
162bfce38f
commit
c783d617a2
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue