codegen.c: add new peephole optimization for `OP_GETUPVAR`.

When `OP_GETUPVAR` is generated right after `OP_SETUPVAR`, there is no
need to read the upvar back to the register, e.g.

    3 008 OP_ADDI       R2      1
    3 011 OP_SETUPVAR   R2      1       0
    4 015 OP_GETUPVAR   R2      1       0
    4 019 OP_LOADI_2    R3

`OP_GETUPVAR` at the address `015` is useless. We can skip it like:

    3 008 OP_ADDI       R2      1
    3 011 OP_SETUPVAR   R2      1      0
    4 015 OP_LOADI_2    R3
parent d4abbf1b
......@@ -494,6 +494,22 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
}
}
static int search_upvar(codegen_scope *s, mrb_sym id, int *idx);
static void
gen_getupvar(codegen_scope *s, uint16_t dst, mrb_sym id)
{
int idx;
int lv = search_upvar(s, id, &idx);
struct mrb_insn_data data = mrb_last_insn(s);
if (!no_peephole(s) && data.insn == OP_SETUPVAR && data.a == dst && data.b == idx && data.c == lv) {
/* skip GETUPVAR right after SETUPVAR */
return;
}
genop_3(s, OP_GETUPVAR, dst, idx, lv);
}
static void
gen_return(codegen_scope *s, uint8_t op, uint16_t src)
{
......@@ -966,8 +982,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
gen_move(s, idx, cursp(), 0);
}
else {
int lv = search_upvar(s, id, &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
gen_getupvar(s, cursp(), id);
}
i++;
opt = opt->cdr;
......@@ -1005,8 +1020,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
gen_move(s, idx, cursp(), 0);
}
else {
int lv = search_upvar(s, kwd_sym, &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
gen_getupvar(s, cursp(), kwd_sym);
}
jmp_def_set = genjmp_0(s, OP_JMP);
dispatch(s, jmpif_key_p);
......@@ -2461,8 +2475,7 @@ codegen(codegen_scope *s, node *tree, int val)
gen_move(s, cursp(), idx, val);
}
else {
int lv = search_upvar(s, nsym(tree), &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
gen_getupvar(s, cursp(), nsym(tree));
}
push();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment