Skip to content

Commit f3323b0

Browse files
authored
ZJIT: Replace Getlocal with LoadSP or GetEP+LoadField (ruby#16242)
Since `GetLocal` (for `level > 0`) is now split into `GetEP` + `LoadField`(ruby#16215), we can remove the Insn and use `LoadSP` instead for the consistency. Also removed a counter that appeared unnecessary.
1 parent 486f7fc commit f3323b0

6 files changed

Lines changed: 4340 additions & 4000 deletions

File tree

zjit.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ def stats_string
247247
:vm_write_locals_count,
248248
:vm_write_stack_count,
249249
:vm_write_to_parent_iseq_local_count,
250-
:vm_read_from_parent_iseq_local_count,
251250

252251
:guard_type_count,
253252
:guard_type_exit_ratio,

zjit/src/codegen.rs

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,6 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
570570
Insn::GetIvar { self_val, id, ic, state: _ } => gen_getivar(jit, asm, opnd!(self_val), *id, *ic),
571571
Insn::SetGlobal { id, val, state } => no_output!(gen_setglobal(jit, asm, *id, opnd!(val), &function.frame_state(*state))),
572572
Insn::GetGlobal { id, state } => gen_getglobal(jit, asm, *id, &function.frame_state(*state)),
573-
&Insn::GetLocal { ep_offset, level, use_sp, .. } => gen_getlocal(asm, ep_offset, level, use_sp),
574573
&Insn::IsBlockParamModified { ep } => gen_is_block_param_modified(asm, opnd!(ep)),
575574
&Insn::GetBlockParam { ep_offset, level, state } => gen_getblockparam(jit, asm, ep_offset, level, &function.frame_state(state)),
576575
&Insn::SetLocal { val, ep_offset, level } => no_output!(gen_setlocal(asm, opnd!(val), function.type_of(val), ep_offset, level)),
@@ -600,6 +599,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio
600599
&Insn::ArrayExtend { left, right, state } => { no_output!(gen_array_extend(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state))) },
601600
Insn::LoadPC => gen_load_pc(asm),
602601
Insn::LoadEC => gen_load_ec(),
602+
Insn::LoadSP => gen_load_sp(),
603603
&Insn::GetEP { level } => gen_get_ep(asm, level),
604604
Insn::GetLEP => gen_get_lep(jit, asm),
605605
Insn::LoadSelf => gen_load_self(),
@@ -722,26 +722,6 @@ fn gen_unbox_fixnum(asm: &mut Assembler, val: Opnd) -> Opnd {
722722
asm.rshift(val, Opnd::UImm(1))
723723
}
724724

725-
/// Get a local variable from a higher scope or the heap. `local_ep_offset` is in number of VALUEs.
726-
/// We generate this instruction with level=0 only when the local variable is on the heap, so we
727-
/// can't optimize the level=0 case using the SP register.
728-
fn gen_getlocal(asm: &mut Assembler, local_ep_offset: u32, level: u32, use_sp: bool) -> lir::Opnd {
729-
let local_ep_offset = i32::try_from(local_ep_offset).unwrap_or_else(|_| panic!("Could not convert local_ep_offset {local_ep_offset} to i32"));
730-
if level > 0 {
731-
gen_incr_counter(asm, Counter::vm_read_from_parent_iseq_local_count);
732-
}
733-
let local = if use_sp {
734-
assert_eq!(level, 0, "use_sp optimization should be used only for level=0 locals");
735-
let offset = -(SIZEOF_VALUE_I32 * (local_ep_offset + 1));
736-
Opnd::mem(64, SP, offset)
737-
} else {
738-
let ep = gen_get_ep(asm, level);
739-
let offset = -(SIZEOF_VALUE_I32 * local_ep_offset);
740-
Opnd::mem(64, ep, offset)
741-
};
742-
asm.load(local)
743-
}
744-
745725
/// Set a local variable from a higher scope or the heap. `local_ep_offset` is in number of VALUEs.
746726
/// We generate this instruction with level=0 only when the local variable is on the heap, so we
747727
/// can't optimize the level=0 case using the SP register.
@@ -1230,6 +1210,10 @@ fn gen_load_ec() -> Opnd {
12301210
EC
12311211
}
12321212

1213+
fn gen_load_sp() -> Opnd {
1214+
SP
1215+
}
1216+
12331217
fn gen_load_self() -> Opnd {
12341218
Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SELF)
12351219
}
@@ -1461,7 +1445,7 @@ fn gen_send_iseq_direct(
14611445
// which optional keyword arguments need their defaults evaluated.
14621446
// We write this to the local table slot at bits_start so that:
14631447
// 1. The interpreter can read it via checkkeyword if we side-exit
1464-
// 2. The JIT entry can read it via GetLocal
1448+
// 2. The JIT entry can read it from the callee frame slot
14651449
if unsafe { rb_get_iseq_flags_has_kw(iseq) } {
14661450
let keyword = unsafe { rb_get_iseq_body_param_keyword(iseq) };
14671451
let bits_start = unsafe { (*keyword).bits_start } as usize;

0 commit comments

Comments
 (0)