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

ruby-changes:68962

From: John <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:28 +0900 (JST)
Subject: [ruby-changes:68962] 67c2cdc59a (master): Implement gen_getlocal

https://git.ruby-lang.org/ruby.git/commit/?id=67c2cdc59a

From 67c2cdc59a5fc8a82804c72a30a2d23ba36f2366 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Tue, 8 Jun 2021 07:52:57 -0700
Subject: Implement gen_getlocal

This extracts the generation code from getlocal_wc1, since this is the
same just with more loops inside vm_get_ep.
---
 bootstraptest/test_yjit.rb | 14 ++++++++++++++
 yjit_codegen.c             | 33 ++++++++++++++++++++++++---------
 2 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 5bf415889e..51c82b55b5 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1021,3 +1021,17 @@ assert_equal 'foo123', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1021
   make_str("foo", 123)
   make_str("foo", 123)
 }
+
+# getlocal with 2 levels
+assert_equal '7', %q{
+  def foo(foo, bar)
+    while foo > 0
+      while bar > 0
+        return foo + bar
+      end
+    end
+  end
+
+  foo(5,2)
+  foo(5,2)
+}
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 87c5b12043..4870911404 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -787,22 +787,21 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L787
 }
 
 static codegen_status_t
-gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
+gen_getlocal_generic(ctx_t* ctx, uint32_t local_idx, uint32_t level)
 {
-    //fprintf(stderr, "gen_getlocal_wc1\n");
-
     // Load environment pointer EP from CFP
     mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep));
 
-    // Get the previous EP from the current EP
-    // See GET_PREV_EP(ep) macro
-    // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
-    mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL));
-    and(cb, REG0, imm_opnd(~0x03));
+    while (level--) {
+        // Get the previous EP from the current EP
+        // See GET_PREV_EP(ep) macro
+        // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03))
+        mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL));
+        and(cb, REG0, imm_opnd(~0x03));
+    }
 
     // Load the local from the block
     // val = *(vm_get_ep(GET_EP(), level) - idx);
-    int32_t local_idx = (int32_t)jit_get_arg(jit, 0);
     const int32_t offs = -(SIZEOF_VALUE * local_idx);
     mov(cb, REG0, mem_opnd(64, REG0, offs));
 
@@ -813,6 +812,21 @@ gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L812
     return YJIT_KEEP_COMPILING;
 }
 
+static codegen_status_t
+gen_getlocal(jitstate_t* jit, ctx_t* ctx)
+{
+    int32_t idx = (int32_t)jit_get_arg(jit, 0);
+    int32_t level = (int32_t)jit_get_arg(jit, 1);
+    return gen_getlocal_generic(ctx, idx, level);
+}
+
+static codegen_status_t
+gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx)
+{
+    int32_t idx = (int32_t)jit_get_arg(jit, 0);
+    return gen_getlocal_generic(ctx, idx, 1);
+}
+
 static codegen_status_t
 gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx)
 {
@@ -3067,6 +3081,7 @@ yjit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L3081
     yjit_reg_op(BIN(putobject_INT2FIX_0_), gen_putobject_int2fix);
     yjit_reg_op(BIN(putobject_INT2FIX_1_), gen_putobject_int2fix);
     yjit_reg_op(BIN(putself), gen_putself);
+    yjit_reg_op(BIN(getlocal), gen_getlocal);
     yjit_reg_op(BIN(getlocal_WC_0), gen_getlocal_wc0);
     yjit_reg_op(BIN(getlocal_WC_1), gen_getlocal_wc1);
     yjit_reg_op(BIN(setlocal_WC_0), gen_setlocal_wc0);
-- 
cgit v1.2.1


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

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