From 188c150f44bd28ab0e4a91d58e6156952aef9904 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 2 Aug 2021 07:34:54 +0900 Subject: codegen.c: constant folding binary operators, <<, >>, %, &, |, ^. --- mrbgems/mruby-compiler/core/codegen.c | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 7d0b51740..4c1fa257c 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -798,6 +798,63 @@ gen_muldiv(codegen_scope *s, uint8_t op, uint16_t dst) } } +static mrb_bool +gen_binop(codegen_scope *s, mrb_sym op, uint16_t dst) +{ + if (no_peephole(s)) return FALSE; + 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 */ + return FALSE; + } + struct mrb_insn_data data0 = mrb_decode_insn(mrb_prev_pc(s, data.addr)); + if (!get_int_operand(s, &data0, &n0)) { + return FALSE; + } + if (op == MRB_OPSYM_2(s->mrb, lshift)) { + if (n < 0) { + if (-63 > n || -n >= sizeof(mrb_int)*8) return FALSE; + n = n0 >> (-n); + } + else { + if (n >= sizeof(mrb_int)*8-1) return FALSE; + n = n0 << n; + } + } + else if (op == MRB_OPSYM_2(s->mrb, rshift)) { + if (n < 0) { + if (-63 > n || -n > sizeof(mrb_int)*8-1) return FALSE; + n = n0 << (-n); + } + else { + if (n >= sizeof(mrb_int)*8-1) return FALSE; + n = n0 >> n; + } + } + else if (op == MRB_OPSYM_2(s->mrb, mod)) { + if (n0 < 0 || n < 0) return FALSE; + n = n0 % n; + } + else if (op == MRB_OPSYM_2(s->mrb, and)) { + n = n0 & n; + } + else if (op == MRB_OPSYM_2(s->mrb, or)) { + n = n0 | n; + } + else if (op == MRB_OPSYM_2(s->mrb, xor)) { + n = n0 ^ n; + } + else { + return FALSE; + } + s->pc = addr_pc(s, data0.addr); + gen_int(s, dst, n); + return TRUE; + } +} + static uint32_t dispatch(codegen_scope *s, uint32_t pos0) { @@ -1551,6 +1608,9 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) sym == MRB_OPSYM_2(s->mrb, neg))) { gen_uniop(s, sym, cursp()); } + else if (!noop && n == 1 && gen_binop(s, sym, cursp())) { + /* constant folding succeeded */ + } else { int idx = new_sym(s, sym); -- cgit v1.2.3