summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-07-31 21:14:54 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-07-31 21:14:54 +0900
commitb1cb6c3c699c52b5c00d27388f22c4a95149b03f (patch)
tree1b0c8bc46c2c5548bfb479f9e19da3ae498523b0 /mrbgems/mruby-compiler
parent43999492a792263eb234db1d399103471c39009c (diff)
downloadmruby-b1cb6c3c699c52b5c00d27388f22c4a95149b03f.tar.gz
mruby-b1cb6c3c699c52b5c00d27388f22c4a95149b03f.zip
codegen.c: allow constant folding for mul / div.
Diffstat (limited to 'mrbgems/mruby-compiler')
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c34
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());