ruby-changes:68896
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:15:06 +0900 (JST)
Subject: [ruby-changes:68896] aee44e4f2b (master): Part 1 of improved type tracking logic
https://git.ruby-lang.org/ruby.git/commit/?id=aee44e4f2b From aee44e4f2bcd795b5a81c72cb75d742103bb070b Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Wed, 31 Mar 2021 15:54:46 -0400 Subject: Part 1 of improved type tracking logic --- yjit_codegen.c | 89 ++++++++++++++++++++++-------------------- yjit_core.c | 119 ++++++++++++++++++++++++++++++++++++++++++++------------- yjit_core.h | 72 +++++++++++++++------------------- 3 files changed, 171 insertions(+), 109 deletions(-) diff --git a/yjit_codegen.c b/yjit_codegen.c index 56b82a5b17..12aa893993 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -369,8 +369,8 @@ static codegen_status_t https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L369 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); x86opnd_t dup_val = ctx_stack_pop(ctx, 0); - int dup_type = ctx_get_top_type(ctx); // Push the same value on top x86opnd_t loc0 = ctx_stack_push(ctx, dup_type); @@ -399,7 +399,7 @@ static codegen_status_t https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L399 gen_putnil(jitstate_t* jit, ctx_t* ctx) { // Write constant at SP - x86opnd_t stack_top = ctx_stack_push(ctx, T_NIL); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_NIL); mov(cb, stack_top, imm_opnd(Qnil)); return YJIT_KEEP_COMPILING; } @@ -412,7 +412,7 @@ gen_putobject(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L412 if (FIXNUM_P(arg)) { // Keep track of the fixnum type tag - x86opnd_t stack_top = ctx_stack_push(ctx, T_FIXNUM); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_FIXNUM); x86opnd_t imm = imm_opnd((int64_t)arg); @@ -429,7 +429,7 @@ gen_putobject(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L429 } else if (arg == Qtrue || arg == Qfalse) { - x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, imm_opnd((int64_t)arg)); } else @@ -441,7 +441,7 @@ gen_putobject(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L441 mov(cb, RAX, mem_opnd(64, RAX, 0)); // Write argument at SP - x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, RAX); } @@ -455,7 +455,7 @@ gen_putobject_int2fix(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L455 int cst_val = (opcode == BIN(putobject_INT2FIX_0_))? 0:1; // Write constant at SP - x86opnd_t stack_top = ctx_stack_push(ctx, T_FIXNUM); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_FIXNUM); mov(cb, stack_top, imm_opnd(INT2FIX(cst_val))); return YJIT_KEEP_COMPILING; @@ -468,7 +468,7 @@ gen_putself(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L468 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, T_NONE); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, RAX); return YJIT_KEEP_COMPILING; @@ -488,7 +488,7 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L488 mov(cb, REG0, mem_opnd(64, REG0, offs)); // Write the local at SP - x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, REG0); return YJIT_KEEP_COMPILING; @@ -515,7 +515,7 @@ gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L515 mov(cb, REG0, mem_opnd(64, REG0, offs)); // Write the local at SP - x86opnd_t stack_top = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_top = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_top, REG0); return YJIT_KEEP_COMPILING; @@ -564,10 +564,10 @@ gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L564 // Check that `self` is a pointer to an object on the GC heap static void -guard_self_is_object(codeblock_t *cb, x86opnd_t self_opnd, uint8_t *side_exit, ctx_t *ctx) +guard_self_is_heap(codeblock_t *cb, x86opnd_t self_opnd, uint8_t *side_exit, ctx_t *ctx) { // `self` is constant throughout the entire region, so we only need to do this check once. - if (!ctx->self_is_object) { + if (!ctx->self_type.is_heap) { test(cb, self_opnd, imm_opnd(RUBY_IMMEDIATE_MASK)); jnz_ptr(cb, side_exit); cmp(cb, self_opnd, imm_opnd(Qfalse)); @@ -580,11 +580,10 @@ guard_self_is_object(codeblock_t *cb, x86opnd_t self_opnd, uint8_t *side_exit, c https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L580 // cmp(cb, self_opnd, imm_opnd(Qnil)); // jbe(cb, side_exit); - ctx->self_is_object = true; + ctx->self_type.is_heap = 1; } } - // Generate a stubbed unconditional jump to the next bytecode instruction. // Blocks that are part of a guard chain can use this to share the same successor. static void @@ -726,7 +725,7 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L725 // Load self from CFP mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, self)); - guard_self_is_object(cb, REG0, COUNTED_EXIT(side_exit, getivar_se_self_not_heap), ctx); + guard_self_is_heap(cb, REG0, COUNTED_EXIT(side_exit, getivar_se_self_not_heap), ctx); // Guard that self has a known class x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass)); @@ -754,7 +753,7 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L753 je_ptr(cb, COUNTED_EXIT(side_exit, getivar_undef)); // Push the ivar on the stack - x86opnd_t out_opnd = ctx_stack_push(ctx, T_NONE); + x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, out_opnd, REG1); } else { @@ -787,7 +786,7 @@ gen_getinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L786 je_ptr(cb, COUNTED_EXIT(side_exit, getivar_undef)); // Push the ivar on the stack - x86opnd_t out_opnd = ctx_stack_push(ctx, T_NONE); + x86opnd_t out_opnd = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, out_opnd, REG0); } @@ -825,7 +824,7 @@ gen_setinstancevariable(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L824 // Load self from CFP mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, self)); - guard_self_is_object(cb, REG0, side_exit, ctx); + guard_self_is_heap(cb, REG0, side_exit, ctx); // Bail if receiver class is different from compiled time call cache class x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass)); @@ -882,17 +881,17 @@ gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L881 } // Get the operands and destination from the stack - int arg1_type = ctx_get_top_type(ctx); + val_type_t arg1_type = ctx_get_temp_type(ctx, 0); x86opnd_t arg1 = ctx_stack_pop(ctx, 1); - int arg0_type = ctx_get_top_type(ctx); + val_type_t arg0_type = ctx_get_temp_type(ctx, 0); x86opnd_t arg0 = ctx_stack_pop(ctx, 1); // If not fixnums, fall back - if (arg0_type != T_FIXNUM) { + if (arg0_type.type != ETYPE_FIXNUM) { test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG)); jz_ptr(cb, side_exit); } - if (arg1_type != T_FIXNUM) { + if (arg1_type.type != ETYPE_FIXNUM) { test(cb, arg1, imm_opnd(RUBY_FIXNUM_FLAG)); jz_ptr(cb, side_exit); } @@ -905,7 +904,7 @@ gen_fixnum_cmp(jitstate_t* jit, ctx_t* ctx, cmov_fn cmov_op) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L904 cmov_op(cb, REG0, REG1); // Push the output on the stack - x86opnd_t dst = ctx_stack_push(ctx, T_NONE); + x86opnd_t dst = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, dst, REG0); return YJIT_KEEP_COMPILING; @@ -1007,7 +1006,7 @@ gen_opt_aref(jitstate_t *jit, ctx_t *ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1006 yjit_load_regs(cb); // Push the return value onto the stack - x86opnd_t stack_ret = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_ret, RAX); } @@ -1068,7 +1067,7 @@ gen_opt_aref(jitstate_t *jit, ctx_t *ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1067 yjit_load_regs(cb); // Push the return value onto the stack - x86opnd_t stack_ret = ctx_stack_push(ctx, T_NONE); + x86opnd_t stack_ret = ctx_stack_push(ctx, TYPE_UNKNOWN); mov(cb, stack_ret, RAX); } @@ -1092,17 +1091,17 @@ gen_opt_and(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L1091 } // Get the operands and destination from the stack - int arg1_type = ctx_get_top_type(ctx); + val_type_t arg1_type = ctx_get_temp_type(ctx, 0); x86opnd_t arg1 = ctx_stack_pop(ctx, 1); - int arg0_type = ctx_get_top_type(ctx); + val_type_t arg0_type = ctx_get_temp_type(ctx, 0); x86opnd_t arg0 = ctx_stack_pop(ctx, 1); // If not fixnums, fall back - if (arg0_type != T_FIXNUM) { + if (arg0_type.type != ETYPE_FIXNUM) { test(cb, arg0, imm_opnd(RUBY_FIXNUM_FLAG)); jz_ptr(cb, side_exit); } - if (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/