diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2024-01-08 09:34:57 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-08 17:34:57 +0000 |
| commit | a0eecfb5bae66470ccf40e27b9193fbf5c76618f (patch) | |
| tree | 7defc6d9403d6177deac2e69ec37ab94e416e25c | |
| parent | 85a7da742a81d87322878a7f66c44b16c7cb9b0b (diff) | |
YJIT: Fallback Integer#<< if a shift amount varies (#9426)
* YJIT: Fallback Integer#<< if a shift amount varies
* YJIT: Do not fallback lshift in the first chain
| -rw-r--r-- | yjit.rb | 2 | ||||
| -rw-r--r-- | yjit/src/codegen.rs | 17 | ||||
| -rw-r--r-- | yjit/src/stats.rs | 2 |
3 files changed, 16 insertions, 5 deletions
@@ -288,7 +288,7 @@ module RubyVM::YJIT ].each do |insn| print_counters(stats, out: out, prefix: "#{insn}_", prompt: "#{insn} exit reasons:", optional: true) end - print_counters(stats, out: out, prefix: 'lshift_', prompt: 'left shift (ltlt) exit reasons: ') + print_counters(stats, out: out, prefix: 'lshift_', prompt: 'left shift (opt_ltlt) exit reasons: ') print_counters(stats, out: out, prefix: 'invalidate_', prompt: 'invalidation reasons: ') end diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 6d85ca4266..7e44c3add0 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4637,17 +4637,28 @@ fn jit_rb_int_lshift( // Untag the fixnum shift amount let shift_amt = comptime_shift.as_isize() >> 1; - if shift_amt > 63 || shift_amt < 0 { return false; } + // Fallback to a C call if the shift amount varies + if asm.ctx.get_chain_depth() > 1 { + return false; + } + let rhs = asm.stack_pop(1); let lhs = asm.stack_pop(1); - // Guard on the shift value we speculated on + // Guard on the shift amount we speculated on asm.cmp(rhs, comptime_shift.into()); - asm.jne(Target::side_exit(Counter::lshift_amt_changed)); + jit_chain_guard( + JCC_JNE, + jit, + asm, + ocb, + 2, // defer_compilation increments chain_depth + Counter::lshift_amount_changed, + ); let in_val = asm.sub(lhs, 1.into()); let shift_opnd = Opnd::UImm(shift_amt as u64); diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index ac247d2fa8..ba1479e152 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -447,7 +447,7 @@ make_counters! { opt_mod_zero, opt_div_zero, - lshift_amt_changed, + lshift_amount_changed, lshift_overflow, opt_aref_argc_not_one, |
