codegen.c: more peephole optimization.

`a=10; a+=1` to generate:

```
    1 000 OP_LOADI      R1      11              ; R1:a
```

instead of:

```
    1 000 OP_LOADI      R1      10              ; R1:a
    1 003 OP_MOVE       R2      R1              ; R1:a
    1 006 OP_ADDI       R2      1
    1 009 OP_MOVE       R1      R2              ; R1:a
```
This commit is contained in:
Yukihiro "Matz" Matsumoto
2021-08-09 11:25:04 +09:00
parent 52eb2af7d0
commit b1b9b157f8
+21 -2
View File
@@ -575,6 +575,9 @@ genjmp2(codegen_scope *s, mrb_code i, uint16_t a, uint32_t pc, int val)
#define genjmp2_0(s,i,a,val) genjmp2(s,i,a,JMPLINK_START,val)
static mrb_bool get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *ns);
static void gen_int(codegen_scope *s, uint16_t dst, mrb_int i);
static void
gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
{
@@ -622,6 +625,24 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
genop_2SS(s, data.insn, dst, i);
}
break;
case OP_ADDI: case OP_SUBI:
if (nopeep || addr_pc(s, data.addr) == s->lastlabel || data.a != src || data.a < s->nlocals) goto normal;
struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr));
if (data0.insn != OP_MOVE || data0.a != data.a || data0.b != dst) goto normal;
s->pc = addr_pc(s, data0.addr);
/* constant folding */
data0 = mrb_decode_insn(mrb_prev_pc(s, data0.addr));
mrb_int n;
if (data0.a == dst && get_int_operand(s, &data0, &n)) {
if ((data.insn == OP_ADDI && !mrb_int_add_overflow(n, data.b, &n)) ||
(data.insn == OP_SUBI && !mrb_int_sub_overflow(n, data.b, &n))) {
s->pc = addr_pc(s, data0.addr);
gen_int(s, dst, n);
break;
}
}
genop_2(s, data.insn, dst, data.b);
break;
default:
goto normal;
}
@@ -726,8 +747,6 @@ get_int_operand(codegen_scope *s, struct mrb_insn_data *data, mrb_int *n)
}
}
static void gen_int(codegen_scope *s, uint16_t dst, mrb_int i);
static void
gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst)
{