[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]