YJIT: implement missing `asm.jg` instruction in backend (#8130)

YJIT: implement missing jg instruction in backend

While trying to implement a specialize integer left shift, I ran
into a problem where we have no way to do a greater-than comparison
at the moment. Surprising we went this far without ever needing it.
This commit is contained in:
Maxime Chevalier-Boisvert 2023-07-27 17:47:29 -04:00 коммит произвёл GitHub
Родитель 83f9d80c0b
Коммит 5669a28fde
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 60 добавлений и 0 удалений

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

@ -1079,6 +1079,9 @@ impl Assembler
Insn::Jl(target) => {
emit_conditional_jump::<{Condition::LT}>(cb, compile_side_exit(*target, self, ocb));
},
Insn::Jg(target) => {
emit_conditional_jump::<{Condition::GT}>(cb, compile_side_exit(*target, self, ocb));
},
Insn::Jbe(target) => {
emit_conditional_jump::<{Condition::LS}>(cb, compile_side_exit(*target, self, ocb));
},

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

@ -432,6 +432,9 @@ pub enum Insn {
/// Jump if lower
Jl(Target),
/// Jump if greater
Jg(Target),
// Unconditional jump to a branch target
Jmp(Target),
@ -578,6 +581,7 @@ impl Insn {
Insn::Jbe(_) => "Jbe",
Insn::Je(_) => "Je",
Insn::Jl(_) => "Jl",
Insn::Jg(_) => "Jg",
Insn::Jmp(_) => "Jmp",
Insn::JmpOpnd(_) => "JmpOpnd",
Insn::Jne(_) => "Jne",
@ -725,6 +729,7 @@ impl<'a> Iterator for InsnOpndIterator<'a> {
Insn::Jbe(_) |
Insn::Je(_) |
Insn::Jl(_) |
Insn::Jg(_) |
Insn::Jmp(_) |
Insn::Jne(_) |
Insn::Jnz(_) |
@ -822,6 +827,7 @@ impl<'a> InsnOpndMutIterator<'a> {
Insn::Jbe(_) |
Insn::Je(_) |
Insn::Jl(_) |
Insn::Jg(_) |
Insn::Jmp(_) |
Insn::Jne(_) |
Insn::Jnz(_) |

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

@ -673,6 +673,14 @@ impl Assembler
}
},
Insn::Jg(target) => {
match compile_side_exit(*target, self, ocb) {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jg_ptr(cb, code_ptr),
Target::Label(label_idx) => jg_label(cb, label_idx),
Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
}
},
Insn::Jbe(target) => {
match compile_side_exit(*target, self, ocb) {
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jbe_ptr(cb, code_ptr),

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

@ -4325,6 +4325,45 @@ fn jit_rb_int_div(
true
}
/*
fn jit_rb_int_lshift(
jit: &mut JITState,
asm: &mut Assembler,
ocb: &mut OutlinedCb,
_ci: *const rb_callinfo,
_cme: *const rb_callable_method_entry_t,
_block: Option<IseqPtr>,
_argc: i32,
_known_recv_class: *const VALUE,
) -> bool {
if asm.ctx.two_fixnums_on_stack(jit) != Some(true) {
return false;
}
guard_two_fixnums(jit, asm, ocb);
let rhs = asm.stack_pop(1);
let lhs = asm.stack_pop(1);
// Ruby supports using a negative shift value
asm.comment("Guard shift negative");
let shift_val = asm.sub(rhs, 1.into());
asm.cmp(shift_val, 0.into());
asm.jl(Target::side_exit(Counter::lshift_range));
asm.cmp(shift_val, 63.into());
asm.jg(Target::side_exit(Counter::lshift_range));
// FIXME: we don't yet support shift with non-immediate values in the backend
// Do the shifting
let out_val = asm.lshift(lhs, shift_val);
asm.jo(Target::side_exit(Counter::lshift_overflow));
let ret_opnd = asm.stack_push(Type::Fixnum);
asm.mov(ret_opnd, out_val);
true
}
*/
fn jit_rb_int_aref(
jit: &mut JITState,
asm: &mut Assembler,
@ -8371,6 +8410,7 @@ impl CodegenGlobals {
self.yjit_reg_method(rb_cInteger, "*", jit_rb_int_mul);
self.yjit_reg_method(rb_cInteger, "/", jit_rb_int_div);
//self.yjit_reg_method(rb_cInteger, "<<", jit_rb_int_lshift);
self.yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref);
// rb_str_to_s() methods in string.c

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

@ -335,6 +335,9 @@ make_counters! {
opt_mod_zero,
opt_div_zero,
lshift_range,
lshift_overflow,
opt_aref_argc_not_one,
opt_aref_arg_not_fixnum,
opt_aref_not_array,