diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-08-09 11:25:04 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-08-11 10:48:18 +0900 |
| commit | b1b9b157f85fe371db706e0c11024681d84e4aba (patch) | |
| tree | af652bb95da9231b44887d1336604f694fae030e | |
| parent | 52eb2af7d05c9fe9aa1447c83ae2520bcc3966c6 (diff) | |
| download | mruby-b1b9b157f85fe371db706e0c11024681d84e4aba.tar.gz mruby-b1b9b157f85fe371db706e0c11024681d84e4aba.zip | |
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
```
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index a3a73fafa..b49db0e31 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -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) { |
