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

ruby-changes:73170

From: Alan <ko1@a...>
Date: Tue, 30 Aug 2022 00:57:59 +0900 (JST)
Subject: [ruby-changes:73170] d916328078 (master): Conscise IR disassembly (https://github.com/Shopify/ruby/pull/302)

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

From d9163280782086b57119abc9478580a6b3efd2c3 Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Tue, 21 Jun 2022 19:41:06 -0400
Subject: Conscise IR disassembly (https://github.com/Shopify/ruby/pull/302)

The output from `dbg!` was too verbose. For `test_jo` the output went
from 37 lines to 5 lines. The added index helps parsing InsnOut
indicies.

Samples:

```
test backend::tests::test_jo ... [src/backend/ir.rs:589] &self = Assembler
    000 Load(Mem64[Reg(3) + 8]) -> Out64(0)
    001 Sub(Out64(0), 1_i64) -> Out64(1)
    002 Load(Out64(1)) -> Out64(2)
    003 Add(Out64(2), Mem64[Reg(3)]) -> Out64(3)
    004 Jo() target=CodePtr(CodePtr(0x5)) -> Out64(4)
    005 Mov(Mem64[Reg(3)], Out64(3)) -> Out64(5)

test backend::tests::test_reuse_reg ... [src/backend/ir.rs:589] &self = Assembler
    000 Load(Mem64[Reg(3)]) -> Out64(0)
    001 Add(Out64(0), 1_u64) -> Out64(1)
    002 Load(Mem64[Reg(3) + 8]) -> Out64(2)
    003 Add(Out64(2), 1_u64) -> Out64(3)
    004 Add(Out64(1), 1_u64) -> Out64(4)
    005 Add(Out64(1), Out64(4)) -> Out64(5)
    006 Store(Mem64[Reg(3)], Out64(4)) -> Out64(6)
    007 Store(Mem64[Reg(3) + 8], Out64(5)) -> Out64(7)
```
---
 yjit/src/backend/ir.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 67 insertions(+), 4 deletions(-)

diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index 96b314e9cb..4e8ed0b8a4 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -121,7 +121,7 @@ pub enum MemBase https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L121
 }
 
 // Memory location
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq)]
 pub struct Mem
 {
     // Base register number or instruction index
@@ -134,8 +134,20 @@ pub struct Mem https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L134
     pub(super) num_bits: u8,
 }
 
+impl fmt::Debug for Mem {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "Mem{}[{:?}", self.num_bits, self.base)?;
+        if self.disp != 0 {
+            let sign = if self.disp > 0 { '+' } else { '-' };
+            write!(fmt, " {sign} {}", self.disp)?;
+        }
+
+        write!(fmt, "]")
+    }
+}
+
 /// Operand to an IR instruction
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq)]
 pub enum Opnd
 {
     None,               // For insns with no output
@@ -153,6 +165,22 @@ pub enum Opnd https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L165
     Reg(Reg),           // Machine register
 }
 
+impl fmt::Debug for Opnd {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        use Opnd::*;
+        match self {
+            Self::None => write!(fmt, "None"),
+            Value(val) => write!(fmt, "Value({val:?})"),
+            InsnOut { idx, num_bits } => write!(fmt, "Out{num_bits}({idx})"),
+            Imm(signed) => write!(fmt, "{signed:x}_i64"),
+            UImm(unsigned) => write!(fmt, "{unsigned:x}_u64"),
+            // Say Mem and Reg only once
+            Mem(mem) => write!(fmt, "{mem:?}"),
+            Reg(reg) => write!(fmt, "{reg:?}"),
+        }
+    }
+}
+
 impl Opnd
 {
     /// Convenience constructor for memory operands
@@ -263,7 +291,7 @@ impl From<CodePtr> for Target { https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L291
 }
 
 /// YJIT IR instruction
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 pub struct Insn
 {
     // Opcode for the instruction
@@ -286,6 +314,35 @@ pub struct Insn https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L314
     pub(super) pos: Option<CodePtr>,
 }
 
+impl fmt::Debug for Insn {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "{:?}(", self.op)?;
+
+        // Print list of operands
+        let mut opnd_iter = self.opnds.iter();
+        if let Some(first_opnd) = opnd_iter.next() {
+            write!(fmt, "{first_opnd:?}")?;
+        }
+        for opnd in opnd_iter {
+            write!(fmt, ", {opnd:?}")?;
+        }
+        write!(fmt, ")")?;
+
+        // Print text, target, and pos if they are present
+        if let Some(text) = &self.text {
+            write!(fmt, " {text:?}")?
+        }
+        if let Some(target) = self.target {
+            write!(fmt, " target={target:?}")?;
+        }
+        if let Some(pos) = self.pos {
+            write!(fmt, " pos={pos:?}")?;
+        }
+
+        write!(fmt, " -> {:?}", self.out)
+    }
+}
+
 /// Object into which we assemble instructions to be
 /// optimized and lowered
 pub struct Assembler
@@ -687,7 +744,13 @@ impl Assembler https://github.com/ruby/ruby/blob/trunk/yjit/src/backend/ir.rs#L744
 
 impl fmt::Debug for Assembler {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.debug_list().entries(self.insns.iter()).finish()
+        write!(fmt, "Assembler\n")?;
+
+        for (idx, insn) in self.insns.iter().enumerate() {
+            write!(fmt, "    {idx:03} {insn:?}\n")?;
+        }
+
+        Ok(())
     }
 }
 
-- 
cgit v1.2.1


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

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