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
This commit is contained in:
Takashi Kokubun 2024-01-08 09:34:57 -08:00 коммит произвёл GitHub
Родитель 85a7da742a
Коммит a0eecfb5ba
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 16 добавлений и 5 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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);

Просмотреть файл

@ -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,