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/