diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | compile.c | 27 |
2 files changed, 34 insertions, 0 deletions
@@ -1,3 +1,10 @@ +Wed Nov 18 11:32:15 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * compile.c (iseq_peephole_optimize): eliminate always/never + branches after a literal object. this sequence typically + appears by defined? operator for a method call on a local + variable. + Wed Nov 18 10:33:06 2015 NAKAMURA Usaku <usa@ruby-lang.org> * ext/socket/ancdata.c (bsock_recvmsg_internal): stretch the buffer size @@ -2031,6 +2031,33 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal */ replace_destination(iobj, nobj); } + else if (pobj) { + int cond; + if (pobj->insn_id == BIN(putobject)) { + cond = (iobj->insn_id == BIN(branchif) ? + OPERAND_AT(pobj, 0) != Qfalse : + iobj->insn_id == BIN(branchunless) ? + OPERAND_AT(pobj, 0) == Qfalse : + FALSE); + } + else if (pobj->insn_id == BIN(putstring)) { + cond = iobj->insn_id == BIN(branchif); + } + else if (pobj->insn_id == BIN(putnil)) { + cond = iobj->insn_id != BIN(branchif); + } + else break; + REMOVE_ELEM(&pobj->link); + if (cond) { + iobj->insn_id = BIN(jump); + goto again; + } + else { + unref_destination(iobj); + REMOVE_ELEM(&iobj->link); + } + break; + } else break; nobj = (INSN *)get_destination_insn(nobj); } |