[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]