YJIT: guard for array_len >= num in expandarray (#8169)

Avoid generating long dispatch chains for all array lengths seen.
This commit is contained in:
Maxime Chevalier-Boisvert 2023-08-04 10:09:43 -04:00 committed by GitHub
parent 61b76e74af
commit fc0b2a8df2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2023-08-04 14:10:04 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
3 changed files with 16 additions and 14 deletions

View File

@ -538,6 +538,7 @@ impl Insn {
pub(super) fn target_mut(&mut self) -> Option<&mut Target> { pub(super) fn target_mut(&mut self) -> Option<&mut Target> {
match self { match self {
Insn::Jbe(target) | Insn::Jbe(target) |
Insn::Jb(target) |
Insn::Je(target) | Insn::Je(target) |
Insn::Jl(target) | Insn::Jl(target) |
Insn::Jmp(target) | Insn::Jmp(target) |
@ -682,6 +683,7 @@ impl Insn {
pub fn target(&self) -> Option<&Target> { pub fn target(&self) -> Option<&Target> {
match self { match self {
Insn::Jbe(target) | Insn::Jbe(target) |
Insn::Jb(target) |
Insn::Je(target) | Insn::Je(target) |
Insn::Jl(target) | Insn::Jl(target) |
Insn::Jmp(target) | Insn::Jmp(target) |
@ -1821,6 +1823,10 @@ impl Assembler {
self.push_insn(Insn::Jbe(target)); self.push_insn(Insn::Jbe(target));
} }
pub fn jb(&mut self, target: Target) {
self.push_insn(Insn::Jb(target));
}
pub fn je(&mut self, target: Target) { pub fn je(&mut self, target: Target) {
self.push_insn(Insn::Je(target)); self.push_insn(Insn::Je(target));
} }

View File

@ -241,8 +241,10 @@ pub enum JCCKinds {
JCC_JNZ, JCC_JNZ,
JCC_JZ, JCC_JZ,
JCC_JE, JCC_JE,
JCC_JB,
JCC_JBE, JCC_JBE,
JCC_JNA, JCC_JNA,
JCC_JNAE,
} }
#[inline(always)] #[inline(always)]
@ -1535,8 +1537,6 @@ fn gen_expandarray(
let array_reg = asm.load(array_opnd); let array_reg = asm.load(array_opnd);
let array_len_opnd = get_array_len(asm, array_reg); let array_len_opnd = get_array_len(asm, array_reg);
/*
// FIXME: JCC_JB not implemented
// Guard on the comptime/expected array length // Guard on the comptime/expected array length
if comptime_len >= num { if comptime_len >= num {
asm.comment(&format!("guard array length >= {}", num)); asm.comment(&format!("guard array length >= {}", num));
@ -1549,6 +1549,7 @@ fn gen_expandarray(
OPT_AREF_MAX_CHAIN_DEPTH, OPT_AREF_MAX_CHAIN_DEPTH,
Counter::expandarray_chain_max_depth, Counter::expandarray_chain_max_depth,
); );
} else { } else {
asm.comment(&format!("guard array length == {}", comptime_len)); asm.comment(&format!("guard array length == {}", comptime_len));
asm.cmp(array_len_opnd, comptime_len.into()); asm.cmp(array_len_opnd, comptime_len.into());
@ -1561,18 +1562,6 @@ fn gen_expandarray(
Counter::expandarray_chain_max_depth, Counter::expandarray_chain_max_depth,
); );
} }
*/
asm.comment(&format!("guard array length == {}", comptime_len));
asm.cmp(array_len_opnd, comptime_len.into());
jit_chain_guard(
JCC_JNE,
jit,
asm,
ocb,
OPT_AREF_MAX_CHAIN_DEPTH,
Counter::expandarray_chain_max_depth,
);
let array_opnd = asm.stack_pop(1); // pop after using the type info let array_opnd = asm.stack_pop(1); // pop after using the type info
@ -1908,6 +1897,7 @@ fn jit_chain_guard(
JCC_JNE | JCC_JNZ => BranchGenFn::JNZToTarget0, JCC_JNE | JCC_JNZ => BranchGenFn::JNZToTarget0,
JCC_JZ | JCC_JE => BranchGenFn::JZToTarget0, JCC_JZ | JCC_JE => BranchGenFn::JZToTarget0,
JCC_JBE | JCC_JNA => BranchGenFn::JBEToTarget0, JCC_JBE | JCC_JNA => BranchGenFn::JBEToTarget0,
JCC_JB | JCC_JNAE => BranchGenFn::JBToTarget0,
}; };
if (asm.ctx.get_chain_depth() as i32) < depth_limit { if (asm.ctx.get_chain_depth() as i32) < depth_limit {

View File

@ -474,6 +474,7 @@ pub enum BranchGenFn {
JNZToTarget0, JNZToTarget0,
JZToTarget0, JZToTarget0,
JBEToTarget0, JBEToTarget0,
JBToTarget0,
JITReturn, JITReturn,
} }
@ -527,6 +528,9 @@ impl BranchGenFn {
BranchGenFn::JBEToTarget0 => { BranchGenFn::JBEToTarget0 => {
asm.jbe(target0) asm.jbe(target0)
} }
BranchGenFn::JBToTarget0 => {
asm.jb(target0)
}
BranchGenFn::JITReturn => { BranchGenFn::JITReturn => {
asm.comment("update cfp->jit_return"); asm.comment("update cfp->jit_return");
asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), Opnd::const_ptr(target0.unwrap_code_ptr().raw_ptr())); asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), Opnd::const_ptr(target0.unwrap_code_ptr().raw_ptr()));
@ -543,6 +547,7 @@ impl BranchGenFn {
BranchGenFn::JNZToTarget0 | BranchGenFn::JNZToTarget0 |
BranchGenFn::JZToTarget0 | BranchGenFn::JZToTarget0 |
BranchGenFn::JBEToTarget0 | BranchGenFn::JBEToTarget0 |
BranchGenFn::JBToTarget0 |
BranchGenFn::JITReturn => BranchShape::Default, BranchGenFn::JITReturn => BranchShape::Default,
} }
} }
@ -563,6 +568,7 @@ impl BranchGenFn {
BranchGenFn::JNZToTarget0 | BranchGenFn::JNZToTarget0 |
BranchGenFn::JZToTarget0 | BranchGenFn::JZToTarget0 |
BranchGenFn::JBEToTarget0 | BranchGenFn::JBEToTarget0 |
BranchGenFn::JBToTarget0 |
BranchGenFn::JITReturn => { BranchGenFn::JITReturn => {
assert_eq!(new_shape, BranchShape::Default); assert_eq!(new_shape, BranchShape::Default);
} }