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

ruby-changes:68942

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:19:24 +0900 (JST)
Subject: [ruby-changes:68942] f6e3f75c2b (master): Introduce concept of YJIT instruction operands

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

From f6e3f75c2b7503eb89f517c57ac4ea97dc2752b4 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Thu, 8 Apr 2021 16:40:08 -0400
Subject: Introduce concept of YJIT instruction operands

---
 yjit_codegen.c | 30 +++++++++++++-------------
 yjit_core.c    | 33 +++++++++++++++++------------
 yjit_core.h    | 66 ++++++++++++++++++++++++++++++++++------------------------
 3 files changed, 74 insertions(+), 55 deletions(-)

diff --git a/yjit_codegen.c b/yjit_codegen.c
index ce9e56a157..5b759f6c6f 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -406,7 +406,7 @@ static codegen_status_t https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L406
 gen_dup(jitstate_t* jit, ctx_t* ctx)
 {
     // Get the top value and its type
-    val_type_t dup_type = ctx_get_temp_type(ctx, 0);
+    val_type_t dup_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t dup_val = ctx_stack_pop(ctx, 0);
 
     // Push the same value on top
@@ -596,7 +596,7 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L596
     // for dealing with how blocks/closures can affect local types
     //
     // Set the type of the local variable in the context
-    //val_type_t temp_type = ctx_get_temp_type(ctx, 0);
+    //val_type_t temp_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     //ctx_set_local_type(ctx, local_idx, temp_type);
 
     // Pop the value to write from the stack
@@ -912,9 +912,9 @@ gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L912
     }
 
     // Get the operands and destination from the stack
-    val_type_t arg1_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg1_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
-    val_type_t arg0_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg0_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
     // If not fixnums, fall back
@@ -1122,9 +1122,9 @@ gen_opt_and(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1122
     }
 
     // Get the operands and destination from the stack
-    val_type_t arg1_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg1_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
-    val_type_t arg0_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg0_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
     // If not fixnums, fall back
@@ -1160,9 +1160,9 @@ gen_opt_minus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1160
     }
 
     // Get the operands and destination from the stack
-    val_type_t arg1_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg1_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
-    val_type_t arg0_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg0_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
     // If not fixnums, fall back
@@ -1200,9 +1200,9 @@ gen_opt_plus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1200
     }
 
     // Get the operands and destination from the stack
-    val_type_t arg1_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg1_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
-    val_type_t arg0_type = ctx_get_temp_type(ctx, 0);
+    val_type_t arg0_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
     // If not fixnums, fall back
@@ -1360,7 +1360,7 @@ Guard that a stack operand has the same class as known_klass. https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1360
 Recompile as contingency if possible, or take side exit a last resort.
 */
 static bool
-jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, uint32_t stack_idx, const int max_chain_depth, uint8_t *side_exit)
+jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, insn_opnd_t insn_opnd, const int max_chain_depth, uint8_t *side_exit)
 {
     // Can't guard for for these classes because some of they are sometimes immediate (special const).
     // Can remove this by adding appropriate dynamic checks.
@@ -1373,10 +1373,10 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, uint32_t s https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1373
         return false;
     }
 
-    val_type_t temp_type = ctx_get_temp_type(ctx, stack_idx);
+    val_type_t val_type = ctx_get_opnd_type(ctx, insn_opnd);
 
     // Check that the receiver is a heap object
-    if (!temp_type.is_heap)
+    if (!val_type.is_heap)
     {
         test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK));
         jnz_ptr(cb, side_exit);
@@ -1385,7 +1385,7 @@ jit_guard_known_klass(jitstate_t *jit, ctx_t* ctx, VALUE known_klass, uint32_t s https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1385
         cmp(cb, REG0, imm_opnd(Qnil));
         je_ptr(cb, side_exit);
 
-        ctx_set_temp_type(ctx, stack_idx, TYPE_HEAP);
+        ctx_set_opnd_type(ctx, insn_opnd, TYPE_HEAP);
     }
 
     // Pointer to the klass field of the receiver &(recv->klass)
@@ -1796,7 +1796,7 @@ gen_opt_send_without_block(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1796
     // Points to the receiver operand on the stack
     x86opnd_t recv = ctx_stack_opnd(ctx, argc);
     mov(cb, REG0, recv);
-    if (!jit_guard_known_klass(jit, ctx, comptime_recv_klass, argc, OSWB_MAX_DEPTH, side_exit)) {
+    if (!jit_guard_known_klass(jit, ctx, comptime_recv_klass, OPND_STACK(argc), OSWB_MAX_DEPTH, side_exit)) {
         return YJIT_CANT_COMPILE;
     }
 
diff --git a/yjit_core.c b/yjit_core.c
index 3be45c12e5..f0b7c31984 100644
--- a/yjit_core.c
+++ b/yjit_core.c
@@ -132,18 +132,20 @@ ctx_stack_opnd(ctx_t* ctx, int32_t idx) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L132
 }
 
 /**
-Get the type of a value on the temp stack
-Returns T_NONE if unknown
+Get the type of an instruction operand
 */
 val_type_t
-ctx_get_temp_type(const ctx_t* ctx, size_t idx)
+ctx_get_opnd_type(const ctx_t* ctx, insn_opnd_t opnd)
 {
-    RUBY_ASSERT(idx < ctx->stack_size);
+    RUBY_ASSERT(opnd.idx < ctx->stack_size);
+
+    if (opnd.is_self)
+        return ctx->self_type;
 
     if (ctx->stack_size > MAX_TEMP_TYPES)
         return TYPE_UNKNOWN;
 
-    temp_mapping_t mapping = ctx->temp_mapping[ctx->stack_size - 1 - idx];
+    temp_mapping_t mapping = ctx->temp_mapping[ctx->stack_size - 1 - opnd.idx];
 
     switch (mapping.kind)
     {
@@ -151,7 +153,7 @@ ctx_get_temp_type(const ctx_t* ctx, size_t idx) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L153
         return ctx->self_type;
 
         case TEMP_STACK:
-        return ctx->temp_types[ctx->stack_size - 1 - idx];
+        return ctx->temp_types[ctx->stack_size - 1 - opnd.idx];
 
         case TEMP_LOCAL:
         RUBY_ASSERT(mapping.idx < MAX_LOCAL_TYPES);
@@ -162,16 +164,21 @@ ctx_get_temp_type(const ctx_t* ctx, size_t idx) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L164
 }
 
 /**
-Set the type of a value in the temporary stack
+Set the type of an instruction operand
 */
-void ctx_set_temp_type(ctx_t* ctx, size_t idx, val_type_t type)
+void ctx_set_opnd_type(ctx_t* ctx, insn_opnd_t opnd, val_type_t type)
 {
-    RUBY_ASSERT(idx < ctx->stack_size);
+    RUBY_ASSERT(opnd.idx < ctx->stack_size);
+
+    if (opnd.is_self) {
+        ctx->self_type = type;
+        return;
+    }
 
     if (ctx->stack_size > MAX_TEMP_TYPES)
         return;
 
-    temp_mapping_t mapping = ctx->temp_mapping[ctx->stack_size - 1 - idx];
+    temp_mapping_t mapping = ctx->temp_mapping[ctx->stack_size - 1 - opnd.idx];
 
     switch (mapping.kind)
     {
@@ -180,7 +187,7 @@ void ctx_set_temp_type(ctx_t* ctx, size_t idx, val_type_t type) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L187
         break;
 
         case TEMP_STACK:
-        ctx->temp_types[ctx->stack_size - 1 - idx] = type;
+        ctx->temp_types[ctx->stack_size - 1 - opnd.idx] = type;
         break;
 
         case TEMP_LOCAL:
@@ -275,8 +282,8 @@ int ctx_diff(const ctx_t* src, const ctx_t* dst) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L282
     // For each value on the temp stack
     for (size_t i = 0; i < src->stack_size; ++i)
     {
-        val_type_t t_src = ctx_get_temp_type(src, i);
-        val_type_t t_dst = ctx_get_temp_type(dst, i);
+        val_type_t t_src = ctx_get_opnd_type(src, OPND_STACK(i));
+        val_type_t t_dst = ctx_get_opnd_type(dst, OPND_STACK(i));
         int temp_diff = type_diff(t_src, t_dst);
 
         if (temp_diff == INT_MAX)
diff --git a/yjit_core.h b/yjit_core.h
index e264d89ffa..3830146f7e 100644
--- a/yjit_core.h
+++ b/yjit_core.h
@@ -26,23 +26,20 @@ https://github.com/ruby/ruby/blob/trunk/yjit_core.h#L26
 // Default versioning context (no type information)
 #define DEFAULT_CTX ( (ctx_t){ 0 } )
 
-typedef enum yjit_type_enum
-{
-    ETYPE_UNKNOWN = 0,
-    ETYPE_NIL,
-    ETYPE_FIXNUM,
-    ETYPE_ARRAY,
-    ETYPE_HASH
-    //ETYPE_SYMBOL
-    //ETYPE_STRING
-
-} type_enum_t;
-
-/**
-Represent the type of a value (local/stack/self) in YJIT
-*/
+// Represent the type of a value (local/stack/self) in YJIT
 typedef struct yjit_type_struct
 {
+    enum
+    {
+        ETYPE_UNKNOWN = 0,
+        ETYPE_NIL,
+        ETYPE_FIXNUM,
+        ETYPE_ARRAY,
+        ETYPE_HASH
+        //ETYPE_SYMBOL
+        //ETYPE_STRING
+    };
+
     // Value is definitely a heap object
     uint8_t is_heap : 1;
 
@@ -69,18 +66,19 @@ STATIC_ASSERT(val_type_size, sizeof(val_type_t) == 1); https://github.com/ruby/ruby/blob/trunk/yjit_core.h#L66
 #define TYPE_ARRAY ( (val_type_t){ .is_heap = 1, .type = ETYPE_ARRAY } )
 #define TYPE_HASH ( (val_type_t){ .is_heap =  (... truncated)

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

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