diff options
| author | Stan Lo <stan.lo@shopify.com> | 2025-09-19 19:52:34 +0100 |
|---|---|---|
| committer | Max Bernstein <tekknolagi@gmail.com> | 2025-09-19 17:18:59 -0400 |
| commit | 2ad3fbb9c79673bed3bad57c89f4a6fc3729c2b6 (patch) | |
| tree | 73254592ddaa70d2f71cdb18f2610c2559cb7437 | |
| parent | 642188fb87a42c04d5672f4c9d16644d6cbcb207 (diff) | |
ZJIT: Simplify NewHash HIR and Codegen
We can use `Vec<Opnd>` instead of `Vec<(Opnd, Opnd)>` in NewHash HIR
as it's the only usage of such type, which requires special handling.
| -rw-r--r-- | zjit/src/codegen.rs | 19 | ||||
| -rw-r--r-- | zjit/src/hir.rs | 29 |
2 files changed, 15 insertions, 33 deletions
diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index e0fd6cf2bd..7185c171c1 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -346,7 +346,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::Const { val: Const::Value(val) } => gen_const(*val), Insn::Const { .. } => panic!("Unexpected Const in gen_insn: {insn}"), Insn::NewArray { elements, state } => gen_new_array(asm, opnds!(elements), &function.frame_state(*state)), - Insn::NewHash { elements, state } => gen_new_hash(jit, asm, elements, &function.frame_state(*state)), + Insn::NewHash { elements, state } => gen_new_hash(jit, asm, opnds!(elements), &function.frame_state(*state)), Insn::NewRange { low, high, flag, state } => gen_new_range(jit, asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::NewRangeFixnum { low, high, flag, state } => gen_new_range_fixnum(asm, opnd!(low), opnd!(high), *flag, &function.frame_state(*state)), Insn::ArrayDup { val, state } => gen_array_dup(asm, opnd!(val), &function.frame_state(*state)), @@ -1259,7 +1259,7 @@ fn gen_new_array( fn gen_new_hash( jit: &mut JITState, asm: &mut Assembler, - elements: &[(InsnId, InsnId)], + elements: Vec<Opnd>, state: &FrameState, ) -> lir::Opnd { gen_prepare_non_leaf_call(jit, asm, state); @@ -1268,19 +1268,10 @@ fn gen_new_hash( let new_hash = asm_ccall!(asm, rb_hash_new_with_size, lir::Opnd::Imm(cap)); if !elements.is_empty() { - let mut pairs = Vec::new(); - for (key_id, val_id) in elements.iter() { - let key = jit.get_opnd(*key_id); - let val = jit.get_opnd(*val_id); - pairs.push(key); - pairs.push(val); - } - - let argv = gen_push_opnds(jit, asm, &pairs); - let argc = (elements.len() * 2) as ::std::os::raw::c_long; - asm_ccall!(asm, rb_hash_bulk_insert, lir::Opnd::Imm(argc), argv, new_hash); + let argv = gen_push_opnds(jit, asm, &elements); + asm_ccall!(asm, rb_hash_bulk_insert, elements.len().into(), argv, new_hash); - gen_pop_opnds(asm, &pairs); + gen_pop_opnds(asm, &elements); } new_hash diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 08bdd5311f..1cc0294929 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -549,7 +549,7 @@ pub enum Insn { ToNewArray { val: InsnId, state: InsnId }, NewArray { elements: Vec<InsnId>, state: InsnId }, /// NewHash contains a vec of (key, value) pairs - NewHash { elements: Vec<(InsnId,InsnId)>, state: InsnId }, + NewHash { elements: Vec<InsnId>, state: InsnId }, NewRange { low: InsnId, high: InsnId, flag: RangeType, state: InsnId }, NewRangeFixnum { low: InsnId, high: InsnId, flag: RangeType, state: InsnId }, ArrayDup { val: InsnId, state: InsnId }, @@ -816,9 +816,11 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::NewHash { elements, .. } => { write!(f, "NewHash")?; let mut prefix = " "; - for (key, value) in elements { - write!(f, "{prefix}{key}: {value}")?; - prefix = ", "; + for chunk in elements.chunks(2) { + if let [key, value] = chunk { + write!(f, "{prefix}{key}: {value}")?; + prefix = ", "; + } } Ok(()) } @@ -1462,13 +1464,7 @@ impl Function { &Defined { op_type, obj, pushval, v, state } => Defined { op_type, obj, pushval, v: find!(v), state: find!(state) }, &DefinedIvar { self_val, pushval, id, state } => DefinedIvar { self_val: find!(self_val), pushval, id, state }, &NewArray { ref elements, state } => NewArray { elements: find_vec!(elements), state: find!(state) }, - &NewHash { ref elements, state } => { - let mut found_elements = vec![]; - for &(key, value) in elements { - found_elements.push((find!(key), find!(value))); - } - NewHash { elements: found_elements, state: find!(state) } - } + &NewHash { ref elements, state } => NewHash { elements: find_vec!(elements), state: find!(state) }, &NewRange { low, high, flag, state } => NewRange { low: find!(low), high: find!(high), flag, state: find!(state) }, &NewRangeFixnum { low, high, flag, state } => NewRangeFixnum { low: find!(low), high: find!(high), flag, state: find!(state) }, &ArrayMax { ref elements, state } => ArrayMax { elements: find_vec!(elements), state: find!(state) }, @@ -2369,17 +2365,11 @@ impl Function { worklist.push_back(state); } &Insn::ArrayMax { ref elements, state } + | &Insn::NewHash { ref elements, state } | &Insn::NewArray { ref elements, state } => { worklist.extend(elements); worklist.push_back(state); } - &Insn::NewHash { ref elements, state } => { - for &(key, value) in elements { - worklist.push_back(key); - worklist.push_back(value); - } - worklist.push_back(state); - } &Insn::NewRange { low, high, state, .. } | &Insn::NewRangeFixnum { low, high, state, .. } => { worklist.push_back(low); @@ -3430,7 +3420,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> { for _ in 0..(count/2) { let value = state.stack_pop()?; let key = state.stack_pop()?; - elements.push((key, value)); + elements.push(value); + elements.push(key); } elements.reverse(); state.stack_push(fun.push_insn(block, Insn::NewHash { elements, state: exit_id })); |
