ruby-changes:40584
From: nobu <ko1@a...>
Date: Thu, 19 Nov 2015 14:12:34 +0900 (JST)
Subject: [ruby-changes:40584] nobu:r52663 (trunk): compile.c: tailcall before specialize
nobu 2015-11-19 14:12:14 +0900 (Thu, 19 Nov 2015) New Revision: 52663 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52663 Log: compile.c: tailcall before specialize * compile.c (iseq_tailcall_optimize): apply tail call optimization before conversion to specialized instructions. when looking back from `leave` instruction, `send` instructions have been translated already. Modified files: trunk/ChangeLog trunk/compile.c Index: ChangeLog =================================================================== --- ChangeLog (revision 52662) +++ ChangeLog (revision 52663) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Nov 19 14:12:12 2015 Nobuyoshi Nakada <nobu@r...> + + * compile.c (iseq_tailcall_optimize): apply tail call optimization + before conversion to specialized instructions. when looking + back from `leave` instruction, `send` instructions have been + translated already. + Thu Nov 19 13:57:58 2015 NAKAMURA Usaku <usa@r...> * win32/win32.c (finish_overlapped_socket): ignore EMSGSIZE when input, Index: compile.c =================================================================== --- compile.c (revision 52662) +++ compile.c (revision 52663) @@ -2100,7 +2100,9 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2100 } } - if (do_tailcallopt && iobj->insn_id == BIN(leave)) { + if (do_tailcallopt && + (iobj->insn_id == BIN(send) || + iobj->insn_id == BIN(invokesuper))) { /* * send ... * leave @@ -2108,13 +2110,29 @@ iseq_peephole_optimize(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2110 * send ..., ... | VM_CALL_TAILCALL, ... * leave # unreachable */ - INSN *piobj = (INSN *)get_prev_insn(iobj); - enum ruby_vminsn_type previ = piobj->insn_id; + INSN *piobj = NULL; + if (iobj->link.next) { + LINK_ELEMENT *next = iobj->link.next; + do { + if (next->type != ISEQ_ELEMENT_INSN) { + next = next->next; + continue; + } + switch (INSN_OF(next)) { + case BIN(nop): + /*case BIN(trace):*/ + next = next->next; + break; + case BIN(leave): + piobj = iobj; + default: + next = NULL; + break; + } + } while (next); + } - if (previ == BIN(send) || previ == BIN(opt_send_without_block) || - previ == BIN(invokesuper) || - previ == BIN(opt_aref) || previ == BIN(opt_aref_with) || - previ == BIN(opt_aset) || previ == BIN(opt_aset_with)) { + if (piobj) { struct rb_call_info *ci = (struct rb_call_info *)piobj->operands[0]; rb_iseq_t *blockiseq = (rb_iseq_t *)piobj->operands[1]; if (blockiseq == 0) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/