YJIT: Branch directly when nil? is known from types
This commit is contained in:
parent
d319184390
commit
5e39b3b844
Notes:
git
2022-09-10 12:30:03 +09:00
@ -3340,11 +3340,6 @@ fn gen_branchnil(
|
|||||||
gen_check_ints(asm, side_exit);
|
gen_check_ints(asm, side_exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if the value is Qnil
|
|
||||||
// RUBY_Qnil /* ...0000 1000 */
|
|
||||||
let val_opnd = ctx.stack_pop(1);
|
|
||||||
asm.cmp(val_opnd, Opnd::UImm(Qnil.into()));
|
|
||||||
|
|
||||||
// Get the branch target instruction offsets
|
// Get the branch target instruction offsets
|
||||||
let next_idx = jit_next_insn_idx(jit) as i32;
|
let next_idx = jit_next_insn_idx(jit) as i32;
|
||||||
let jump_idx = next_idx + jump_offset;
|
let jump_idx = next_idx + jump_offset;
|
||||||
@ -3357,6 +3352,16 @@ fn gen_branchnil(
|
|||||||
idx: jump_idx.try_into().unwrap(),
|
idx: jump_idx.try_into().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let val_type = ctx.get_opnd_type(StackOpnd(0));
|
||||||
|
let val_opnd = ctx.stack_pop(1);
|
||||||
|
|
||||||
|
if let Some(result) = val_type.known_nil() {
|
||||||
|
let target = if result { jump_block } else { next_block };
|
||||||
|
gen_direct_jump(jit, ctx, target, asm);
|
||||||
|
} else {
|
||||||
|
// Test if the value is Qnil
|
||||||
|
// RUBY_Qnil /* ...0000 1000 */
|
||||||
|
asm.cmp(val_opnd, Opnd::UImm(Qnil.into()));
|
||||||
// Generate the branch instructions
|
// Generate the branch instructions
|
||||||
gen_branch(
|
gen_branch(
|
||||||
jit,
|
jit,
|
||||||
@ -3369,6 +3374,7 @@ fn gen_branchnil(
|
|||||||
Some(ctx),
|
Some(ctx),
|
||||||
gen_branchnil_branch,
|
gen_branchnil_branch,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
EndBlock
|
EndBlock
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an Option with the exact value if it is known, otherwise None
|
/// Returns an Option boolean representing whether the value is truthy if known, otherwise None
|
||||||
pub fn known_truthy(&self) -> Option<bool> {
|
pub fn known_truthy(&self) -> Option<bool> {
|
||||||
match self {
|
match self {
|
||||||
Type::Nil => Some(false),
|
Type::Nil => Some(false),
|
||||||
@ -183,6 +183,16 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an Option boolean representing whether the value is equal to nil if known, otherwise None
|
||||||
|
pub fn known_nil(&self) -> Option<bool> {
|
||||||
|
match (self, self.known_truthy()) {
|
||||||
|
(Type::Nil, _) => Some(true),
|
||||||
|
(Type::False, _) => Some(false), // Qfalse is not nil
|
||||||
|
(_, Some(true)) => Some(false), // if truthy, can't be nil
|
||||||
|
(_, _) => None // otherwise unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute a difference between two value types
|
/// Compute a difference between two value types
|
||||||
/// Returns 0 if the two are the same
|
/// Returns 0 if the two are the same
|
||||||
/// Returns > 0 if different but compatible
|
/// Returns > 0 if different but compatible
|
||||||
|
Loading…
x
Reference in New Issue
Block a user