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

ruby-changes:69030

From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:36 +0900 (JST)
Subject: [ruby-changes:69030] 2404ff691d (master): Factor our guard_two_fixnums(). Implement opt_or.

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

From 2404ff691d81183dc7d1bdc844fd7d556edf6837 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Fri, 9 Apr 2021 14:01:27 -0400
Subject: Factor our guard_two_fixnums(). Implement opt_or.

---
 yjit_codegen.c | 118 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 70 insertions(+), 48 deletions(-)

diff --git a/yjit_codegen.c b/yjit_codegen.c
index 5b759f6c6f..bd42c7f346 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -897,6 +897,34 @@ gen_setinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L897
     return YJIT_KEEP_COMPILING;
 }
 
+static void
+guard_two_fixnums(ctx_t* ctx, uint8_t* side_exit)
+{
+    // Get the stack operand types
+    val_type_t arg1_type = ctx_get_opnd_type(ctx, OPND_STACK(0));
+    val_type_t arg0_type = ctx_get_opnd_type(ctx, OPND_STACK(1));
+
+    // Get stack operands without popping them
+    x86opnd_t arg1 = ctx_stack_opnd(ctx, 0);
+    x86opnd_t arg0 = ctx_stack_opnd(ctx, 1);
+
+    // If not fixnums, fall back
+    if (arg0_type.type != ETYPE_FIXNUM) {
+        ADD_COMMENT(cb, "guard arg0 fixnum");
+        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
+        jz_ptr(cb, side_exit);
+    }
+    if (arg1_type.type != ETYPE_FIXNUM) {
+        ADD_COMMENT(cb, "guard arg1 fixnum");
+        test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
+        jz_ptr(cb, side_exit);
+    }
+
+    // TODO: set stack types in context
+    ctx_set_opnd_type(ctx, OPND_STACK(0), TYPE_FIXNUM);
+    ctx_set_opnd_type(ctx, OPND_STACK(1), TYPE_FIXNUM);
+}
+
 // Conditional move operation used by comparison operators
 typedef void (*cmov_fn)(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
 
@@ -911,22 +939,13 @@ gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L939
         return YJIT_CANT_COMPILE;
     }
 
+    // Check that both operands are fixnums
+    guard_two_fixnums(ctx, side_exit);
+
     // Get the operands and destination from the stack
-    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_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
-    // If not fixnums, fall back
-    if (arg0_type.type != ETYPE_FIXNUM) {
-        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-    if (arg1_type.type != ETYPE_FIXNUM) {
-        test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-
     // Compare the arguments
     xor(cb, REG0_32, REG0_32); // REG0 = Qfalse
     mov(cb, REG1, arg0);
@@ -1121,22 +1140,13 @@ gen_opt_and(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1140
         return YJIT_CANT_COMPILE;
     }
 
+    // Check that both operands are fixnums
+    guard_two_fixnums(ctx, side_exit);
+
     // Get the operands and destination from the stack
-    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_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
-    // If not fixnums, fall back
-    if (arg0_type.type != ETYPE_FIXNUM) {
-        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-    if (arg1_type.type != ETYPE_FIXNUM) {
-        test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-
     // Do the bitwise and arg0 & arg1
     mov(cb, REG0, arg0);
     and(cb, REG0, arg1);
@@ -1149,32 +1159,52 @@ gen_opt_and(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1159
 }
 
 static codegen_status_t
-gen_opt_minus(jitstate_t* jit, ctx_t* ctx)
+gen_opt_or(jitstate_t* jit, ctx_t* ctx)
 {
     // Create a size-exit to fall back to the interpreter
     // Note: we generate the side-exit before popping operands from the stack
     uint8_t* side_exit = yjit_side_exit(jit, ctx);
 
-    if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)) {
+    if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_OR)) {
         return YJIT_CANT_COMPILE;
     }
 
+    // Check that both operands are fixnums
+    guard_two_fixnums(ctx, side_exit);
+
     // Get the operands and destination from the stack
-    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_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
-    // If not fixnums, fall back
-    if (arg0_type.type != ETYPE_FIXNUM) {
-        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-    if (arg1_type.type != ETYPE_FIXNUM) {
-        test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
+    // Do the bitwise or arg0 | arg1
+    mov(cb, REG0, arg0);
+    or(cb, REG0, arg1);
+
+    // Push the output on the stack
+    x86opnd_t dst = ctx_stack_push(ctx, TYPE_FIXNUM);
+    mov(cb, dst, REG0);
+
+    return YJIT_KEEP_COMPILING;
+}
+
+static codegen_status_t
+gen_opt_minus(jitstate_t* jit, ctx_t* ctx)
+{
+    // Create a size-exit to fall back to the interpreter
+    // Note: we generate the side-exit before popping operands from the stack
+    uint8_t* side_exit = yjit_side_exit(jit, ctx);
+
+    if (!assume_bop_not_redefined(jit->block, INTEGER_REDEFINED_OP_FLAG, BOP_MINUS)) {
+        return YJIT_CANT_COMPILE;
     }
 
+    // Check that both operands are fixnums
+    guard_two_fixnums(ctx, side_exit);
+
+    // Get the operands and destination from the stack
+    x86opnd_t arg1 = ctx_stack_pop(ctx, 1);
+    x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
+
     // Subtract arg0 - arg1 and test for overflow
     mov(cb, REG0, arg0);
     sub(cb, REG0, arg1);
@@ -1199,22 +1229,13 @@ gen_opt_plus(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1229
         return YJIT_CANT_COMPILE;
     }
 
+    // Check that both operands are fixnums
+    guard_two_fixnums(ctx, side_exit);
+
     // Get the operands and destination from the stack
-    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_opnd_type(ctx, OPND_STACK(0));
     x86opnd_t arg0 = ctx_stack_pop(ctx, 1);
 
-    // If not fixnums, fall back
-    if (arg0_type.type != ETYPE_FIXNUM) {
-        test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG));
-        jz_ptr(cb, side_exit);
-    }
-    if (arg1_type.type != ETYPE_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);
     sub(cb, REG0, imm_opnd(1));
@@ -2007,6 +2028,7 @@ yjit_init_codegen(void) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L2028
     yjit_reg_op(BIN(opt_gt), gen_opt_gt);
     yjit_reg_op(BIN(opt_aref), gen_opt_aref);
     yjit_reg_op(BIN(opt_and), gen_opt_and);
+    yjit_reg_op(BIN(opt_or), gen_opt_or);
     yjit_reg_op(BIN(opt_minus), gen_opt_minus);
     yjit_reg_op(BIN(opt_plus), gen_opt_plus);
     yjit_reg_op(BIN(opt_getinlinecache), gen_opt_getinlinecache);
-- 
cgit v1.2.1


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

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