ruby-changes:73205
From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 01:00:25 +0900 (JST)
Subject: [ruby-changes:73205] f833d75bee (master): Refactor YJIT branches to use PosMarker (https://github.com/Shopify/ruby/pull/333)
https://git.ruby-lang.org/ruby.git/commit/?id=f833d75bee From f833d75bee13ecb485db1591898cb871b24a2991 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maximechevalierb@g...> Date: Wed, 20 Jul 2022 14:50:00 -0400 Subject: Refactor YJIT branches to use PosMarker (https://github.com/Shopify/ruby/pull/333) * Refactor defer_compilation to use PosMarker * Port gen_direct_jump() to use PosMarker * Port gen_branch, branchunless * Port over gen_jump() * Port over branchif and branchnil * Fix use od record_boundary_patch_point in jump_to_next_insn --- yjit/src/backend/arm64/mod.rs | 3 ++ yjit/src/backend/ir.rs | 2 + yjit/src/backend/x86_64/mod.rs | 8 ++++ yjit/src/codegen.rs | 104 +++++++++++++---------------------------- yjit/src/core.rs | 96 ++++++++++++++++++------------------- 5 files changed, 94 insertions(+), 119 deletions(-) diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index c5ddbea7c1..35026a520b 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -637,6 +637,9 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/arm64/mod.rs#L637 Op::Je => { emit_conditional_jump::<{Condition::EQ}>(cb, insn.target.unwrap()); }, + Op::Jne => { + emit_conditional_jump::<{Condition::NE}>(cb, insn.target.unwrap()); + }, Op::Jbe => { emit_conditional_jump::<{Condition::LS}>(cb, insn.target.unwrap()); }, diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index 8d58da88f2..c55a8f609b 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -102,6 +102,7 @@ pub enum Op https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L102 // Low-level conditional jump instructions Jbe, Je, + Jne, Jz, Jnz, Jo, @@ -883,6 +884,7 @@ macro_rules! def_push_2_opnd_no_out { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L884 def_push_1_opnd_no_out!(jmp_opnd, Op::JmpOpnd); def_push_jcc!(jmp, Op::Jmp); def_push_jcc!(je, Op::Je); +def_push_jcc!(jne, Op::Jne); def_push_jcc!(jbe, Op::Jbe); def_push_jcc!(jz, Op::Jz); def_push_jcc!(jnz, Op::Jnz); diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 2fb7e39346..2efe920ddf 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -367,6 +367,14 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L367 } } + Op::Jne => { + match insn.target.unwrap() { + Target::CodePtr(code_ptr) => jne_ptr(cb, code_ptr), + Target::Label(label_idx) => jne_label(cb, label_idx), + _ => unreachable!() + } + } + Op::Jbe => { match insn.target.unwrap() { Target::CodePtr(code_ptr) => jbe_ptr(cb, code_ptr), diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index d2f483c79d..0b906970f7 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -37,7 +37,6 @@ enum CodegenStatus { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L37 KeepCompiling, CantCompile, EndBlock, - DeferCompilation, } /// Code generation function signature @@ -698,17 +697,10 @@ fn jump_to_next_insn( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L697 // We are at the end of the current instruction. Record the boundary. if jit.record_boundary_patch_point { - todo!(); - - /* - let next_insn = unsafe { jit.pc.offset(insn_len(jit.opcode).try_into().unwrap()) }; - let exit_pos = gen_exit(next_insn, &reset_depth, ocb.unwrap()); - record_global_inval_patch(cb, exit_pos); + let exit_pc = unsafe { jit.pc.offset(insn_len(jit.opcode).try_into().unwrap()) }; + let exit_pos = gen_outlined_exit(exit_pc, &reset_depth, ocb); + record_global_inval_patch(asm, exit_pos); jit.record_boundary_patch_point = false; - */ - - - } // Generate the jump instruction @@ -752,9 +744,6 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L744 // Create a backend assembler instance let mut asm = Assembler::new(); - // Codegen status for the last instruction compiled - let mut status = CantCompile; - // For each instruction to compile // NOTE: could rewrite this loop with a std::iter::Iterator while insn_idx < iseq_size { @@ -792,7 +781,7 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L781 } // Lookup the codegen function for this instruction - status = CantCompile; + let mut status = CantCompile; if let Some(gen_fn) = get_gen_fn(VALUE(opcode)) { // :count-placement: // Count bytecode instructions that execute in generated code. @@ -835,11 +824,6 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L824 break; } - // If we are deferring compilation for this instruction - if status == DeferCompilation { - break; - } - // For now, reset the chain depth after each instruction as only the // first instruction in the block can concern itself with the depth. ctx.reset_chain_depth(); @@ -870,24 +854,9 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L854 block.set_end_idx(insn_idx); } - // If we are deferring compilation for the current instruction - if status == DeferCompilation { - defer_compilation(&jit.block, insn_idx, &ctx, cb, ocb); - - // Mark the end position of the block - let mut block = jit.block.borrow_mut(); - block.set_end_addr(cb.get_write_ptr()); - } - - - // We currently can't handle cases where the request is for a block that // doesn't go to the next instruction. - //assert!(!jit.record_boundary_patch_point); - - - - + assert!(!jit.record_boundary_patch_point); // If code for the block doesn't fit, fail if cb.has_dropped_bytes() || ocb.unwrap().has_dropped_bytes() { @@ -1140,7 +1109,8 @@ fn gen_opt_plus( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1109 ocb: &mut OutlinedCb, ) -> CodegenStatus { if !jit_at_current_insn(jit) { - return DeferCompilation; + defer_compilation(jit, ctx, asm, ocb); + return EndBlock; } let comptime_a = jit_peek_at_stack(jit, ctx, 1); @@ -3208,9 +3178,10 @@ fn gen_opt_case_dispatch( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3178 KeepCompiling // continue with the next instruction } +*/ fn gen_branchif_branch( - cb: &mut CodeBlock, + asm: &mut Assembler, target0: CodePtr, target1: Option<CodePtr>, shape: BranchShape, @@ -3218,14 +3189,14 @@ fn gen_branchif_branch( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3189 assert!(target1 != None); match shape { BranchShape::Next0 => { - jz_ptr(cb, target1.unwrap()); + asm.jz(target1.unwrap().into()); } BranchShape::Next1 => { - jnz_ptr(cb, target0); + asm.jnz(target0.into()); } BranchShape::Default => { - jnz_ptr(cb, target0); - jmp_ptr(cb, target1.unwrap()); + asm.jnz(target0.into()); + asm.jmp(target1.unwrap().into()); } } } @@ -3233,7 +3204,7 @@ fn gen_branchif_branch( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3204 fn gen_branchif( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> CodegenStatus { let jump_offset = jit_get_arg(jit, 0).as_i32(); @@ -3241,14 +3212,14 @@ fn gen_branchif( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3212 // Check for interrupts, but only on backward branches that may create loops if jump_offset < 0 { let side_exit = get_side_exit(jit, ocb, ctx); - gen_check_ints(cb, side_exit); + gen_check_ints(asm, side_exit); } // Test if any bit (outside of the Qnil bit) is on // RUBY_Qfalse /* ...0000 0000 */ // RUBY_Qnil /* ...0000 1000 */ let val_opnd = ctx.stack_pop(1); - test(cb, val_opnd, imm_opnd(!Qnil.as_i64())); + asm.test(val_opnd, Opnd::Imm(!Qnil.as_i64())); // Get the branch target instruction offsets let next_idx = jit_next_insn_idx(jit); @@ -3266,7 +3237,7 @@ fn gen_branchif( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3237 gen_branch( jit, ctx, - cb, + asm, ocb, jump_block, ctx, @@ -3277,7 +3248,6 @@ fn gen_branchif( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3248 EndBlock } -*/ fn gen_branchunless_branch( asm: &mut Assembler, @@ -3328,18 +3298,11 @@ fn gen_branchunless( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3298 idx: jump_idx.try_into().unwrap(), }; - - - - // TODO: port gen_branch logic - todo!("complete branchunless implementation"); - - /* // Generate the branch instructions gen_branch( jit, ctx, - cb, + asm, ocb, jump_block, ctx, @@ -3349,24 +3312,20 @@ fn gen_branchunless( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3312 ); EndBlock - */ - - } -/* fn gen_branchnil_branch( - cb: &mut CodeBlock, + asm: &mut Assembler, target0: CodePtr, target1: Option<CodePtr>, shape: BranchShape, ) { match shape { - (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/