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

ruby-changes:73098

From: Maxime <ko1@a...>
Date: Tue, 30 Aug 2022 00:45:19 +0900 (JST)
Subject: [ruby-changes:73098] 2ffaa377c2 (master): WIP backend IR sketch

https://git.ruby-lang.org/ruby.git/commit/?id=2ffaa377c2

From 2ffaa377c212279e4a8bf1da8ac65a00dcdadd53 Mon Sep 17 00:00:00 2001
From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...>
Date: Wed, 11 May 2022 15:17:44 -0400
Subject: WIP backend IR sketch

---
 yjit/src/asm/x86_64/mod.rs |  24 +--
 yjit/src/ir.rs             | 479 +++++++++++++++++++++++++++++++++++++++++++++
 yjit/src/lib.rs            |   1 +
 3 files changed, 492 insertions(+), 12 deletions(-)
 create mode 100644 yjit/src/ir.rs

diff --git a/yjit/src/asm/x86_64/mod.rs b/yjit/src/asm/x86_64/mod.rs
index 6eb7efaa0a..b4ef2e4bf9 100644
--- a/yjit/src/asm/x86_64/mod.rs
+++ b/yjit/src/asm/x86_64/mod.rs
@@ -9,20 +9,20 @@ mod tests; https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/x86_64/mod.rs#L9
 pub struct X86Imm
 {
     // Size in bits
-    num_bits: u8,
+    pub num_bits: u8,
 
     // The value of the immediate
-    value: i64
+    pub value: i64
 }
 
 #[derive(Clone, Copy, Debug)]
 pub struct X86UImm
 {
     // Size in bits
-    num_bits: u8,
+    pub num_bits: u8,
 
     // The value of the immediate
-    value: u64
+    pub value: u64
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -38,32 +38,32 @@ pub enum RegType https://github.com/ruby/ruby/blob/trunk/yjit/src/asm/x86_64/mod.rs#L38
 pub struct X86Reg
 {
     // Size in bits
-    num_bits: u8,
+    pub num_bits: u8,
 
     // Register type
-    reg_type: RegType,
+    pub reg_type: RegType,
 
     // Register index number
-    reg_no: u8,
+    pub reg_no: u8,
 }
 
 #[derive(Clone, Copy, Debug)]
 pub struct X86Mem
 {
     // Size in bits
-    num_bits: u8,
+    pub num_bits: u8,
 
     /// Base register number
-    base_reg_no: u8,
+    pub base_reg_no: u8,
 
     /// Index register number
-    idx_reg_no: Option<u8>,
+    pub idx_reg_no: Option<u8>,
 
     /// SIB scale exponent value (power of two, two bits)
-    scale_exp: u8,
+    pub scale_exp: u8,
 
     /// Constant displacement from the base, not scaled
-    disp: i32,
+    pub disp: i32,
 }
 
 #[derive(Clone, Copy, Debug)]
diff --git a/yjit/src/ir.rs b/yjit/src/ir.rs
new file mode 100644
index 0000000000..a20a982493
--- /dev/null
+++ b/yjit/src/ir.rs
@@ -0,0 +1,479 @@ https://github.com/ruby/ruby/blob/trunk/yjit/src/ir.rs#L1
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_imports)]
+
+use std::convert::From;
+use crate::cruby::{VALUE};
+use crate::virtualmem::{CodePtr};
+use crate::asm::x86_64::{X86Opnd, X86Imm, X86UImm, X86Reg, X86Mem, RegType};
+use crate::core::{Context, Type, TempMapping};
+
+
+
+
+/*
+// Minimally, we might want to specify how many operands and branch targets an insn has
+// Branch targets are not interchangeable with other operand types. We distinguish
+// between branch and regular instructions.
+//
+// TODO: should mark instructions that produce no output operand
+//
+make_ops! {
+    (Comment, 1, 0),
+    ...
+
+    // Call is variadic, might need to be special-cased
+}
+*/
+
+
+
+
+
+
+
+
+
+/// Instruction opcodes
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Op
+{
+    // Add a comment into the IR at the point that this instruction is added. It
+    // won't have any impact on that actual compiled code, but it will impact
+    // the output of ir_print_insns. Accepts as its only operand an EIR_IMM
+    // operand (typically generated by ir_str_ptr).
+    Comment,
+
+    // Add a label into the IR at the point that this instruction is added. It
+    // will eventually be translated into an offset when generating code such
+    // that EIR_LABEL_IDX operands know where to jump to. Accepts as its only
+    // operand an EIR_LABEL_NAME operand (typically generated by ir_label_opnd).
+    Label,
+
+    // Add two operands together, and return the result as a new operand. This
+    // operand can then be used as the operand on another instruction. It
+    // accepts two operands, which can be of any type
+    //
+    // Under the hood when allocating registers, the IR will determine the most
+    // efficient way to get these values into memory. For example, if both
+    // operands are immediates, then it will load the first one into a register
+    // first with a mov instruction and then add them together. If one of them
+    // is a register, however, it will just perform a single add instruction.
+    Add,
+
+    // This is the same as the OP_ADD instruction, except for subtraction.
+    Sub,
+
+    // This is the same as the OP_ADD instruction, except that it performs the
+    // binary AND operation.
+    And,
+
+    // Perform the NOT operation on an individual operand, and return the result
+    // as a new operand. This operand can then be used as the operand on another
+    // instruction.
+    Not,
+
+    //
+    // Low-level instructions
+    //
+
+    // A low-level mov instruction. It accepts two operands.
+    Mov,
+
+    // Bitwise AND test instruction
+    Test,
+
+    // Jump if not zero
+    Jnz,
+
+    /*
+    // 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.
+    //
+    // The OP_JUMP_EQ instruction accepts two additional operands, to be
+    // compared for equality. If they're equal, then the generated code jumps to
+    // the target label. If they're not, then it continues on to the next
+    // instruction.
+    JumpEq,
+
+    // The OP_JUMP_NE instruction is very similar to the OP_JUMP_EQ instruction,
+    // except it compares for inequality instead.
+    JumpNe,
+
+    // Checks the overflow flag and conditionally jumps to the target if it is
+    // currently set.
+    JumpOvf,
+
+    // A low-level call instruction for calling a function by a pointer. It
+    // accepts one operand of type EIR_IMM that should be a pointer to the
+    // function. Usually this is done by first casting the function to a void*,
+    // as in: ir_const_ptr((void *)&my_function)).
+    Call,
+
+    // Calls a function by a pointer and returns an operand that contains the
+    // result of the function. Accepts as its operands a pointer to a function
+    // of type EIR_IMM (usually generated from ir_const_ptr) and a variable
+    // number of arguments to the function being called.
+    //
+    // This is the higher-level instruction that should be used when you want to
+    // call a function with arguments, as opposed to OP_CALL which is
+    // lower-level and just calls a function without moving arguments into
+    // registers for you.
+    CCall,
+
+    // Returns from the function being generated immediately. This is different
+    // from OP_RETVAL in that it does nothing with the return value register
+    // (whatever is in there is what will get returned). Accepts no operands.
+    Ret,
+
+    // First, moves a value into the return value register. Then, returns from
+    // the generated function. Accepts as its only operand the value that should
+    // be returned from the generated function.
+    RetVal,
+
+    // A low-level cmp instruction. It accepts two operands. The first it
+    // expects to be a register. The second can be anything. Most of the time
+    // this instruction shouldn't be used by the developer since other
+    // instructions break down to this one.
+    Cmp,
+
+    // A conditional move instruction that should be preceeded at some point by
+    // an OP_CMP instruction that would have set the requisite comparison flags.
+    // Accepts 2 operands, both of which are expected to be of the EIR_REG type.
+    //
+    // If the comparison indicates the left compared value is greater than or
+    // equal to the right compared value, then the conditional move is executed,
+    // otherwise we just continue on to the next instruction.
+    //
+    // This is considered a low-level instruction, and the OP_SELECT_* variants
+    // should be preferred if possible.
+    CMovGE,
+
+    // The same as OP_CMOV_GE, except the comparison is greater than.
+    CMovGT,
+
+    // The same as OP_CMOV_GE, except the comparison is less than or equal.
+    CMovLE,
+
+    // The same as OP_CMOV_GE, except the comparison is less than.
+    CMovLT,
+
+    // Selects between two different values based on a comparison of two other
+    // values. Accepts 4 operands. The first two are the basis of the
+    // comparison. The second two are the "then" case and the "else" case. You
+    // can effectively think of this instruction as a ternary operation, where
+    // the first two values are being compared.
+    //
+    // OP_SELECT_GE performs the described ternary using a greater than or equal
+    // comparison, that is if the first operand is greater than or equal to the
+    // second operand.
+    SelectGE,
+
+    // The same as OP_SELECT_GE, except the comparison is greater than.
+    SelectGT,
+
+    // The same as OP_SELECT_GE, except the comparison is less than or equal.
+    SelectLE,
+
+    // The same as OP_SELECT_GE, except the comparison is less than.
+    SelectLT,
+
+    // For later:
+    // These encode Ruby true/false semantics
+    // Can be used to enable op fusion of Ruby compare + branch.
+    // OP_JUMP_TRUE, // (opnd, target)
+    // OP_JUMP_FALSE, // (opnd, target)
+
+    // For later:
+    // OP_GUARD_HEAP, // (opnd, target)
+    // OP_GUARD_IMM, // (opnd, target)
+    // OP_GUARD_FIXNUM, // (opnd, target)
+
+    // For later:
+    // OP_COUNTER_INC, (counter_name)
+
+    // For later:
+    // OP_LEA,
+    // OP_TEST,
+    */
+}
+
+
+
+
+
+
+
+
+
+
+// Register value used by IR operands
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub struct Reg
+{
+    // Register number/index
+    reg_no: u8,
+
+    // Size in bits
+    num_bits: u8,
+
+    // Special register flag EC/CFP/SP/SELF
+    special: bool,
+}
+
+// Memory location
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub struct Mem
+{
+    // Base register
+    base: Reg,
+
+    // Offset relative to the base pointer
+    disp: i32,
+
+    // Size in bits
+    num_bits: u8,
+}
+
+/// Operand to an I (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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