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

ruby-changes:44242

From: nobu <ko1@a...>
Date: Sat, 1 Oct 2016 19:19:42 +0900 (JST)
Subject: [ruby-changes:44242] nobu:r56315 (trunk): compile.c: optimize flip-flop

nobu	2016-10-01 19:19:36 +0900 (Sat, 01 Oct 2016)

  New Revision: 56315

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=56315

  Log:
    compile.c: optimize flip-flop
    
    * compile.c (compile_flip_flop): simplify generated code.
    * compile.c (compile_branch_condition): flip-flop can appear only
      in coditional expressions.

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/test/ruby/test_flip.rb
Index: test/ruby/test_flip.rb
===================================================================
--- test/ruby/test_flip.rb	(revision 56314)
+++ test/ruby/test_flip.rb	(revision 56315)
@@ -3,8 +3,11 @@ require 'test/unit' https://github.com/ruby/ruby/blob/trunk/test/ruby/test_flip.rb#L3
 
 class TestFlip < Test::Unit::TestCase
   def test_flip_flop
+    assert_equal [4,5], (1..9).select {|n| true if (n==4)..(n==5)}
+    assert_equal [4,5], (1..9).select {|n| true if (n==4)...(n==5)}
     assert_equal [2], (1..9).select {|n| true if (n==2)..(n%2).zero?}
     assert_equal [2,3,4], (1..9).select {|n| true if (n==2)...(n%2).zero?}
+    assert_equal [4,5,7,8], (1..9).select {|n| true if (n==4)...(n==5) or (n==7)...(n==8)}
   end
 
   def test_hidden_key
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 56314)
+++ ChangeLog	(revision 56315)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Oct  1 19:19:34 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* compile.c (compile_flip_flop): simplify generated code.
+
+	* compile.c (compile_branch_condition): flip-flop can appear only
+	  in coditional expressions.
+
 Sat Oct  1 02:02:02 2016  NAKAMURA Usaku  <usa@r...>
 
 	* win32/win32.c (poll_child_status): rb_w32_wait_events_blocking() sets
Index: compile.c
===================================================================
--- compile.c	(revision 56314)
+++ compile.c	(revision 56315)
@@ -2787,6 +2787,39 @@ compile_dregx(rb_iseq_t *iseq, LINK_ANCH https://github.com/ruby/ruby/blob/trunk/compile.c#L2787
 }
 
 static int
+compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int again,
+		  LABEL *then_label, LABEL *else_label)
+{
+    const int line = nd_line(node);
+    LABEL *lend = NEW_LABEL(line);
+    rb_num_t cnt = ISEQ_FLIP_CNT_INCREMENT(iseq->body->local_iseq)
+	+ VM_SVAR_FLIPFLOP_START;
+    VALUE key = INT2FIX(cnt);
+
+    ADD_INSN2(ret, line, getspecial, key, INT2FIX(0));
+    ADD_INSNL(ret, line, branchif, lend);
+
+    /* *flip == 0 */
+    COMPILE(ret, "flip2 beg", node->nd_beg);
+    ADD_INSNL(ret, line, branchunless, else_label);
+    ADD_INSN1(ret, line, putobject, Qtrue);
+    ADD_INSN1(ret, line, setspecial, key);
+    if (!again) {
+	ADD_INSNL(ret, line, jump, then_label);
+    }
+
+    /* *flip == 1 */
+    ADD_LABEL(ret, lend);
+    COMPILE(ret, "flip2 end", node->nd_end);
+    ADD_INSNL(ret, line, branchunless, then_label);
+    ADD_INSN1(ret, line, putobject, Qfalse);
+    ADD_INSN1(ret, line, setspecial, key);
+    ADD_INSNL(ret, line, jump, then_label);
+
+    return COMPILE_OK;
+}
+
+static int
 compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * cond,
 			 LABEL *then_label, LABEL *else_label)
 {
@@ -2834,6 +2867,12 @@ compile_branch_condition(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L2867
 	/* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
 	ADD_INSNL(ret, nd_line(cond), jump, else_label);
 	break;
+      case NODE_FLIP2:
+	compile_flip_flop(iseq, ret, cond, TRUE, then_label, else_label);
+	break;
+      case NODE_FLIP3:
+	compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label);
+	break;
       default:
 	COMPILE(ret, "branch condition", cond);
 	ADD_INSNL(ret, nd_line(cond), branchunless, else_label);
@@ -5896,47 +5935,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5935
 	}
 	break;
       }
-      case NODE_FLIP2:
-      case NODE_FLIP3:{
-	LABEL *lend = NEW_LABEL(line);
-	LABEL *lfin = NEW_LABEL(line);
-	LABEL *ltrue = NEW_LABEL(line);
-	rb_iseq_t *local_iseq = iseq->body->local_iseq;
-	rb_num_t cnt;
-	VALUE key;
-
-	cnt = ISEQ_FLIP_CNT_INCREMENT(local_iseq) + VM_SVAR_FLIPFLOP_START;
-	key = INT2FIX(cnt);
-
-	ADD_INSN2(ret, line, getspecial, key, INT2FIX(0));
-	ADD_INSNL(ret, line, branchif, lend);
-
-	/* *flip == 0 */
-	COMPILE(ret, "flip2 beg", node->nd_beg);
-	ADD_INSN(ret, line, dup);
-	ADD_INSNL(ret, line, branchunless, lfin);
-	if (nd_type(node) == NODE_FLIP3) {
-	    ADD_INSN(ret, line, dup);
-	    ADD_INSN1(ret, line, setspecial, key);
-	    ADD_INSNL(ret, line, jump, lfin);
-	}
-	else {
-	    ADD_INSN1(ret, line, setspecial, key);
-	}
-
-	/* *flip == 1 */
-	ADD_LABEL(ret, lend);
-	COMPILE(ret, "flip2 end", node->nd_end);
-	ADD_INSNL(ret, line, branchunless, ltrue);
-	ADD_INSN1(ret, line, putobject, Qfalse);
-	ADD_INSN1(ret, line, setspecial, key);
-
-	ADD_LABEL(ret, ltrue);
-	ADD_INSN1(ret, line, putobject, Qtrue);
-
-	ADD_LABEL(ret, lfin);
-	break;
-      }
       case NODE_SELF:{
 	if (!poped) {
 	    ADD_INSN(ret, line, putself);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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