summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bernstein <max.bernstein@shopify.com>2025-02-06 11:04:48 -0500
committerTakashi Kokubun <takashikkbn@gmail.com>2025-04-18 21:52:55 +0900
commit30e688ca14c5bcab58974cea468c24bdd55bee54 (patch)
tree89344fe9bc5df5432632d9eaa18b8fb4ca54320e
parent2b05fbd1b4ad30e878b9a5914507f2ec676b1885 (diff)
Move IR to its own file
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13131
-rw-r--r--zjit/src/ir.rs115
-rw-r--r--zjit/src/lib.rs116
2 files changed, 116 insertions, 115 deletions
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<InsnId>,
+ insns: Vec<InsnId>,
+}
+
+impl Block {
+ fn new() -> Block {
+ Block { params: vec![], insns: vec![] }
+ }
+}
+
+#[derive(Debug, PartialEq)]
+struct Function {
+ entry_block: BlockId,
+ insns: Vec<Insn>,
+ blocks: Vec<Block>,
+}
+
+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<Opnd>,
+}
+
+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<RubyOpcode>) -> 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<InsnId>,
- insns: Vec<InsnId>,
-}
-
-impl Block {
- fn new() -> Block {
- Block { params: vec![], insns: vec![] }
- }
-}
-
-#[derive(Debug, PartialEq)]
-struct Function {
- entry_block: BlockId,
- insns: Vec<Insn>,
- blocks: Vec<Block>,
-}
-
-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<Opnd>,
-}
-
-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<RubyOpcode>) -> 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)] }
- ],
- });
- }
-}