diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-07-31 21:14:54 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-07-31 21:14:54 +0900 |
| commit | b1cb6c3c699c52b5c00d27388f22c4a95149b03f (patch) | |
| tree | 1b0c8bc46c2c5548bfb479f9e19da3ae498523b0 /mrbgems/mruby-compiler/core/codegen.c | |
| parent | 43999492a792263eb234db1d399103471c39009c (diff) | |
| download | mruby-b1cb6c3c699c52b5c00d27388f22c4a95149b03f.tar.gz mruby-b1cb6c3c699c52b5c00d27388f22c4a95149b03f.zip | |
codegen.c: allow constant folding for mul / div.
Diffstat (limited to 'mrbgems/mruby-compiler/core/codegen.c')
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 5a02f2d09..70b95d7e3 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -739,6 +739,36 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) } } +static void +gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) +{ + if (no_peephole(s)) { + normal: + genop_1(s, op, dst); + return; + } + else { + struct mrb_insn_data data = mrb_last_insn(s); + mrb_int n, n0; + if (addr_pc(s, data.addr) == s->lastlabel || !get_int_operand(s, &data, &n)) { + /* not integer immediate */ + goto normal; + } + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + if (!get_int_operand(s, &data0, &n0)) { + goto normal; + } + if (op == OP_MUL) { + if (mrb_int_mul_overflow(n0, n, &n)) goto normal; + } + else { /* OP_DIV */ + n = n0 / n; + } + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + } +} + static uint32_t dispatch(codegen_scope *s, uint32_t pos0) { @@ -1466,10 +1496,10 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) gen_addsub(s, OP_SUB, cursp()); } else if (!noop && sym == MRB_OPSYM_2(s->mrb, mul) && n == 1) { - genop_1(s, OP_MUL, cursp()); + gen_muldiv(s, OP_MUL, cursp()); } else if (!noop && sym == MRB_OPSYM_2(s->mrb, div) && n == 1) { - genop_1(s, OP_DIV, cursp()); + gen_muldiv(s, OP_DIV, cursp()); } else if (!noop && sym == MRB_OPSYM_2(s->mrb, lt) && n == 1) { genop_1(s, OP_LT, cursp()); |
