From 30e688ca14c5bcab58974cea468c24bdd55bee54 Mon Sep 17 00:00:00 2001 From: Max Bernstein Date: Thu, 6 Feb 2025 11:04:48 -0500 Subject: Move IR to its own file --- zjit/src/ir.rs | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ zjit/src/lib.rs | 116 +------------------------------------------------------- 2 files changed, 116 insertions(+), 115 deletions(-) create mode 100644 zjit/src/ir.rs diff --git a/zjit/src/ir.rs b/zjit/src/ir.rs new file mode 100644 index 0000000000..ff1cbace9a --- /dev/null +++ b/zjit/src/ir.rs @@ -0,0 +1,115 @@ +use crate::cruby::{VALUE, Qnil}; + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub struct InsnId(usize); + +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub struct BlockId(usize); + +#[derive(Debug, PartialEq)] +enum Opnd { + Const(VALUE), + Insn(InsnId), +} + +#[derive(Debug, PartialEq)] +enum Insn { + Param { idx: usize }, + Return { val: Opnd }, +} + +#[derive(Debug, PartialEq)] +struct Block { + params: Vec, + insns: Vec, +} + +impl Block { + fn new() -> Block { + Block { params: vec![], insns: vec![] } + } +} + +#[derive(Debug, PartialEq)] +struct Function { + entry_block: BlockId, + insns: Vec, + blocks: Vec, +} + +impl Function { + fn new() -> Function { + Function { blocks: vec![Block::new()], insns: vec![], entry_block: BlockId(0) } + } + + fn push_insn(&mut self, block: BlockId, insn: Insn) -> InsnId { + let id = InsnId(self.insns.len()); + self.insns.push(insn); + // Add the insn to the block + self.blocks[block.0].insns.push(id); + id + } +} + +enum RubyOpcode { + Putnil, + Putobject(VALUE), + Leave, +} + +struct FrameState { + stack: Vec, +} + +impl FrameState { + fn new() -> FrameState { + FrameState { stack: vec![] } + } + + fn push(&mut self, opnd: Opnd) { + self.stack.push(opnd); + } + + fn pop(&mut self) -> Opnd { + self.stack.pop().expect("Bytecode stack mismatch") + } +} + +fn to_ssa(opcodes: &Vec) -> Function { + let mut result = Function::new(); + let mut state = FrameState::new(); + let block = result.entry_block; + for opcode in opcodes { + match opcode { + RubyOpcode::Putnil => { state.push(Opnd::Const(Qnil)); }, + RubyOpcode::Putobject(val) => { state.push(Opnd::Const(*val)); }, + RubyOpcode::Leave => { + result.push_insn(block, Insn::Return { val: state.pop() }); + }, + } + } + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + let opcodes = vec![ + RubyOpcode::Putnil, + RubyOpcode::Leave, + ]; + let function = to_ssa(&opcodes); + assert_eq!(function, Function { + entry_block: BlockId(0), + insns: vec![ + Insn::Return { val: Opnd::Const(Qnil) } + ], + blocks: vec![ + Block { params: vec![], insns: vec![InsnId(0)] } + ], + }); + } +} diff --git a/zjit/src/lib.rs b/zjit/src/lib.rs index 0a45005cee..4cd4f8a25e 100644 --- a/zjit/src/lib.rs +++ b/zjit/src/lib.rs @@ -2,7 +2,7 @@ mod cruby; mod stats; -use cruby::{VALUE, Qnil}; +mod ir; extern "C" fn zjit_init() { println!("zjit_init"); @@ -12,117 +12,3 @@ extern "C" fn zjit_init() { pub extern "C" fn rb_zjit_parse_option() -> bool { false } - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub struct InsnId(usize); - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub struct BlockId(usize); - -#[derive(Debug, PartialEq)] -enum Opnd { - Const(VALUE), - Insn(InsnId), -} - -#[derive(Debug, PartialEq)] -enum Insn { - Param { idx: usize }, - Return { val: Opnd }, -} - -#[derive(Debug, PartialEq)] -struct Block { - params: Vec, - insns: Vec, -} - -impl Block { - fn new() -> Block { - Block { params: vec![], insns: vec![] } - } -} - -#[derive(Debug, PartialEq)] -struct Function { - entry_block: BlockId, - insns: Vec, - blocks: Vec, -} - -impl Function { - fn new() -> Function { - Function { blocks: vec![Block::new()], insns: vec![], entry_block: BlockId(0) } - } - - fn push_insn(&mut self, block: BlockId, insn: Insn) -> InsnId { - let id = InsnId(self.insns.len()); - self.insns.push(insn); - // Add the insn to the block - self.blocks[block.0].insns.push(id); - id - } -} - -enum RubyOpcode { - Putnil, - Putobject(VALUE), - Leave, -} - -struct FrameState { - stack: Vec, -} - -impl FrameState { - fn new() -> FrameState { - FrameState { stack: vec![] } - } - - fn push(&mut self, opnd: Opnd) { - self.stack.push(opnd); - } - - fn pop(&mut self) -> Opnd { - self.stack.pop().expect("Bytecode stack mismatch") - } -} - -fn to_ssa(opcodes: &Vec) -> Function { - let mut result = Function::new(); - let mut state = FrameState::new(); - let block = result.entry_block; - for opcode in opcodes { - match opcode { - RubyOpcode::Putnil => { state.push(Opnd::Const(Qnil)); }, - RubyOpcode::Putobject(val) => { state.push(Opnd::Const(*val)); }, - RubyOpcode::Leave => { - result.push_insn(block, Insn::Return { val: state.pop() }); - }, - } - } - result -} - -#[cfg(test)] -mod tests { - use crate::*; - - #[test] - fn test() { - let opcodes = vec![ - RubyOpcode::Putnil, - RubyOpcode::Leave, - ]; - let function = to_ssa(&opcodes); - assert_eq!(function, Function { - entry_block: BlockId(0), - insns: vec![ - Insn::Return { val: Opnd::Const(Qnil) } - ], - blocks: vec![ - Block { params: vec![], insns: vec![InsnId(0)] } - ], - }); - } -} -- cgit v1.2.3