mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user