codegen.c: allow constant folding for mul / div.

This commit is contained in:
Yukihiro "Matz" Matsumoto
2021-07-31 21:14:54 +09:00
parent 43999492a7
commit b1cb6c3c69
+32 -2
View File
@@ -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());