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

ruby-changes:69043

From: John <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:38 +0900 (JST)
Subject: [ruby-changes:69043] 6c80150d40 (master): Introduce ctx_{get, set}_opnd_mapping

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

From 6c80150d402758fa07470cb88d5a15b1ffd15e6c Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Wed, 14 Jul 2021 11:36:33 -0700
Subject: Introduce ctx_{get,set}_opnd_mapping

---
 yjit_codegen.c |  38 +++++++++-----------
 yjit_core.c    | 108 +++++++++++++++++++++++++++++++++++++++++----------------
 yjit_core.h    |  11 ++++++
 3 files changed, 106 insertions(+), 51 deletions(-)

diff --git a/yjit_codegen.c b/yjit_codegen.c
index 5c7a2faafe..297d4f4291 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -553,11 +553,11 @@ static codegen_status_t https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L553
 gen_dup(jitstate_t* jit, ctx_t* ctx)
 {
     // Get the top value and its type
-    val_type_t dup_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t dup_val = ctx_stack_pop(ctx, 0);
+    temp_type_mapping_t mapping = ctx_get_opnd_mapping(ctx, OPND_STACK(0));
 
     // Push the same value on top
-    x86opnd_t loc0 = ctx_stack_push(ctx, dup_type);
+    x86opnd_t loc0 = ctx_stack_push_mapping(ctx, mapping);
     mov(cb, REG0, dup_val);
     mov(cb, loc0, REG0);
 
@@ -575,17 +575,16 @@ gen_dupn(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L575
         return YJIT_CANT_COMPILE;
     }
 
-    val_type_t type1 = ctx_get_opnd_type(ctx, OPND_STACK(1));
     x86opnd_t opnd1 = ctx_stack_opnd(ctx, 1);
-
-    val_type_t type0 = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t opnd0 = ctx_stack_opnd(ctx, 0);
+    temp_type_mapping_t mapping1 = ctx_get_opnd_mapping(ctx, OPND_STACK(1));
+    temp_type_mapping_t mapping0 = ctx_get_opnd_mapping(ctx, OPND_STACK(0));
 
-    x86opnd_t dst1 = ctx_stack_push(ctx, type1);
+    x86opnd_t dst1 = ctx_stack_push_mapping(ctx, mapping1);
     mov(cb, REG0, opnd1);
     mov(cb, dst1, REG0);
 
-    x86opnd_t dst0 = ctx_stack_push(ctx, type0);
+    x86opnd_t dst0 = ctx_stack_push_mapping(ctx, mapping0);
     mov(cb, REG0, opnd0);
     mov(cb, dst0, REG0);
 
@@ -596,21 +595,19 @@ gen_dupn(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L595
 static codegen_status_t
 gen_swap(jitstate_t* jit, ctx_t* ctx)
 {
-    val_type_t type0 = ctx_get_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t opnd0 = ctx_stack_opnd(ctx, 0);
-
-    val_type_t type1 = ctx_get_opnd_type(ctx, OPND_STACK(1));
     x86opnd_t opnd1 = ctx_stack_opnd(ctx, 1);
+    temp_type_mapping_t mapping0 = ctx_get_opnd_mapping(ctx, OPND_STACK(0));
+    temp_type_mapping_t mapping1 = ctx_get_opnd_mapping(ctx, OPND_STACK(1));
 
     mov(cb, REG0, opnd0);
     mov(cb, REG1, opnd1);
-
-    ctx_set_opnd_type(ctx, OPND_STACK(0), type1);
-    ctx_set_opnd_type(ctx, OPND_STACK(1), type0);
-
     mov(cb, opnd0, REG1);
     mov(cb, opnd1, REG0);
 
+    ctx_set_opnd_mapping(ctx, OPND_STACK(0), mapping1);
+    ctx_set_opnd_mapping(ctx, OPND_STACK(1), mapping0);
+
     return YJIT_KEEP_COMPILING;
 }
 
@@ -620,16 +617,15 @@ gen_setn(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L617
 {
     rb_num_t n = (rb_num_t)jit_get_arg(jit, 0);
 
-    // Get the top value and its type
-    val_type_t top_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
+    // Set the destination
     x86opnd_t top_val = ctx_stack_pop(ctx, 0);
-
-    // Set the destination and its type
-    ctx_set_opnd_type(ctx, OPND_STACK(n), top_type);
     x86opnd_t dst_opnd = ctx_stack_opnd(ctx, (int32_t)n);
     mov(cb, REG0, top_val);
     mov(cb, dst_opnd, REG0);
 
+    temp_type_mapping_t mapping = ctx_get_opnd_mapping(ctx, OPND_STACK(0));
+    ctx_set_opnd_mapping(ctx, OPND_STACK(n), mapping);
+
     return YJIT_KEEP_COMPILING;
 }
 
@@ -640,10 +636,10 @@ gen_topn(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L636
     int32_t n = (int32_t)jit_get_arg(jit, 0);
 
     // Get top n type / operand
-    val_type_t top_n_type = ctx_get_opnd_type(ctx, OPND_STACK(n));
     x86opnd_t top_n_val = ctx_stack_opnd(ctx, n);
+    temp_type_mapping_t mapping = ctx_get_opnd_mapping(ctx, OPND_STACK(n));
 
-    x86opnd_t loc0 = ctx_stack_push(ctx, top_n_type);
+    x86opnd_t loc0 = ctx_stack_push_mapping(ctx, mapping);
     mov(cb, REG0, top_n_val);
     mov(cb, loc0, REG0);
 
diff --git a/yjit_core.c b/yjit_core.c
index e846c95330..c4db3de854 100644
--- a/yjit_core.c
+++ b/yjit_core.c
@@ -21,16 +21,18 @@ ctx_sp_opnd(ctx_t* ctx, int32_t offset_bytes) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L21
 }
 
 /*
-Push one new value on the temp stack
+Push one new value on the temp stack with an explicit mapping
 Return a pointer to the new stack top
 */
 x86opnd_t
-ctx_stack_push(ctx_t* ctx, val_type_t type)
+ctx_stack_push_mapping(ctx_t* ctx, temp_type_mapping_t mapping)
 {
-    // Keep track of the type of the value
+    // Keep track of the type and mapping of the value
     if (ctx->stack_size < MAX_TEMP_TYPES) {
-        ctx->temp_mapping[ctx->stack_size] = MAP_STACK;
-        ctx->temp_types[ctx->stack_size] = type;
+        ctx->temp_mapping[ctx->stack_size] = mapping.mapping;
+        ctx->temp_types[ctx->stack_size] = mapping.type;
+
+        RUBY_ASSERT(mapping.mapping.kind != TEMP_LOCAL || mapping.mapping.idx < MAX_LOCAL_TYPES);
     }
 
     ctx->stack_size += 1;
@@ -41,24 +43,26 @@ ctx_stack_push(ctx_t* ctx, val_type_t type) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L43
     return mem_opnd(64, REG_SP, offset);
 }
 
+
+/*
+Push one new value on the temp stack
+Return a pointer to the new stack top
+*/
+x86opnd_t
+ctx_stack_push(ctx_t* ctx, val_type_t type)
+{
+    temp_type_mapping_t mapping = { MAP_STACK, type };
+    return ctx_stack_push_mapping(ctx, mapping);
+}
+
 /*
 Push the self value on the stack
 */
 x86opnd_t
 ctx_stack_push_self(ctx_t* ctx)
 {
-    // Keep track of the type of the value
-    if (ctx->stack_size < MAX_TEMP_TYPES) {
-        ctx->temp_mapping[ctx->stack_size] = MAP_SELF;
-        ctx->temp_types[ctx->stack_size] = ctx->self_type;
-    }
-
-    ctx->stack_size += 1;
-    ctx->sp_offset += 1;
-
-    // SP points just above the topmost value
-    int32_t offset = (ctx->sp_offset - 1) * sizeof(VALUE);
-    return mem_opnd(64, REG_SP, offset);
+    temp_type_mapping_t mapping = { MAP_SELF, TYPE_UNKNOWN };
+    return ctx_stack_push_mapping(ctx, mapping);
 }
 
 /*
@@ -67,17 +71,15 @@ Push a local variable on the stack https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L71
 x86opnd_t
 ctx_stack_push_local(ctx_t* ctx, size_t local_idx)
 {
-    // Keep track of the type of the value
-    if (ctx->stack_size < MAX_TEMP_TYPES && local_idx < MAX_LOCAL_TYPES) {
-        ctx->temp_mapping[ctx->stack_size] = (temp_mapping_t){ .kind = TEMP_LOCAL, .idx = local_idx };
+    if (local_idx >= MAX_LOCAL_TYPES) {
+        return ctx_stack_push(ctx, TYPE_UNKNOWN);
     }
 
-    ctx->stack_size += 1;
-    ctx->sp_offset += 1;
-
-    // SP points just above the topmost value
-    int32_t offset = (ctx->sp_offset - 1) * sizeof(VALUE);
-    return mem_opnd(64, REG_SP, offset);
+    temp_type_mapping_t mapping = {
+        (temp_mapping_t){ .kind = TEMP_LOCAL, .idx = local_idx },
+        TYPE_UNKNOWN
+    };
+    return ctx_stack_push_mapping(ctx, mapping);
 }
 
 /*
@@ -131,7 +133,7 @@ ctx_get_opnd_type(const ctx_t* ctx, insn_opnd_t opnd) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L133
     if (opnd.is_self)
         return ctx->self_type;
 
-    if (ctx->stack_size > MAX_TEMP_TYPES)
+    if (ctx->stack_size >= MAX_TEMP_TYPES)
         return TYPE_UNKNOWN;
 
     RUBY_ASSERT(opnd.idx < ctx->stack_size);
@@ -170,11 +172,13 @@ void ctx_upgrade_opnd_type(ctx_t* ctx, insn_opnd_t opnd, val_type_t type) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L172
         return;
     }
 
-    if (ctx->stack_size > MAX_TEMP_TYPES)
+    if (ctx->stack_size >= MAX_TEMP_TYPES)
         return;
 
     RUBY_ASSERT(opnd.idx < ctx->stack_size);
-    temp_mapping_t mapping = ctx->temp_mapping[ctx->stack_size - 1 - opnd.idx];
+    int stack_index = ctx->stack_size - 1 - opnd.idx;
+    RUBY_ASSERT(stack_index < MAX_TEMP_TYPES);
+    temp_mapping_t mapping = ctx->temp_mapping[stack_index];
 
     switch (mapping.kind)
     {
@@ -183,7 +187,6 @@ void ctx_upgrade_opnd_type(ctx_t* ctx, insn_opnd_t opnd, val_type_t type) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L187
         break;
 
         case TEMP_STACK:
-        int stack_index = ctx->stack_size - 1 - opnd.idx;
         UPGRADE_TYPE(ctx->temp_types[stack_index], type);
         break;
 
@@ -194,6 +197,51 @@ void ctx_upgrade_opnd_type(ctx_t* ctx, insn_opnd_t opnd, val_type_t type) https://github.com/ruby/ruby/blob/trunk/yjit_core.c#L197
     }
 }
 
+temp_type_mapping_t
+ctx_get_opnd_mapping(const ctx_t* ctx, insn_opnd_t opnd)
+{
+    temp_type_mapping_t type_mapping;
+    type_mapping.type = ctx_get_opnd_type(ctx, opnd);
+
+    if (opnd.is_self) {
+        type_mapping.mapping = MAP_SELF;
+        return type_mapping;
+    }
+
+    RUBY_ASSERT(opnd.idx < ctx->stack_size);
+    int stack_idx = ctx->stack_size - 1 - opnd.idx;
+
+    if (stack_idx < MAX_TEMP_TYPES) {
+        type_mapping.mapping = ctx->temp_mapping[stack_idx];
+    } else {
+        // We can't know the source of this stack operand, so we assume it is
+        // a stack-only temporary. type will be UNKNOWN
+        RUBY_ASSERT(type_mapping.type.type == ETYPE_UNKNOWN);
+        type_mapping.mapping = MAP_STACK;
+    }
+
+    return type_mapping;
+}
+
+void
+ctx_set_opnd_mapping(ctx_t* ctx, insn_opnd_t opnd, temp_type_mapping_t type_mapping)
+{
+    // self is always MAP_SELF
+    RUBY_ASSERT(!opnd.is_self);
+
+    RUBY_ASSERT(opnd.idx < ctx->stack_size);
+    int stack_idx = ctx->stack_size - 1 - opnd.idx;
+
+    // If outside of tracked range, do nothing
+    if (stack_idx >= MAX_TEMP_TYPES)
+        return;
+
+    ctx->temp_mapping[stack_idx] = type_mapping.mapping;
+
+    // Only used when mapping == MAP_STACK
+    ctx->temp_types[stack_idx] = type_mapping.type;
+}
+
 /**
 Se (... truncated)

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

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