summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <tekknolagi@gmail.com>2026-05-12 12:16:59 -0400
committerGitHub <noreply@github.com>2026-05-12 16:16:59 +0000
commitf1ca69b9de6243925a00073c54e18fb5db461a10 (patch)
treef694170e850f41d328ace9260eeb09c3966e61a4
parent9e0261a9dc1efd17a4698b1a804eb3641520d9da (diff)
ZJIT: Remove unused GuardTypeNot instruction (#16926)
We changed how AnyToString worked and no longer need this instruction.
-rw-r--r--zjit/src/codegen.rs40
-rw-r--r--zjit/src/hir.rs13
-rw-r--r--zjit/src/stats.rs2
3 files changed, 0 insertions, 55 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs
index 097257ddf8..d89d3900fc 100644
--- a/zjit/src/codegen.rs
+++ b/zjit/src/codegen.rs
@@ -713,7 +713,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
Insn::RefineType { val, .. } => opnd!(val),
Insn::HasType { val, expected } => gen_has_type(jit, asm, opnd!(val), *expected),
Insn::GuardType { val, guard_type, state } => gen_guard_type(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
- Insn::GuardTypeNot { val, guard_type, state } => gen_guard_type_not(jit, asm, opnd!(val), *guard_type, &function.frame_state(*state)),
&Insn::GuardBitEquals { val, expected, reason, state, recompile } => gen_guard_bit_equals(jit, asm, opnd!(val), expected, reason, recompile, &function.frame_state(state)),
&Insn::GuardAnyBitSet { val, mask, reason, state, .. } => gen_guard_any_bit_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
&Insn::GuardNoBitsSet { val, mask, reason, state, .. } => gen_guard_no_bits_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)),
@@ -2641,45 +2640,6 @@ fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard
val
}
-fn gen_guard_type_not(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, guard_type: Type, state: &FrameState) -> lir::Opnd {
- if guard_type.is_subtype(types::String) {
- // We only exit if val *is* a String. Otherwise we fall through.
- let hir_block_id = asm.current_block().hir_block_id;
- let rpo_idx = asm.current_block().rpo_index;
-
- // Create continuation block upfront so early-out jumps can target it
- let cont_block = asm.new_block(hir_block_id, false, rpo_idx);
- let cont_edge = || Target::Block(lir::BranchEdge { target: cont_block, args: vec![] });
-
- let side = side_exit(jit, state, GuardTypeNot(guard_type));
-
- // Continue if special constant (not string)
- asm.test(val, Opnd::UImm(RUBY_IMMEDIATE_MASK as u64));
- asm.jnz(jit, cont_edge());
-
- // Continue if false (not string)
- asm.cmp(val, Qfalse.into());
- asm.je(jit, cont_edge());
-
- let val = asm.load_mem(val);
-
- let flags = asm.load(Opnd::mem(VALUE_BITS, val, RUBY_OFFSET_RBASIC_FLAGS));
- let tag = asm.and(flags, Opnd::UImm(RUBY_T_MASK as u64));
- asm.cmp(tag, Opnd::UImm(RUBY_T_STRING as u64));
- asm.je(jit, side);
-
- // Fall through to continuation block
- asm.jmp(cont_edge());
-
- asm.set_current_block(cont_block);
- let label = jit.get_label(asm, cont_block, hir_block_id);
- asm.write_label(label);
- } else {
- unimplemented!("unsupported type: {guard_type}");
- }
- val
-}
-
/// Compile an identity check with a side exit
fn gen_guard_bit_equals(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, expected: crate::hir::Const, reason: SideExitReason, recompile: Option<Recompile>, state: &FrameState) -> lir::Opnd {
if matches!(reason, SideExitReason::GuardShape(_) ) {
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index 1d8358cbad..b7eee653a6 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -518,7 +518,6 @@ pub enum SideExitReason {
FixnumMultOverflow,
FixnumLShiftOverflow,
GuardType(Type),
- GuardTypeNot(Type),
GuardShape(ShapeId),
ExpandArray,
GuardNotFrozen,
@@ -628,7 +627,6 @@ impl std::fmt::Display for SideExitReason {
SideExitReason::UnhandledNewarraySend(VM_OPT_NEWARRAY_SEND_INCLUDE_P) => write!(f, "UnhandledNewarraySend(INCLUDE_P)"),
SideExitReason::UnhandledDuparraySend(method_id) => write!(f, "UnhandledDuparraySend({method_id})"),
SideExitReason::GuardType(guard_type) => write!(f, "GuardType({guard_type})"),
- SideExitReason::GuardTypeNot(guard_type) => write!(f, "GuardTypeNot({guard_type})"),
SideExitReason::GuardNotShared => write!(f, "GuardNotShared"),
SideExitReason::PatchPoint(invariant) => write!(f, "PatchPoint({invariant})"),
_ => write!(f, "{self:?}"),
@@ -1115,7 +1113,6 @@ pub enum Insn {
/// Side-exit if val doesn't have the expected type.
GuardType { val: InsnId, guard_type: Type, state: InsnId },
- GuardTypeNot { val: InsnId, guard_type: Type, state: InsnId },
/// Side-exit if val is not the expected Const.
GuardBitEquals { val: InsnId, expected: Const, reason: SideExitReason, state: InsnId, recompile: Option<Recompile> },
/// Side-exit if (val & mask) == 0
@@ -1268,7 +1265,6 @@ macro_rules! for_each_operand_impl {
| Insn::StringCopy { val, state, .. }
| Insn::ObjectAlloc { val, state }
| Insn::GuardType { val, state, .. }
- | Insn::GuardTypeNot { val, state, .. }
| Insn::GuardBitEquals { val, state, .. }
| Insn::GuardAnyBitSet { val, state, .. }
| Insn::GuardNoBitsSet { val, state, .. }
@@ -1680,11 +1676,6 @@ impl Insn {
if guard_type.is_subtype(types::Immediate) { abstract_heaps::Empty } else { abstract_heaps::Memory },
abstract_heaps::Control
),
- Insn::GuardTypeNot { guard_type, .. }
- => Effect::read_write(
- if guard_type.is_subtype(types::Immediate) { abstract_heaps::Empty } else { abstract_heaps::Memory },
- abstract_heaps::Control
- ),
Insn::GuardBitEquals { .. } => Effect::read_write(abstract_heaps::Empty, abstract_heaps::Control),
Insn::GuardAnyBitSet { .. } => Effect::read_write(abstract_heaps::Empty, abstract_heaps::Control),
Insn::GuardNoBitsSet { .. } => Effect::read_write(abstract_heaps::Empty, abstract_heaps::Control),
@@ -2075,7 +2066,6 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
Insn::GuardType { val, guard_type, .. } => { write!(f, "GuardType {val}, {}", guard_type.print(self.ptr_map)) },
Insn::RefineType { val, new_type, .. } => { write!(f, "RefineType {val}, {}", new_type.print(self.ptr_map)) },
Insn::HasType { val, expected, .. } => { write!(f, "HasType {val}, {}", expected.print(self.ptr_map)) },
- Insn::GuardTypeNot { val, guard_type, .. } => { write!(f, "GuardTypeNot {val}, {}", guard_type.print(self.ptr_map)) },
Insn::GuardBitEquals { val, expected, .. } => { write!(f, "GuardBitEquals {val}, {}", expected.print(self.ptr_map)) },
Insn::GuardAnyBitSet { val, mask, mask_name: Some(name), .. } => { write!(f, "GuardAnyBitSet {val}, {name}={}", mask.print(self.ptr_map)) },
Insn::GuardAnyBitSet { val, mask, .. } => { write!(f, "GuardAnyBitSet {val}, {}", mask.print(self.ptr_map)) },
@@ -2905,7 +2895,6 @@ impl Function {
Insn::GuardType { val, guard_type, .. } => self.type_of(*val).intersection(*guard_type),
Insn::RefineType { val, new_type, .. } => self.type_of(*val).intersection(*new_type),
Insn::HasType { .. } => types::CBool,
- Insn::GuardTypeNot { .. } => types::BasicObject,
Insn::GuardBitEquals { val, expected, .. } => self.type_of(*val).intersection(Type::from_const(*expected)),
Insn::GuardAnyBitSet { val, .. } => self.type_of(*val),
Insn::GuardNoBitsSet { val, .. } => self.type_of(*val),
@@ -3089,7 +3078,6 @@ impl Function {
let id = self.union_find.borrow().find_const(insn);
match self.insns[id.0] {
Insn::GuardType { val, .. }
- | Insn::GuardTypeNot { val, .. }
| Insn::GuardBitEquals { val, .. }
| Insn::GuardAnyBitSet { val, .. }
| Insn::GuardNoBitsSet { val, .. } => self.chase_insn(val),
@@ -5845,7 +5833,6 @@ impl Function {
| Insn::Throw { val, .. }
| Insn::ObjToString { val, .. }
| Insn::GuardType { val, .. }
- | Insn::GuardTypeNot { val, .. }
| Insn::ToArray { val, .. }
| Insn::ToNewArray { val, .. }
| Insn::Defined { v: val, .. }
diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs
index 412dd045bf..522b74c48a 100644
--- a/zjit/src/stats.rs
+++ b/zjit/src/stats.rs
@@ -204,7 +204,6 @@ make_counters! {
exit_fixnum_div_by_zero,
exit_box_fixnum_overflow,
exit_guard_type_failure,
- exit_guard_type_not_failure,
exit_guard_bit_equals_failure,
exit_guard_int_equals_failure,
exit_guard_shape_failure,
@@ -599,7 +598,6 @@ pub fn side_exit_counter(reason: crate::hir::SideExitReason) -> Counter {
FixnumDivByZero => exit_fixnum_div_by_zero,
BoxFixnumOverflow => exit_box_fixnum_overflow,
GuardType(_) => exit_guard_type_failure,
- GuardTypeNot(_) => exit_guard_type_not_failure,
GuardShape(_) => exit_guard_shape_failure,
ExpandArray => exit_expandarray_failure,
GuardNotFrozen => exit_guard_not_frozen_failure,