summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <[email protected]>2025-02-06 15:41:22 -0500
committerTakashi Kokubun <[email protected]>2025-04-18 21:52:56 +0900
commitc5e17f50b7bc81d39f2f063a238fc8cb55ef726c (patch)
treef6bf69cb8ff3a9c81dc901cf05514ea3559d07c0
parent520872074603d99432e206b55461fe6d62dd305a (diff)
Make iseq_to_ssa return Function object
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13131
-rw-r--r--zjit/src/ir.rs46
1 files changed, 24 insertions, 22 deletions
diff --git a/zjit/src/ir.rs b/zjit/src/ir.rs
index 673de4fe3e..e1f6bb2003 100644
--- a/zjit/src/ir.rs
+++ b/zjit/src/ir.rs
@@ -24,7 +24,7 @@ impl std::fmt::Display for BlockId {
/// Instruction operand
#[derive(Debug, PartialEq, Clone, Copy)]
-enum Opnd {
+pub enum Opnd {
Const(VALUE),
Insn(InsnId),
}
@@ -40,13 +40,13 @@ impl std::fmt::Display for Opnd {
}
#[derive(Debug, PartialEq)]
-struct BranchEdge {
+pub struct BranchEdge {
target: BlockId,
args: Vec<Opnd>,
}
#[derive(Debug, PartialEq)]
-enum Insn {
+pub enum Insn {
// SSA block parameter. Also used for function parameters in the function's entry block.
Param { idx: usize },
@@ -89,7 +89,7 @@ enum Insn {
}
#[derive(Default, Debug, PartialEq)]
-struct Block {
+pub struct Block {
params: Vec<InsnId>,
insns: Vec<InsnId>,
}
@@ -98,7 +98,7 @@ impl Block {
}
#[derive(Debug, PartialEq)]
-struct Function {
+pub struct Function {
// TODO:
// ISEQ this function refers to
//iseq: *const iseqptr_t,
@@ -240,6 +240,7 @@ fn to_ssa(opcodes: &Vec<RubyOpcode>) -> Function {
result
}
+/// Get instruction argument
fn get_arg(pc: *const VALUE, arg_idx: isize) -> VALUE {
unsafe { *(pc.offset(arg_idx + 1)) }
}
@@ -272,10 +273,10 @@ fn compute_jump_targets(iseq: *const rb_iseq_t) -> Vec<u32> {
jump_targets
}
-pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
- let mut result = Function::new();
+pub fn iseq_to_ssa(iseq: *const rb_iseq_t) -> Function {
+ let mut fun = Function::new();
let mut state = FrameState::new();
- let mut block = result.entry_block;
+ let mut block = fun.entry_block;
let iseq_size = unsafe { get_iseq_encoded_size(iseq) };
let mut insn_idx = 0;
@@ -287,7 +288,7 @@ pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
if insn_idx == 0 {
todo!("Separate entry block for param/self/...");
}
- insn_idx_to_block.insert(insn_idx, result.new_block());
+ insn_idx_to_block.insert(insn_idx, fun.new_block());
}
while insn_idx < iseq_size {
@@ -310,19 +311,19 @@ pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
YARVINSN_putobject => { state.push(Opnd::Const(get_arg(pc, 0))); },
YARVINSN_putstring => {
let val = Opnd::Const(get_arg(pc, 0));
- let insn_id = result.push_insn(block, Insn::StringCopy { val });
+ let insn_id = fun.push_insn(block, Insn::StringCopy { val });
state.push(Opnd::Insn(insn_id));
}
YARVINSN_intern => {
let val = state.pop();
- let insn_id = result.push_insn(block, Insn::StringIntern { val });
+ let insn_id = fun.push_insn(block, Insn::StringIntern { val });
state.push(Opnd::Insn(insn_id));
}
YARVINSN_newarray => {
let count = get_arg(pc, 0).as_usize();
- let insn_id = result.push_insn(block, Insn::NewArray { count });
+ let insn_id = fun.push_insn(block, Insn::NewArray { count });
for idx in (0..count).rev() {
- result.push_insn(block, Insn::ArraySet { idx, val: state.pop() });
+ fun.push_insn(block, Insn::ArraySet { idx, val: state.pop() });
}
state.push(Opnd::Insn(insn_id));
}
@@ -341,18 +342,18 @@ pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
let obj = get_arg(pc, 0);
let pushval = get_arg(pc, 0);
let v = state.pop();
- state.push(Opnd::Insn(result.push_insn(block, Insn::Defined { op_type, obj, pushval, v })));
+ state.push(Opnd::Insn(fun.push_insn(block, Insn::Defined { op_type, obj, pushval, v })));
}
YARVINSN_opt_getconstant_path => {
let ic = get_arg(pc, 0).as_ptr::<u8>();
- state.push(Opnd::Insn(result.push_insn(block, Insn::GetConstantPath { ic })));
+ state.push(Opnd::Insn(fun.push_insn(block, Insn::GetConstantPath { ic })));
}
YARVINSN_branchunless => {
let offset = get_arg(pc, 0).as_i64();
let val = state.pop();
- let test_id = result.push_insn(block, Insn::Test { val });
+ let test_id = fun.push_insn(block, Insn::Test { val });
// TODO(max): Check interrupts
- let branch_id = result.push_insn(block,
+ let branch_id = fun.push_insn(block,
Insn::IfFalse {
val: Opnd::Insn(test_id),
target: BranchEdge {
@@ -378,7 +379,7 @@ pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
// TODO: we need to add a BOP not redefined check here
let v0 = state.pop();
let v1 = state.pop();
- let add_id = result.push_insn(block, Insn::Add { v0, v1 });
+ let add_id = fun.push_insn(block, Insn::Add { v0, v1 });
state.push(Opnd::Insn(add_id));
}
@@ -386,18 +387,19 @@ pub fn iseq_to_ssa(iseq: *const rb_iseq_t) {
// TODO: we need to add a BOP not redefined check here
let v0 = state.pop();
let v1 = state.pop();
- let lt_id = result.push_insn(block, Insn::Lt { v0, v1 });
+ let lt_id = fun.push_insn(block, Insn::Lt { v0, v1 });
state.push(Opnd::Insn(lt_id));
}
YARVINSN_leave => {
- result.push_insn(block, Insn::Return { val: state.pop() });
+ fun.push_insn(block, Insn::Return { val: state.pop() });
}
_ => eprintln!("zjit: to_ssa: unknown opcode `{}'", insn_name(opcode as usize)),
}
}
- print!("SSA:\n{result}");
- return;
+
+ print!("SSA:\n{fun}");
+ return fun;
}
#[cfg(test)]