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

ruby-changes:51143

From: k0kubun <ko1@a...>
Date: Tue, 8 May 2018 01:17:04 +0900 (JST)
Subject: [ruby-changes:51143] k0kubun:r63350 (trunk): _mjit_compile_send.erb: inline recursive call

k0kubun	2018-05-08 01:16:59 +0900 (Tue, 08 May 2018)

  New Revision: 63350

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

  Log:
    _mjit_compile_send.erb: inline recursive call
    
    mjit_compile.c: propagate funcname to compile_insn
    
    test_jit.rb: add test covering this behavior
    
    * Benchmark
    
    ```
    require 'benchmark_driver'
    
    Benchmark.driver(runner: :time, repeat_count: 4) do |x|
      x.prelude %{
        def fib(x)
          return x if x == 0 || x == 1
          fib(x-1) + fib(x-2)
        end
      }
      x.report 'fib(40)'
      x.loop_count 1
    
      x.rbenv(
        'before,--jit',
        'before',
        'after,--jit',
        'after',
      )
      x.verbose
    end
    ```
    
    ```
    before,--jit: ruby 2.6.0dev (2018-05-08 trunk 63349) +JIT [x86_64-linux]
    before: ruby 2.6.0dev (2018-05-08 trunk 63349) [x86_64-linux]
    after,--jit: ruby 2.6.0dev (2018-05-08 trunk 63349) +JIT [x86_64-linux]
    last_commit=_mjit_compile_send.erb: inline recursive call
    after: ruby 2.6.0dev (2018-05-08 trunk 63349) [x86_64-linux]
    last_commit=_mjit_compile_send.erb: inline recursive call
    Calculating -------------------------------------
                         before,--jit      before  after,--jit       after
                 fib(40)        2.886       8.685        2.562       8.800 s -       1.000 times
    
    Comparison:
                              fib(40)
             after,--jit:         2.6 s
            before,--jit:         2.9 s - 1.13x  slower
                  before:         8.7 s - 3.39x  slower
                   after:         8.8 s - 3.44x  slower
    
    ```

  Modified files:
    trunk/mjit_compile.c
    trunk/test/ruby/test_jit.rb
    trunk/tool/ruby_vm/views/_mjit_compile_send.erb
Index: mjit_compile.c
===================================================================
--- mjit_compile.c	(revision 63349)
+++ mjit_compile.c	(revision 63350)
@@ -27,6 +27,7 @@ struct compile_status { https://github.com/ruby/ruby/blob/trunk/mjit_compile.c#L27
     /* If TRUE, JIT-ed code will use local variables to store pushed values instead of
        using VM's stack and moving stack pointer. */
     int local_stack_p;
+    const char *funcname; /* the method name which is being compiled */
 };
 
 /* Storage to keep data which is consistent in each conditional branch.
@@ -193,6 +194,7 @@ mjit_compile(FILE *f, const struct rb_is https://github.com/ruby/ruby/blob/trunk/mjit_compile.c#L194
     status.success = TRUE;
     status.local_stack_p = !body->catch_except_p;
     status.stack_size_for_pos = ALLOC_N(int, body->iseq_size);
+    status.funcname = funcname;
     memset(status.stack_size_for_pos, NOT_COMPILED_STACK_SIZE, sizeof(int) * body->iseq_size);
 
     /* For performance, we verify stack size only on compilation time (mjit_compile.inc.erb) without --jit-debug */
Index: tool/ruby_vm/views/_mjit_compile_send.erb
===================================================================
--- tool/ruby_vm/views/_mjit_compile_send.erb	(revision 63349)
+++ tool/ruby_vm/views/_mjit_compile_send.erb	(revision 63350)
@@ -58,6 +58,9 @@ https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_mjit_compile_send.erb#L58
                 fprintf(f, "            VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n");
                 fprintf(f, "            v = vm_exec(ec, TRUE);\n");
             }
+            else if (body == iseq->body) { /* inline recursive call */
+                fprintf(f, "            v = %s(ec, ec->cfp);\n", status->funcname);
+            }
             else {
                 fprintf(f, "            if ((v = mjit_exec(ec)) == Qundef) {\n");
                 fprintf(f, "                VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"); /* This is vm_call0_body's code after vm_call_iseq_setup */
Index: test/ruby/test_jit.rb
===================================================================
--- test/ruby/test_jit.rb	(revision 63349)
+++ test/ruby/test_jit.rb	(revision 63350)
@@ -322,6 +322,16 @@ class TestJIT < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_jit.rb#L322
 
   def test_compile_insn_opt_send_without_block
     assert_compile_once('print', result_inspect: 'nil', insns: %i[opt_send_without_block])
+
+    # recursive inline
+    assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '120', success_count: 1, min_calls: 2)
+    begin;
+      def fact(i)
+        return i if i <= 1
+        i * fact(i - 1)
+      end
+      print fact(5)
+    end;
   end
 
   def test_compile_insn_invokesuper

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

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