codegen.c: peephole optimize OP_JMPxxx.
@@ -524,10 +524,39 @@ genjmp2(codegen_scope *s, mrb_code i, uint16_t a, uint32_t pc, int val)
if (!no_peephole(s) && !val) {
struct mrb_insn_data data = mrb_last_insn(s);
- if (data.insn == OP_MOVE && data.a == a) {
+ switch (data.insn) {
+ case OP_MOVE:
+ if (data.a == a && data.a > s->nlocals) {
rewind_pc(s);
a = data.b;
}
+ break;
+ case OP_LOADNIL:
+ case OP_LOADF:
+ if (data.a == a || data.a > s->nlocals) {
+ s->pc = addr_pc(s, data.addr);
+ if (i == OP_JMPNOT || (i == OP_JMPNIL && data.insn == OP_LOADNIL)) {
+ return genjmp(s, OP_JMP, pc);
+ }
+ else { /* OP_JMPIF */
+ return JMPLINK_START;
+ }
+ }
+ break;
+ case OP_LOADT: case OP_LOADI: case OP_LOADINEG: case OP_LOADI__1:
+ case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3:
+ case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7:
+ if (data.a == a || data.a > s->nlocals) {
+ s->pc = addr_pc(s, data.addr);
+ if (i == OP_JMPIF) {
+ return genjmp(s, OP_JMP, pc);
+ }
+ else { /* OP_JMPNOT and OP_JMPNIL */
+ return JMPLINK_START;
+ }
+ }
+ break;
+ }
}
if (a > 0xff) {
