Skip to content

Commit

Permalink
Use TCO to accelerate funciton emulate
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
qwe661234 committed Dec 12, 2022
1 parent 285a988 commit 416aafa
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ typedef struct {

/* instruction length */
uint8_t insn_len;
uint8_t is_tail;
} rv_insn_t;

/* translated basic block */
Expand Down
28 changes: 5 additions & 23 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 416aafa

Please sign in to comment.