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

ruby-changes:68711

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:31 +0900 (JST)
Subject: [ruby-changes:68711] 0a6e824ad2 (master): Prototype type-specialization for temp values

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

From 0a6e824ad2cc22315b32d1a11dc094c528b32acb Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 20 Jan 2021 16:58:09 -0500
Subject: Prototype type-specialization for temp values

---
 ujit_codegen.c | 38 ++++++++++++++++++++++----------------
 ujit_core.c    | 39 ++++++++++++++++++++++++++++++++++++---
 ujit_core.h    |  6 ++----
 3 files changed, 60 insertions(+), 23 deletions(-)

diff --git a/ujit_codegen.c b/ujit_codegen.c
index 4e02e1f43f..488e4ca770 100644
--- a/ujit_codegen.c
+++ b/ujit_codegen.c
@@ -230,8 +230,8 @@ static bool https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L230
 gen_dup(jitstate_t* jit, ctx_t* ctx)
 {
     x86opnd_t dup_val = ctx_stack_pop(ctx, 1);
-    x86opnd_t loc0 = ctx_stack_push(ctx, 1);
-    x86opnd_t loc1 = ctx_stack_push(ctx, 1);
+    x86opnd_t loc0 = ctx_stack_push(ctx, T_NONE);
+    x86opnd_t loc1 = ctx_stack_push(ctx, T_NONE);
     mov(cb, RAX, dup_val);
     mov(cb, loc0, RAX);
     mov(cb, loc1, RAX);
@@ -257,7 +257,7 @@ static bool https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L257
 gen_putnil(jitstate_t* jit, ctx_t* ctx)
 {
     // Write constant at SP
-    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_top = ctx_stack_push(ctx, T_NIL);
     mov(cb, stack_top, imm_opnd(Qnil));
     return true;
 }
@@ -272,7 +272,7 @@ gen_putobject(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L272
     mov(cb, RAX, mem_opnd(64, RAX, 8)); // One after the opcode
 
     // Write argument at SP
-    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, RAX);
 
     return true;
@@ -285,7 +285,7 @@ gen_putobject_int2fix(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L285
     int cst_val = (opcode == BIN(putobject_INT2FIX_0_))? 0:1;
 
     // Write constant at SP
-    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_top = ctx_stack_push(ctx, T_FIXNUM);
     mov(cb, stack_top, imm_opnd(INT2FIX(cst_val)));
 
     return true;
@@ -298,7 +298,7 @@ gen_putself(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L298
     mov(cb, RAX, member_opnd(REG_CFP, rb_control_frame_t, self));
 
     // Write it on the stack
-    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, RAX);
 
     return true;
@@ -318,7 +318,7 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L318
     mov(cb, REG0, mem_opnd(64, REG0, offs));
 
     // Write the local at SP
-    x86opnd_t stack_top = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_top, REG0);
 
     return true;
@@ -437,7 +437,7 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L437
     je_ptr(cb, side_exit);
 
     // Push the ivar on the stack
-    x86opnd_t out_opnd = ctx_stack_push(ctx, 1);
+    x86opnd_t out_opnd = ctx_stack_push(ctx, T_NONE);
     mov(cb, out_opnd, REG0);
 
     return true;
@@ -549,7 +549,7 @@ gen_opt_lt(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L549
     cmovl(cb, REG0, REG1);
 
     // Push the output on the stack
-    x86opnd_t dst = ctx_stack_push(ctx, 1);
+    x86opnd_t dst = ctx_stack_push(ctx, T_NONE);
     mov(cb, dst, REG0);
 
     return true;
@@ -589,7 +589,7 @@ gen_opt_minus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L589
     add(cb, REG0, imm_opnd(1));
 
     // Push the output on the stack
-    x86opnd_t dst = ctx_stack_push(ctx, 1);
+    x86opnd_t dst = ctx_stack_push(ctx, T_NONE);
     mov(cb, dst, REG0);
 
     return true;
@@ -613,14 +613,20 @@ gen_opt_plus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L613
     jnz_ptr(cb, side_exit);
 
     // Get the operands and destination from the stack
+    int arg1_type = ctx_get_top_type(ctx);
     x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
+    int arg0_type = ctx_get_top_type(ctx);
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
     // If not fixnums, fall back
-    test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
-    jz_ptr(cb, side_exit);
-    test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
-    jz_ptr(cb, side_exit);
+    if (arg0_type != T_FIXNUM) {
+        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
+        jz_ptr(cb, side_exit);
+    }
+    if (arg1_type != T_FIXNUM) {
+        test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
+        jz_ptr(cb, side_exit);
+    }
 
     // Add arg0 + arg1 and test for overflow
     mov(cb, REG0, arg0);
@@ -629,7 +635,7 @@ gen_opt_plus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L635
     jo_ptr(cb, side_exit);
 
     // Push the output on the stack
-    x86opnd_t dst = ctx_stack_push(ctx, 1);
+    x86opnd_t dst = ctx_stack_push(ctx, T_NONE);
     mov(cb, dst, REG0);
 
     return true;
@@ -938,7 +944,7 @@ gen_opt_send_without_block(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_codegen.c#L944
     pop(cb, REG_CFP);
 
     // Push the return value on the Ruby stack
-    x86opnd_t stack_ret = ctx_stack_push(ctx, 1);
+    x86opnd_t stack_ret = ctx_stack_push(ctx, T_NONE);
     mov(cb, stack_ret, RAX);
 
     // If this function needs a Ruby stack frame
diff --git a/ujit_core.c b/ujit_core.c
index 2ca4550a71..aaaf56d3b3 100644
--- a/ujit_core.c
+++ b/ujit_core.c
@@ -31,13 +31,18 @@ ctx_sp_opnd(ctx_t* ctx, int32_t offset_bytes) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L31
 }
 
 /*
-Make space on the stack for N values
+Push one new value on the temp stack
 Return a pointer to the new stack top
 */
 x86opnd_t
-ctx_stack_push(ctx_t* ctx, size_t n)
+ctx_stack_push(ctx_t* ctx, int type)
 {
-    ctx->stack_size += n;
+    // Keep track of the type of the value
+    RUBY_ASSERT(type <= RUBY_T_MASK);
+    if (ctx->stack_size < MAX_TEMP_TYPES)
+        ctx->temp_types[ctx->stack_size] = type;
+
+    ctx->stack_size += 1;
 
     // SP points just above the topmost value
     int32_t offset = (ctx->stack_size - 1) * 8;
@@ -51,15 +56,28 @@ Return a pointer to the stack top before the pop operation https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L56
 x86opnd_t
 ctx_stack_pop(ctx_t* ctx, size_t n)
 {
+    RUBY_ASSERT(n <= ctx->stack_size);
+
     // SP points just above the topmost value
     int32_t offset = (ctx->stack_size - 1) * 8;
     x86opnd_t top = mem_opnd(64, REG_SP, offset);
 
+    // Clear the types of the popped values
+    for (size_t i = 0; i < n; ++i)
+    {
+        size_t idx = ctx->stack_size - i - 1;
+        if (idx < MAX_TEMP_TYPES)
+            ctx->temp_types[idx] = T_NONE;
+    }
+
     ctx->stack_size -= n;
 
     return top;
 }
 
+/**
+Get an operand pointing to a slot on the temp stack
+*/
 x86opnd_t
 ctx_stack_opnd(ctx_t* ctx, int32_t idx)
 {
@@ -70,6 +88,21 @@ ctx_stack_opnd(ctx_t* ctx, int32_t idx) https://github.com/ruby/ruby/blob/trunk/ujit_core.c#L88
     return opnd;
 }
 
+/**
+Get the type of the topmost value on the temp stack
+Returns T_NONE if unknown
+*/
+int
+ctx_get_top_type(ctx_t* ctx)
+{
+    RUBY_ASSERT(n <= ctx->stack_size);
+
+    if (ctx->stack_size > MAX_TEMP_TYPES)
+        return T_NONE;
+
+    return ctx->temp_types[ctx->stack_size - 1];
+}
+
 // Add an incoming branch for a given block version
 static void add_incoming(block_t* p_block, uint32_t branch_idx)
 {
diff --git a/ujit_core.h b/ujit_core.h
index dc94cd2873..5438cd850e 100644
--- a/ujit_core.h
+++ b/ujit_core.h
@@ -112,13 +112,11 @@ typedef struct BlockVersion https://github.com/ruby/ruby/blob/trunk/ujit_core.h#L112
 } block_t;
 
 // Context object methods
-int ctx_get_opcode(ctx_t *ctx);
-uint32_t ctx_next_idx(ctx_t* ctx);
-VALUE ctx_get_arg(ctx_t* ctx, size_t arg_idx);
 x86opnd_t ctx_sp_opnd(ctx_t* ctx, int32_t offset_bytes);
-x86opnd_t ctx_stack_push(ctx_t* ctx, size_t n);
+x86opnd_t ctx_stack_push(ctx_t* ctx, int type);
 x86opnd_t ctx_stack_pop(ctx_t* ctx, size_t n);
 x86opnd_t ctx_stack_opnd(ctx_t* ctx, int32_t idx);
+int ctx_get_top_type(ctx_t* ctx);
 
 block_t* find_block_version(blockid_t blockid, const ctx_t* ctx);
 block_t* gen_block_version(blockid_t blockid, const ctx_t* ctx);
-- 
cgit v1.2.1


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

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