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/