From d3f7d2c7bdc27c8168b2f4bddb11065f8fa43aef Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Wed, 8 Apr 2026 13:34:34 -0400 Subject: ZJIT: Pull load out of IsBlockParamModified (#16673) This makes IsBlockParamModified pure and the loads more understandable to load-store forwarding. --- zjit/src/codegen.rs | 5 +- zjit/src/cruby.rs | 1 + zjit/src/hir.rs | 28 +++-- zjit/src/hir/opt_tests.rs | 195 +++++++++++++++--------------- zjit/src/hir/tests.rs | 295 ++++++++++++++++++++++++---------------------- 5 files changed, 278 insertions(+), 246 deletions(-) diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index 46b24e583b..5df020f4f5 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -731,7 +731,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio Insn::GetIvar { self_val, id, ic, state: _ } => gen_getivar(jit, asm, opnd!(self_val), *id, *ic), Insn::SetGlobal { id, val, state } => no_output!(gen_setglobal(jit, asm, *id, opnd!(val), &function.frame_state(*state))), Insn::GetGlobal { id, state } => gen_getglobal(jit, asm, *id, &function.frame_state(*state)), - &Insn::IsBlockParamModified { ep } => gen_is_block_param_modified(asm, opnd!(ep)), + &Insn::IsBlockParamModified { flags } => gen_is_block_param_modified(asm, opnd!(flags)), &Insn::GetBlockParam { ep_offset, level, state } => gen_getblockparam(jit, asm, ep_offset, level, &function.frame_state(state)), &Insn::SetLocal { val, ep_offset, level } => no_output!(gen_setlocal(asm, opnd!(val), function.type_of(val), ep_offset, level)), Insn::GetConstant { klass, id, allow_nil, state } => gen_getconstant(jit, asm, opnd!(klass), *id, opnd!(allow_nil), &function.frame_state(*state)), @@ -896,8 +896,7 @@ fn gen_setlocal(asm: &mut Assembler, val: Opnd, val_type: Type, local_ep_offset: } /// Returns 1 (as CBool) when VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM is set; returns 0 otherwise. -fn gen_is_block_param_modified(asm: &mut Assembler, ep: Opnd) -> Opnd { - let flags = asm.load(Opnd::mem(VALUE_BITS, ep, SIZEOF_VALUE_I32 * (VM_ENV_DATA_INDEX_FLAGS as i32))); +fn gen_is_block_param_modified(asm: &mut Assembler, flags: Opnd) -> Opnd { asm.test(flags, VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM.into()); asm.csel_nz(Opnd::Imm(1), Opnd::Imm(0)) } diff --git a/zjit/src/cruby.rs b/zjit/src/cruby.rs index 38c8044f8f..6ea041d72f 100644 --- a/zjit/src/cruby.rs +++ b/zjit/src/cruby.rs @@ -1564,6 +1564,7 @@ pub(crate) mod ids { name: _env_data_index_specval name: _ep_method_entry name: _ep_specval + name: _ep_flags name: _rbasic_flags name: RUBY_FL_FREEZE name: RUBY_ELTS_SHARED diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 73fb894044..02b99a6d78 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -925,9 +925,9 @@ pub enum Insn { StoreField { recv: InsnId, id: ID, offset: i32, val: InsnId }, WriteBarrier { recv: InsnId, val: InsnId }, - /// Check whether VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM is set in the environment flags. + /// Check whether VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM is set in the (already loaded) environment flags. /// Returns CBool (0/1). - IsBlockParamModified { ep: InsnId }, + IsBlockParamModified { flags: InsnId }, /// Get the block parameter as a Proc. GetBlockParam { level: u32, ep_offset: u32, state: InsnId }, /// Set a local variable in a higher scope or the heap @@ -1162,8 +1162,8 @@ macro_rules! for_each_operand_impl { Insn::IsBlockGiven { lep } => { $visit_one!(lep); } - Insn::IsBlockParamModified { ep } => { - $visit_one!(ep); + Insn::IsBlockParamModified { flags } => { + $visit_one!(flags); } Insn::CheckMatch { target, pattern, state, .. } => { $visit_one!(target); @@ -1588,7 +1588,7 @@ impl Insn { Insn::GetSpecialNumber { .. } => effects::Any, Insn::GetClassVar { .. } => effects::Any, Insn::SetClassVar { .. } => effects::Any, - Insn::IsBlockParamModified { .. } => effects::Any, + Insn::IsBlockParamModified { .. } => effects::Empty, Insn::GetBlockParam { .. } => effects::Any, Insn::Snapshot { .. } => effects::Empty, Insn::Jump(_) => effects::Any, @@ -2141,8 +2141,8 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { Insn::SetIvar { self_val, id, val, .. } => write!(f, "SetIvar {self_val}, :{}, {val}", id.contents_lossy()), Insn::GetGlobal { id, .. } => write!(f, "GetGlobal :{}", id.contents_lossy()), Insn::SetGlobal { id, val, .. } => write!(f, "SetGlobal :{}, {val}", id.contents_lossy()), - &Insn::IsBlockParamModified { ep } => { - write!(f, "IsBlockParamModified {ep}") + &Insn::IsBlockParamModified { flags } => { + write!(f, "IsBlockParamModified {flags}") }, &Insn::SetLocal { val, level, ep_offset } => { let name = get_local_var_name_for_printer(self.iseq, level, ep_offset).map_or(String::new(), |x| format!("{x}, ")); @@ -2833,7 +2833,7 @@ impl Function { &GuardGreaterEq { left, right, reason, state } => GuardGreaterEq { left: find!(left), right: find!(right), reason, state }, &GuardLess { left, right, state } => GuardLess { left: find!(left), right: find!(right), state }, &IsBlockGiven { lep } => IsBlockGiven { lep: find!(lep) }, - &IsBlockParamModified { ep } => IsBlockParamModified { ep: find!(ep) }, + &IsBlockParamModified { flags } => IsBlockParamModified { flags: find!(flags) }, &GetBlockParam { level, ep_offset, state } => GetBlockParam { level, ep_offset, state: find!(state) }, &FixnumAdd { left, right, state } => FixnumAdd { left: find!(left), right: find!(right), state }, &FixnumSub { left, right, state } => FixnumSub { left: find!(left), right: find!(right), state }, @@ -3620,6 +3620,10 @@ impl Function { self.push_insn(block, Insn::LoadField { recv, id: ID!(_rbasic_flags), offset: RUBY_OFFSET_RBASIC_FLAGS, return_type: types::CUInt64 }) } + fn load_ep_flags(&mut self, block: BlockId, ep: InsnId) -> InsnId { + self.push_insn(block, Insn::LoadField { recv: ep, id: ID!(_ep_flags), offset: SIZEOF_VALUE_I32 * (VM_ENV_DATA_INDEX_FLAGS as i32), return_type: types::CUInt64 }) + } + pub fn guard_not_frozen(&mut self, block: BlockId, recv: InsnId, state: InsnId) { let flags = self.load_rbasic_flags(block, recv); self.push_insn(block, Insn::GuardNoBitsSet { val: flags, mask: Const::CUInt64(RUBY_FL_FREEZE as u64), mask_name: Some(ID!(RUBY_FL_FREEZE)), reason: SideExitReason::GuardNotFrozen, state }); @@ -6167,7 +6171,6 @@ impl Function { | Insn::LoadField { .. } | Insn::GetConstantPath { .. } | Insn::IsBlockGiven { .. } - | Insn::IsBlockParamModified { .. } | Insn::GetGlobal { .. } | Insn::LoadPC | Insn::LoadSP @@ -6456,6 +6459,7 @@ impl Function { } Insn::RefineType { .. } => Ok(()), Insn::HasType { val, .. } => self.assert_subtype(insn_id, val, types::BasicObject), + Insn::IsBlockParamModified { flags } => self.assert_subtype(insn_id, flags, types::CUInt64), } } @@ -7612,7 +7616,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { let join_local = if level == 0 { Some(fun.push_insn(join_block, Insn::Param)) } else { None }; let ep = fun.push_insn(block, Insn::GetEP { level }); - let is_modified = fun.push_insn(block, Insn::IsBlockParamModified { ep }); + let flags = fun.load_ep_flags(block, ep); + let is_modified = fun.push_insn(block, Insn::IsBlockParamModified { flags }); fun.push_insn(block, Insn::IfTrue { val: is_modified, target: BranchEdge { target: modified_block, args: vec![] }}); fun.push_insn(block, Insn::Jump(BranchEdge { target: unmodified_block, args: vec![] })); @@ -7781,7 +7786,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { let join_param = fun.push_insn(join_block, Insn::Param); let ep = fun.push_insn(block, Insn::GetEP { level }); - let is_modified = fun.push_insn(block, Insn::IsBlockParamModified { ep }); + let flags = fun.load_ep_flags(block, ep); + let is_modified = fun.push_insn(block, Insn::IsBlockParamModified { flags }); fun.push_insn(block, Insn::IfTrue { val: is_modified, diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 2f7ce00b69..43e35352b2 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -4729,15 +4729,16 @@ mod hir_opt_tests { Jump bb3(v6, v7) bb3(v9:BasicObject, v10:BasicObject): v17:CPtr = GetEP 0 - v18:CBool = IsBlockParamModified v17 - IfTrue v18, bb4() - v23:CInt64 = LoadField v17, :_env_data_index_specval@0x1001 - v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) - v25:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v25, v10) + v18:CUInt64 = LoadField v17, :_ep_flags@0x1001 + v19:CBool = IsBlockParamModified v18 + IfTrue v19, bb4() + v24:CInt64 = LoadField v17, :_env_data_index_specval@0x1002 + v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) + v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v26, v10) bb4(): - v21:BasicObject = LoadField v17, :block@0x1010 - Jump bb6(v21, v21) + v22:BasicObject = LoadField v17, :block@0x1010 + Jump bb6(v22, v22) bb6(v15:BasicObject, v16:BasicObject): SideExit NoProfileSend recompile "); @@ -4769,25 +4770,27 @@ mod hir_opt_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:NilClass): v18:CPtr = GetEP 0 - v19:CBool = IsBlockParamModified v18 - IfTrue v19, bb4() - v24:BasicObject = GetBlockParam :block, l0, EP@4 - Jump bb6(v24) + v19:CUInt64 = LoadField v18, :_ep_flags@0x1001 + v20:CBool = IsBlockParamModified v19 + IfTrue v20, bb4() + v25:BasicObject = GetBlockParam :block, l0, EP@4 + Jump bb6(v25) bb4(): - v22:BasicObject = LoadField v18, :block@0x1001 - Jump bb6(v22) + v23:BasicObject = LoadField v18, :block@0x1002 + Jump bb6(v23) bb6(v17:BasicObject): - v32:CPtr = GetEP 0 - v33:CBool = IsBlockParamModified v32 - IfTrue v33, bb7() - v38:CInt64 = LoadField v32, :_env_data_index_specval@0x1002 - v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) - v40:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb9(v40, v17) + v33:CPtr = GetEP 0 + v34:CUInt64 = LoadField v33, :_ep_flags@0x1001 + v35:CBool = IsBlockParamModified v34 + IfTrue v35, bb7() + v40:CInt64 = LoadField v33, :_env_data_index_specval@0x1003 + v41:CInt64 = GuardAnyBitSet v40, CUInt64(1) + v42:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb9(v42, v17) bb7(): - v36:BasicObject = LoadField v32, :block@0x1001 - Jump bb9(v36, v36) - bb9(v30:BasicObject, v31:BasicObject): + v38:BasicObject = LoadField v33, :block@0x1002 + Jump bb9(v38, v38) + bb9(v31:BasicObject, v32:BasicObject): SideExit NoProfileSend recompile "); } @@ -4816,25 +4819,27 @@ mod hir_opt_tests { Jump bb3(v5, v6) bb3(v8:BasicObject, v9:NilClass): v14:CPtr = GetEP 1 - v15:CBool = IsBlockParamModified v14 - IfTrue v15, bb4() - v20:BasicObject = GetBlockParam :block, l1, EP@3 - Jump bb6(v20) + v15:CUInt64 = LoadField v14, :_ep_flags@0x1000 + v16:CBool = IsBlockParamModified v15 + IfTrue v16, bb4() + v21:BasicObject = GetBlockParam :block, l1, EP@3 + Jump bb6(v21) bb4(): - v18:BasicObject = LoadField v14, :block@0x1000 - Jump bb6(v18) + v19:BasicObject = LoadField v14, :block@0x1001 + Jump bb6(v19) bb6(v13:BasicObject): - v27:CPtr = GetEP 1 - v28:CBool = IsBlockParamModified v27 - IfTrue v28, bb7() - v33:CInt64 = LoadField v27, :_env_data_index_specval@0x1001 - v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) - v35:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb9(v35) + v28:CPtr = GetEP 1 + v29:CUInt64 = LoadField v28, :_ep_flags@0x1000 + v30:CBool = IsBlockParamModified v29 + IfTrue v30, bb7() + v35:CInt64 = LoadField v28, :_env_data_index_specval@0x1002 + v36:CInt64 = GuardAnyBitSet v35, CUInt64(1) + v37:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb9(v37) bb7(): - v31:BasicObject = LoadField v27, :block@0x1000 - Jump bb9(v31) - bb9(v26:BasicObject): + v33:BasicObject = LoadField v28, :block@0x1001 + Jump bb9(v33) + bb9(v27:BasicObject): SideExit NoProfileSend recompile "); } @@ -4914,13 +4919,14 @@ mod hir_opt_tests { Jump bb3(v6, v7) bb3(v9:BasicObject, v10:BasicObject): v15:CPtr = GetEP 0 - v16:CBool = IsBlockParamModified v15 - IfTrue v16, bb4() - v21:BasicObject = GetBlockParam :block, l0, EP@3 - Jump bb6(v21) + v16:CUInt64 = LoadField v15, :_ep_flags@0x1001 + v17:CBool = IsBlockParamModified v16 + IfTrue v17, bb4() + v22:BasicObject = GetBlockParam :block, l0, EP@3 + Jump bb6(v22) bb4(): - v19:BasicObject = LoadField v15, :block@0x1001 - Jump bb6(v19) + v20:BasicObject = LoadField v15, :block@0x1002 + Jump bb6(v20) bb6(v14:BasicObject): CheckInterrupts Return v14 @@ -4948,13 +4954,14 @@ mod hir_opt_tests { Jump bb3(v4) bb3(v6:BasicObject): v11:CPtr = GetEP 1 - v12:CBool = IsBlockParamModified v11 - IfTrue v12, bb4() - v17:BasicObject = GetBlockParam :block, l1, EP@3 - Jump bb6(v17) + v12:CUInt64 = LoadField v11, :_ep_flags@0x1000 + v13:CBool = IsBlockParamModified v12 + IfTrue v13, bb4() + v18:BasicObject = GetBlockParam :block, l1, EP@3 + Jump bb6(v18) bb4(): - v15:BasicObject = LoadField v11, :block@0x1000 - Jump bb6(v15) + v16:BasicObject = LoadField v11, :block@0x1001 + Jump bb6(v16) bb6(v10:BasicObject): CheckInterrupts Return v10 @@ -8204,19 +8211,20 @@ mod hir_opt_tests { bb3(v9:BasicObject, v10:BasicObject): v14:ArrayExact = NewArray v18:CPtr = GetEP 0 - v19:CBool = IsBlockParamModified v18 - IfTrue v19, bb4() - v24:CInt64 = LoadField v18, :_env_data_index_specval@0x1001 - v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) - v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v26, v10) + v19:CUInt64 = LoadField v18, :_ep_flags@0x1001 + v20:CBool = IsBlockParamModified v19 + IfTrue v20, bb4() + v25:CInt64 = LoadField v18, :_env_data_index_specval@0x1002 + v26:CInt64 = GuardAnyBitSet v25, CUInt64(1) + v27:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v27, v10) bb4(): - v22:BasicObject = LoadField v18, :block@0x1010 - Jump bb6(v22, v22) + v23:BasicObject = LoadField v18, :block@0x1010 + Jump bb6(v23, v23) bb6(v16:BasicObject, v17:BasicObject): - v29:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing + v30:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing CheckInterrupts - Return v29 + Return v30 "); } @@ -8242,19 +8250,20 @@ mod hir_opt_tests { bb3(v9:BasicObject, v10:BasicObject): v14:ArrayExact = NewArray v18:CPtr = GetEP 0 - v19:CBool = IsBlockParamModified v18 - IfTrue v19, bb4() - v24:CInt64 = LoadField v18, :_env_data_index_specval@0x1001 - v25:CInt64[0] = GuardBitEquals v24, CInt64(0) - v26:NilClass = Const Value(nil) - Jump bb6(v26, v10) + v19:CUInt64 = LoadField v18, :_ep_flags@0x1001 + v20:CBool = IsBlockParamModified v19 + IfTrue v20, bb4() + v25:CInt64 = LoadField v18, :_env_data_index_specval@0x1002 + v26:CInt64[0] = GuardBitEquals v25, CInt64(0) + v27:NilClass = Const Value(nil) + Jump bb6(v27, v10) bb4(): - v22:BasicObject = LoadField v18, :block@0x1002 - Jump bb6(v22, v22) + v23:BasicObject = LoadField v18, :block@0x1003 + Jump bb6(v23, v23) bb6(v16:BasicObject, v17:BasicObject): - v29:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing + v30:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing CheckInterrupts - Return v29 + Return v30 "); } @@ -8281,19 +8290,20 @@ mod hir_opt_tests { bb3(v6:BasicObject): v10:ArrayExact = NewArray v13:CPtr = GetEP 1 - v14:CBool = IsBlockParamModified v13 - IfTrue v14, bb4() - v19:CInt64 = LoadField v13, :_env_data_index_specval@0x1000 - v20:CInt64 = GuardAnyBitSet v19, CUInt64(1) - v21:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v21) + v14:CUInt64 = LoadField v13, :_ep_flags@0x1000 + v15:CBool = IsBlockParamModified v14 + IfTrue v15, bb4() + v20:CInt64 = LoadField v13, :_env_data_index_specval@0x1001 + v21:CInt64 = GuardAnyBitSet v20, CUInt64(1) + v22:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v22) bb4(): - v17:BasicObject = LoadField v13, :block@0x1010 - Jump bb6(v17) + v18:BasicObject = LoadField v13, :block@0x1010 + Jump bb6(v18) bb6(v12:BasicObject): - v24:BasicObject = Send v10, &block, :map, v12 # SendFallbackReason: Complex argument passing + v25:BasicObject = Send v10, &block, :map, v12 # SendFallbackReason: Complex argument passing CheckInterrupts - Return v24 + Return v25 "); } @@ -11768,19 +11778,20 @@ mod hir_opt_tests { bb3(v9:BasicObject, v10:BasicObject): v14:ArrayExact = NewArray v18:CPtr = GetEP 0 - v19:CBool = IsBlockParamModified v18 - IfTrue v19, bb4() - v24:CInt64 = LoadField v18, :_env_data_index_specval@0x1001 - v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) - v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v26, v10) + v19:CUInt64 = LoadField v18, :_ep_flags@0x1001 + v20:CBool = IsBlockParamModified v19 + IfTrue v20, bb4() + v25:CInt64 = LoadField v18, :_env_data_index_specval@0x1002 + v26:CInt64 = GuardAnyBitSet v25, CUInt64(1) + v27:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v27, v10) bb4(): - v22:BasicObject = LoadField v18, :block@0x1010 - Jump bb6(v22, v22) + v23:BasicObject = LoadField v18, :block@0x1010 + Jump bb6(v23, v23) bb6(v16:BasicObject, v17:BasicObject): - v29:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing + v30:BasicObject = Send v14, &block, :map, v16 # SendFallbackReason: Complex argument passing CheckInterrupts - Return v29 + Return v30 "); } diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index afaa50dd11..90337c1778 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -2467,17 +2467,18 @@ pub(crate) mod hir_build_tests { v29:ArrayExact = ToArray v19 PatchPoint NoEPEscape(test) v36:CPtr = GetEP 0 - v37:CBool = IsBlockParamModified v36 - IfTrue v37, bb4() + v37:CUInt64 = LoadField v36, :_ep_flags@0x1004 + v38:CBool = IsBlockParamModified v37 + IfTrue v38, bb4() Jump bb5() bb4(): - v40:BasicObject = LoadField v36, :&@0x1004 - Jump bb6(v40, v40) + v41:BasicObject = LoadField v36, :&@0x1005 + Jump bb6(v41, v41) bb5(): - v42:CInt64 = LoadField v36, :_env_data_index_specval@0x1005 - v43:CInt64 = GuardAnyBitSet v42, CUInt64(1) - v44:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v44, v21) + v43:CInt64 = LoadField v36, :_env_data_index_specval@0x1006 + v44:CInt64 = GuardAnyBitSet v43, CUInt64(1) + v45:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v45, v21) bb6(v34:BasicObject, v35:BasicObject): SideExit SplatKwNotProfiled "); @@ -3390,15 +3391,16 @@ pub(crate) mod hir_build_tests { Jump bb3(v6, v7) bb3(v9:BasicObject, v10:BasicObject): v15:CPtr = GetEP 0 - v16:CBool = IsBlockParamModified v15 - IfTrue v16, bb4() + v16:CUInt64 = LoadField v15, :_ep_flags@0x1001 + v17:CBool = IsBlockParamModified v16 + IfTrue v17, bb4() Jump bb5() bb4(): - v19:BasicObject = LoadField v15, :block@0x1001 - Jump bb6(v19) + v20:BasicObject = LoadField v15, :block@0x1002 + Jump bb6(v20) bb5(): - v21:BasicObject = GetBlockParam :block, l0, EP@3 - Jump bb6(v21) + v22:BasicObject = GetBlockParam :block, l0, EP@3 + Jump bb6(v22) bb6(v14:BasicObject): CheckInterrupts Return v14 @@ -3426,21 +3428,22 @@ pub(crate) mod hir_build_tests { Jump bb3(v6, v7) bb3(v9:BasicObject, v10:BasicObject): v17:CPtr = GetEP 0 - v18:CBool = IsBlockParamModified v17 - IfTrue v18, bb4() + v18:CUInt64 = LoadField v17, :_ep_flags@0x1001 + v19:CBool = IsBlockParamModified v18 + IfTrue v19, bb4() Jump bb5() bb4(): - v21:BasicObject = LoadField v17, :block@0x1001 - Jump bb6(v21, v21) + v22:BasicObject = LoadField v17, :block@0x1002 + Jump bb6(v22, v22) bb5(): - v23:CInt64 = LoadField v17, :_env_data_index_specval@0x1002 - v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) - v25:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v25, v10) + v24:CInt64 = LoadField v17, :_env_data_index_specval@0x1003 + v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) + v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v26, v10) bb6(v15:BasicObject, v16:BasicObject): - v28:BasicObject = Send v9, &block, :tap, v15 # SendFallbackReason: Uncategorized(send) + v29:BasicObject = Send v9, &block, :tap, v15 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v28 + Return v29 "); } @@ -3470,32 +3473,34 @@ pub(crate) mod hir_build_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:NilClass): v18:CPtr = GetEP 0 - v19:CBool = IsBlockParamModified v18 - IfTrue v19, bb4() + v19:CUInt64 = LoadField v18, :_ep_flags@0x1001 + v20:CBool = IsBlockParamModified v19 + IfTrue v20, bb4() Jump bb5() bb4(): - v22:BasicObject = LoadField v18, :block@0x1001 - Jump bb6(v22) + v23:BasicObject = LoadField v18, :block@0x1002 + Jump bb6(v23) bb5(): - v24:BasicObject = GetBlockParam :block, l0, EP@4 - Jump bb6(v24) + v25:BasicObject = GetBlockParam :block, l0, EP@4 + Jump bb6(v25) bb6(v17:BasicObject): - v32:CPtr = GetEP 0 - v33:CBool = IsBlockParamModified v32 - IfTrue v33, bb7() + v33:CPtr = GetEP 0 + v34:CUInt64 = LoadField v33, :_ep_flags@0x1001 + v35:CBool = IsBlockParamModified v34 + IfTrue v35, bb7() Jump bb8() bb7(): - v36:BasicObject = LoadField v32, :block@0x1001 - Jump bb9(v36, v36) + v38:BasicObject = LoadField v33, :block@0x1002 + Jump bb9(v38, v38) bb8(): - v38:CInt64 = LoadField v32, :_env_data_index_specval@0x1002 - v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) - v40:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb9(v40, v17) - bb9(v30:BasicObject, v31:BasicObject): - v43:BasicObject = Send v11, &block, :tap, v30 # SendFallbackReason: Uncategorized(send) + v40:CInt64 = LoadField v33, :_env_data_index_specval@0x1003 + v41:CInt64 = GuardAnyBitSet v40, CUInt64(1) + v42:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb9(v42, v17) + bb9(v31:BasicObject, v32:BasicObject): + v45:BasicObject = Send v11, &block, :tap, v31 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v43 + Return v45 "); } @@ -3523,32 +3528,34 @@ pub(crate) mod hir_build_tests { Jump bb3(v5, v6) bb3(v8:BasicObject, v9:NilClass): v14:CPtr = GetEP 1 - v15:CBool = IsBlockParamModified v14 - IfTrue v15, bb4() + v15:CUInt64 = LoadField v14, :_ep_flags@0x1000 + v16:CBool = IsBlockParamModified v15 + IfTrue v16, bb4() Jump bb5() bb4(): - v18:BasicObject = LoadField v14, :block@0x1000 - Jump bb6(v18) + v19:BasicObject = LoadField v14, :block@0x1001 + Jump bb6(v19) bb5(): - v20:BasicObject = GetBlockParam :block, l1, EP@3 - Jump bb6(v20) + v21:BasicObject = GetBlockParam :block, l1, EP@3 + Jump bb6(v21) bb6(v13:BasicObject): - v27:CPtr = GetEP 1 - v28:CBool = IsBlockParamModified v27 - IfTrue v28, bb7() + v28:CPtr = GetEP 1 + v29:CUInt64 = LoadField v28, :_ep_flags@0x1000 + v30:CBool = IsBlockParamModified v29 + IfTrue v30, bb7() Jump bb8() bb7(): - v31:BasicObject = LoadField v27, :block@0x1000 - Jump bb9(v31) + v33:BasicObject = LoadField v28, :block@0x1001 + Jump bb9(v33) bb8(): - v33:CInt64 = LoadField v27, :_env_data_index_specval@0x1001 - v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) - v35:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb9(v35) - bb9(v26:BasicObject): - v38:BasicObject = Send v8, &block, :tap, v26 # SendFallbackReason: Uncategorized(send) + v35:CInt64 = LoadField v28, :_env_data_index_specval@0x1002 + v36:CInt64 = GuardAnyBitSet v35, CUInt64(1) + v37:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb9(v37) + bb9(v27:BasicObject): + v40:BasicObject = Send v8, &block, :tap, v27 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v38 + Return v40 "); } @@ -3630,15 +3637,16 @@ pub(crate) mod hir_build_tests { Jump bb3(v4) bb3(v6:BasicObject): v11:CPtr = GetEP 1 - v12:CBool = IsBlockParamModified v11 - IfTrue v12, bb4() + v12:CUInt64 = LoadField v11, :_ep_flags@0x1000 + v13:CBool = IsBlockParamModified v12 + IfTrue v13, bb4() Jump bb5() bb4(): - v15:BasicObject = LoadField v11, :block@0x1000 - Jump bb6(v15) + v16:BasicObject = LoadField v11, :block@0x1001 + Jump bb6(v16) bb5(): - v17:BasicObject = GetBlockParam :block, l1, EP@3 - Jump bb6(v17) + v18:BasicObject = GetBlockParam :block, l1, EP@3 + Jump bb6(v18) bb6(v10:BasicObject): CheckInterrupts Return v10 @@ -3735,17 +3743,18 @@ pub(crate) mod hir_build_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject): v21:CPtr = GetEP 0 - v22:CBool = IsBlockParamModified v21 - IfTrue v22, bb4() + v22:CUInt64 = LoadField v21, :_ep_flags@0x1002 + v23:CBool = IsBlockParamModified v22 + IfTrue v23, bb4() Jump bb5() bb4(): - v25:BasicObject = LoadField v21, :b@0x1002 - Jump bb6(v25, v25) + v26:BasicObject = LoadField v21, :b@0x1003 + Jump bb6(v26, v26) bb5(): - v27:CInt64 = LoadField v21, :_env_data_index_specval@0x1003 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) - v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v29, v13) + v28:CInt64 = LoadField v21, :_env_data_index_specval@0x1004 + v29:CInt64 = GuardAnyBitSet v28, CUInt64(1) + v30:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v30, v13) bb6(v19:BasicObject, v20:BasicObject): SideExit SplatKwNotProfiled "); @@ -3784,22 +3793,23 @@ pub(crate) mod hir_build_tests { v29:ArrayExact = ToArray v19 PatchPoint NoEPEscape(test) v36:CPtr = GetEP 0 - v37:CBool = IsBlockParamModified v36 - IfTrue v37, bb4() + v37:CUInt64 = LoadField v36, :_ep_flags@0x1004 + v38:CBool = IsBlockParamModified v37 + IfTrue v38, bb4() Jump bb5() bb4(): - v40:BasicObject = LoadField v36, :&@0x1004 - Jump bb6(v40, v40) + v41:BasicObject = LoadField v36, :&@0x1005 + Jump bb6(v41, v41) bb5(): - v42:CInt64 = LoadField v36, :_env_data_index_specval@0x1005 - v43:CInt64[0] = GuardBitEquals v42, CInt64(0) - v44:NilClass = Const Value(nil) - Jump bb6(v44, v21) + v43:CInt64 = LoadField v36, :_env_data_index_specval@0x1006 + v44:CInt64[0] = GuardBitEquals v43, CInt64(0) + v45:NilClass = Const Value(nil) + Jump bb6(v45, v21) bb6(v34:BasicObject, v35:BasicObject): - v47:NilClass = GuardType v20, NilClass - v49:BasicObject = Send v17, &block, :foo, v18, v29, v47, v34 # SendFallbackReason: Uncategorized(send) + v48:NilClass = GuardType v20, NilClass + v50:BasicObject = Send v17, &block, :foo, v18, v29, v48, v34 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v49 + Return v50 "); } @@ -3828,22 +3838,23 @@ pub(crate) mod hir_build_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject): v21:CPtr = GetEP 0 - v22:CBool = IsBlockParamModified v21 - IfTrue v22, bb4() + v22:CUInt64 = LoadField v21, :_ep_flags@0x1002 + v23:CBool = IsBlockParamModified v22 + IfTrue v23, bb4() Jump bb5() bb4(): - v25:BasicObject = LoadField v21, :b@0x1002 - Jump bb6(v25, v25) + v26:BasicObject = LoadField v21, :b@0x1003 + Jump bb6(v26, v26) bb5(): - v27:CInt64 = LoadField v21, :_env_data_index_specval@0x1003 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) - v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v29, v13) + v28:CInt64 = LoadField v21, :_env_data_index_specval@0x1004 + v29:CInt64 = GuardAnyBitSet v28, CUInt64(1) + v30:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v30, v13) bb6(v19:BasicObject, v20:BasicObject): - v32:HashExact = GuardType v12, HashExact - v34:BasicObject = Send v11, &block, :foo, v32, v19 # SendFallbackReason: Uncategorized(send) + v33:HashExact = GuardType v12, HashExact + v35:BasicObject = Send v11, &block, :foo, v33, v19 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v34 + Return v35 "); } @@ -3872,22 +3883,23 @@ pub(crate) mod hir_build_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject): v21:CPtr = GetEP 0 - v22:CBool = IsBlockParamModified v21 - IfTrue v22, bb4() + v22:CUInt64 = LoadField v21, :_ep_flags@0x1002 + v23:CBool = IsBlockParamModified v22 + IfTrue v23, bb4() Jump bb5() bb4(): - v25:BasicObject = LoadField v21, :b@0x1002 - Jump bb6(v25, v25) + v26:BasicObject = LoadField v21, :b@0x1003 + Jump bb6(v26, v26) bb5(): - v27:CInt64 = LoadField v21, :_env_data_index_specval@0x1003 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) - v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v29, v13) + v28:CInt64 = LoadField v21, :_env_data_index_specval@0x1004 + v29:CInt64 = GuardAnyBitSet v28, CUInt64(1) + v30:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v30, v13) bb6(v19:BasicObject, v20:BasicObject): - v32:HashExact = GuardType v12, HashExact - v34:BasicObject = Send v11, &block, :foo, v32, v19 # SendFallbackReason: Uncategorized(send) + v33:HashExact = GuardType v12, HashExact + v35:BasicObject = Send v11, &block, :foo, v33, v19 # SendFallbackReason: Uncategorized(send) CheckInterrupts - Return v34 + Return v35 "); } @@ -3926,17 +3938,18 @@ pub(crate) mod hir_build_tests { v29:ArrayExact = ToArray v19 PatchPoint NoEPEscape(test) v36:CPtr = GetEP 0 - v37:CBool = IsBlockParamModified v36 - IfTrue v37, bb4() + v37:CUInt64 = LoadField v36, :_ep_flags@0x1004 + v38:CBool = IsBlockParamModified v37 + IfTrue v38, bb4() Jump bb5() bb4(): - v40:BasicObject = LoadField v36, :&@0x1004 - Jump bb6(v40, v40) + v41:BasicObject = LoadField v36, :&@0x1005 + Jump bb6(v41, v41) bb5(): - v42:CInt64 = LoadField v36, :_env_data_index_specval@0x1005 - v43:CInt64[0] = GuardBitEquals v42, CInt64(0) - v44:NilClass = Const Value(nil) - Jump bb6(v44, v21) + v43:CInt64 = LoadField v36, :_env_data_index_specval@0x1006 + v44:CInt64[0] = GuardBitEquals v43, CInt64(0) + v45:NilClass = Const Value(nil) + Jump bb6(v45, v21) bb6(v34:BasicObject, v35:BasicObject): SideExit SplatKwPolymorphic "); @@ -3969,17 +3982,18 @@ pub(crate) mod hir_build_tests { Jump bb3(v7, v8, v9) bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject): v21:CPtr = GetEP 0 - v22:CBool = IsBlockParamModified v21 - IfTrue v22, bb4() + v22:CUInt64 = LoadField v21, :_ep_flags@0x1002 + v23:CBool = IsBlockParamModified v22 + IfTrue v23, bb4() Jump bb5() bb4(): - v25:BasicObject = LoadField v21, :block@0x1002 - Jump bb6(v25, v25) + v26:BasicObject = LoadField v21, :block@0x1003 + Jump bb6(v26, v26) bb5(): - v27:CInt64 = LoadField v21, :_env_data_index_specval@0x1003 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) - v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb6(v29, v13) + v28:CInt64 = LoadField v21, :_env_data_index_specval@0x1004 + v29:CInt64 = GuardAnyBitSet v28, CUInt64(1) + v30:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb6(v30, v13) bb6(v19:BasicObject, v20:BasicObject): SideExit SplatKwNotNilOrHash "); @@ -4659,30 +4673,31 @@ pub(crate) mod hir_build_tests { v27:BasicObject = InvokeBuiltin dir_s_open, v18, v19, v20 PatchPoint NoEPEscape(open) v35:CPtr = GetEP 0 - v36:CBool = IsBlockParamModified v35 - IfTrue v36, bb5() + v36:CUInt64 = LoadField v35, :_ep_flags@0x1004 + v37:CBool = IsBlockParamModified v36 + IfTrue v37, bb5() Jump bb6() bb5(): - v39:BasicObject = LoadField v35, :block@0x1004 - Jump bb7(v39, v39) + v40:BasicObject = LoadField v35, :block@0x1005 + Jump bb7(v40, v40) bb6(): - v41:CInt64 = LoadField v35, :_env_data_index_specval@0x1005 - v42:CInt64 = GuardAnyBitSet v41, CUInt64(1) - v43:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) - Jump bb7(v43, v22) + v42:CInt64 = LoadField v35, :_env_data_index_specval@0x1006 + v43:CInt64 = GuardAnyBitSet v42, CUInt64(1) + v44:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) + Jump bb7(v44, v22) bb7(v33:BasicObject, v34:BasicObject): CheckInterrupts - v47:CBool = Test v33 - v48:Falsy = RefineType v33, Falsy - IfFalse v47, bb4(v18, v19, v20, v21, v34, v27) - v50:Truthy = RefineType v33, Truthy - v54:BasicObject = InvokeBlock, v27 # SendFallbackReason: InvokeBlock: not yet specialized - v57:BasicObject = InvokeBuiltin dir_s_close, v18, v27 + v48:CBool = Test v33 + v49:Falsy = RefineType v33, Falsy + IfFalse v48, bb4(v18, v19, v20, v21, v34, v27) + v51:Truthy = RefineType v33, Truthy + v55:BasicObject = InvokeBlock, v27 # SendFallbackReason: InvokeBlock: not yet specialized + v58:BasicObject = InvokeBuiltin dir_s_close, v18, v27 CheckInterrupts - Return v54 - bb4(v63:BasicObject, v64:BasicObject, v65:BasicObject, v66:BasicObject, v67:BasicObject, v68:BasicObject): + Return v55 + bb4(v64:BasicObject, v65:BasicObject, v66:BasicObject, v67:BasicObject, v68:BasicObject, v69:BasicObject): CheckInterrupts - Return v68 + Return v69 "); } -- cgit v1.2.3