ruby-changes:73117
From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 00:53:32 +0900 (JST)
Subject: [ruby-changes:73117] 04e2ccede4 (master): Change codegen.rs to use backend Assembler directly
https://git.ruby-lang.org/ruby.git/commit/?id=04e2ccede4 From 04e2ccede4e992a6e0d18ed506d76625ee7da8a3 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Mon, 6 Jun 2022 15:54:22 -0400 Subject: Change codegen.rs to use backend Assembler directly --- yjit/src/backend/ir.rs | 17 ++++++ yjit/src/backend/x86_64/mod.rs | 6 +- yjit/src/codegen.rs | 126 +++++++++++------------------------------ yjit/src/lib.rs | 7 +++ 4 files changed, 62 insertions(+), 94 deletions(-) diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index a578564afb..fa8a7b8e2b 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -84,6 +84,9 @@ pub enum Op https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L84 // C function call with N arguments (variadic) CCall, + // C function return + CRet, + /* // The following are conditional jump instructions. They all accept as their // first operand an EIR_LABEL_NAME, which is used as the target of the jump. @@ -661,6 +664,18 @@ macro_rules! def_push_1_opnd { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L664 }; } +macro_rules! def_push_1_opnd_no_out { + ($op_name:ident, $opcode:expr) => { + impl Assembler + { + pub fn $op_name(&mut self, opnd0: Opnd) + { + self.push_insn($opcode, vec![opnd0], None); + } + } + }; +} + macro_rules! def_push_2_opnd { ($op_name:ident, $opcode:expr) => { impl Assembler @@ -688,7 +703,9 @@ macro_rules! def_push_2_opnd_no_out { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L703 def_push_2_opnd!(add, Op::Add); def_push_2_opnd!(sub, Op::Sub); def_push_2_opnd!(and, Op::And); +def_push_1_opnd_no_out!(cret, Op::CRet); def_push_1_opnd!(load, Op::Load); +def_push_2_opnd_no_out!(store, Op::Store); def_push_2_opnd_no_out!(mov, Op::Mov); def_push_2_opnd_no_out!(lea, Op::Lea); def_push_2_opnd_no_out!(cmp, Op::Cmp); diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index f6ebcc5643..eb54ced2bf 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -109,8 +109,7 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L109 add(cb, insn.opnds[0].into(), insn.opnds[1].into()) }, - //TODO: - //Store + Op::Store => mov(cb, insn.opnds[0].into(), insn.opnds[1].into()), Op::Load => { mov(cb, insn.out.into(), insn.opnds[0].into()); @@ -127,6 +126,9 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/x86_64/mod.rs#L126 Op::Mov => mov(cb, insn.opnds[0].into(), insn.opnds[1].into()), + // Load effective address + Op::Lea => lea(cb, insn.opnds[0].into(), insn.opnds[1].into()), + // Test and set flags Op::Test => test(cb, insn.opnds[0].into(), insn.opnds[1].into()), diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index a94eeb62ca..955d87eb68 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -54,7 +54,7 @@ enum CodegenStatus { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L54 type InsnGenFn = fn( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> CodegenStatus; @@ -778,6 +778,9 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L778 // Mark the start position of the block blockref.borrow_mut().set_start_addr(cb.get_write_ptr()); + // Create a backend assembler instance + let mut asm = Assembler::new(); + // For each instruction to compile // NOTE: could rewrite this loop with a std::iter::Iterator while insn_idx < iseq_size { @@ -832,7 +835,7 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L835 } // Call the code generation function - status = gen_fn(&mut jit, &mut ctx, cb, ocb); + status = gen_fn(&mut jit, &mut ctx, &mut asm, ocb); } // If we can't compile this instruction @@ -869,6 +872,9 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L872 // Finish filling out the block { + // Compile code into the code block + asm.compile(&mut jit, cb); + let mut block = jit.block.borrow_mut(); // Mark the end position of the block @@ -887,19 +893,6 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L893 return Err(()); } - // TODO: we may want a feature for this called dump_insns? Can leave commented for now - /* - if (YJIT_DUMP_MODE >= 2) { - // Dump list of compiled instrutions - fprintf(stderr, "Compiled the following for iseq=%p:\n", (void *)iseq); - for (uint32_t idx = block->blockid.idx; idx < insn_idx; ) { - int opcode = yjit_opcode_at_pc(iseq, yjit_iseq_pc_at_idx(iseq, idx)); - fprintf(stderr, " %04d %s\n", idx, insn_name(opcode)); - idx += insn_len(opcode); - } - } - */ - // Block compiled successfully Ok(blockref) } @@ -907,7 +900,7 @@ pub fn gen_single_block( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L900 fn gen_nop( _jit: &mut JITState, _ctx: &mut Context, - _cb: &mut CodeBlock, + _asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { // Do nothing @@ -917,7 +910,7 @@ fn gen_nop( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L910 fn gen_pop( _jit: &mut JITState, ctx: &mut Context, - _cb: &mut CodeBlock, + _asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { // Decrement SP @@ -925,90 +918,27 @@ fn gen_pop( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L918 KeepCompiling } - - - -/* -fn gen_dup( - _jit: &mut JITState, - ctx: &mut Context, - cb: &mut CodeBlock, - _ocb: &mut OutlinedCb, -) -> CodegenStatus { - let dup_val = ctx.stack_pop(0); - let (mapping, tmp_type) = ctx.get_opnd_mapping(StackOpnd(0)); - - let loc0 = ctx.stack_push_mapping((mapping, tmp_type)); - mov(cb, REG0, dup_val); - mov(cb, loc0, REG0); - - KeepCompiling -} -*/ - -#[allow(dead_code)] fn gen_dup( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { - let mut asm = Assembler::new(); - let dup_val = ctx.ir_stack_pop(0); let (mapping, tmp_type) = ctx.get_opnd_mapping(StackOpnd(0)); let loc0 = ctx.ir_stack_push_mapping((mapping, tmp_type)); asm.mov(loc0, dup_val); - asm.compile(jit, cb); - - KeepCompiling -} - - - - -/* -// duplicate stack top n elements -fn gen_dupn( - jit: &mut JITState, - ctx: &mut Context, - cb: &mut CodeBlock, - _ocb: &mut OutlinedCb, -) -> CodegenStatus { - let nval: VALUE = jit_get_arg(jit, 0); - let VALUE(n) = nval; - - // In practice, seems to be only used for n==2 - if n != 2 { - return CantCompile; - } - - let opnd1: X86Opnd = ctx.stack_opnd(1); - let opnd0: X86Opnd = ctx.stack_opnd(0); - - let mapping1 = ctx.get_opnd_mapping(StackOpnd(1)); - let mapping0 = ctx.get_opnd_mapping(StackOpnd(0)); - - let dst1: X86Opnd = ctx.stack_push_mapping(mapping1); - mov(cb, REG0, opnd1); - mov(cb, dst1, REG0); - - let dst0: X86Opnd = ctx.stack_push_mapping(mapping0); - mov(cb, REG0, opnd0); - mov(cb, dst0, REG0); - KeepCompiling } -*/ // duplicate stack top n elements fn gen_dupn( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { @@ -1034,8 +964,6 @@ fn gen_dupn( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L964 let dst0: Opnd = ctx.ir_stack_push_mapping(mapping0); asm.mov(dst0, opnd0); - asm.compile(jit, cb); - KeepCompiling } @@ -1043,24 +971,22 @@ fn gen_dupn( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L971 fn gen_swap( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { - stack_swap(jit, ctx, cb, 0, 1, REG0, REG1); + stack_swap(jit, ctx, asm, 0, 1, REG0, REG1); KeepCompiling } fn stack_swap( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, offset0: u16, offset1: u16, _reg0: X86Opnd, _reg1: X86Opnd, ) { - let mut asm = Assembler::new(); - let stack0_mem = ctx.ir_stack_opnd(offset0 as i32); let stack1_mem = ctx.ir_stack_opnd(offset1 as i32); @@ -1074,10 +1000,18 @@ fn stack_swap( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L1000 ctx.set_opnd_mapping(StackOpnd(offset0), mapping1); ctx.set_opnd_mapping(StackOpnd(offset1), mapping0); - - asm.compile(jit, cb); } + + + + + + + + + +/* fn gen_putnil( jit: &mut JITState, ctx: &mut Context, @@ -6069,6 +6003,7 @@ fn gen_opt_invokebuiltin_delegate( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L6003 KeepCompiling } +*/ /// Maps a YARV opcode to a code generation function (if supported) fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { @@ -6078,10 +6013,12 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L6013 match opcode { YARVINSN_nop => Some(gen_nop), - YARVINSN_pop => Some(gen_pop), + //YARVINSN_pop => Some(gen_pop), YARVINSN_dup => Some(gen_dup), YARVINSN_dupn => Some(gen_dupn), YARVINSN_swap => (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/