From 416aafa85d493d1add1e80da99b698c5cb496a33 Mon Sep 17 00:00:00 2001 From: qwe661234 Date: Mon, 12 Dec 2022 20:38:06 +0800 Subject: [PATCH] Use TCO to accelerate funciton emulate We need to refactor the function emulate to a recursive version for meeting the requirement of tail-call optimization(TCO). To achieve this, I add a variable is_tail to the struct rv_insn_t to help us determine whether the basic block is terminate or not. As a result, we can use this variable to rewrite function emulate into a self-recursive function. Running coremark and dhrystone benchmark now produces faster results than it did previously. --- src/decode.h | 1 + src/emulate.c | 28 +++++----------------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/decode.h b/src/decode.h index 63f134944..b5022c1f6 100644 --- a/src/decode.h +++ b/src/decode.h @@ -240,6 +240,7 @@ typedef struct { /* instruction length */ uint8_t insn_len; + uint8_t is_tail; } rv_insn_t; /* translated basic block */ diff --git a/src/emulate.c b/src/emulate.c index 995e3b6f1..99d37a8ba 100644 --- a/src/emulate.c +++ b/src/emulate.c @@ -1147,7 +1147,9 @@ static bool emulate(riscv_t *rv, const rv_insn_t *ir) /* step over instruction */ rv->PC += ir->insn_len; - return true; + if(ir->is_tail) + return true; + return emulate(rv, ir + 1); } static bool insn_is_branch(uint8_t opcode) @@ -1240,27 +1242,6 @@ static block_t *block_find(const block_map_t *map, const uint32_t addr) return NULL; } -/* execute a basic block */ -static bool block_emulate(riscv_t *rv, const block_t *block) -{ - const uint32_t n_insn = block->n_insn; - const rv_insn_t *ir = block->ir; - - /* execute the block */ - for (uint32_t i = 0; i < n_insn; i++) { - /* enforce zero register */ - rv->X[rv_reg_zero] = 0; - - /* execute the instruction */ - if (!emulate(rv, ir + i)) - return false; - - /* increment the cycles csr */ - rv->csr_cycle++; - } - return true; -} - static void block_translate(riscv_t *rv, block_t *block) { block->pc_start = block->pc_end = rv->PC; @@ -1288,6 +1269,7 @@ static void block_translate(riscv_t *rv, block_t *block) if (insn_is_branch(ir->opcode)) break; } + (block->ir + block->n_insn - 1)->is_tail = true; } static block_t *block_find_or_translate(riscv_t *rv, block_t *prev) @@ -1350,7 +1332,7 @@ void rv_step(riscv_t *rv, int32_t cycles) assert(block); /* execute the block */ - if (!block_emulate(rv, block)) + if (!emulate(rv, block->ir)) break; prev = block;