luaur-code-gen 0.1.3

Native (A64/X64) code generation for Luau (Rust).
Documentation
use crate::enums::ir_op_kind::IrOpKind;
use crate::functions::is_pseudo::is_pseudo;
use crate::functions::try_get_next_block_in_chain::try_get_next_block_in_chain;
use crate::macros::codegen_assert::CODEGEN_ASSERT;
use crate::records::ir_block::IrBlock;
use crate::records::ir_function::IrFunction;
use crate::records::ir_op::IrOp;
use alloc::vec::Vec;

pub fn get_live_in_out_value_count(
    function: &mut IrFunction,
    start: &mut IrBlock,
    visit_chain: bool,
) -> (u32, u32) {
    let mut blocks = Vec::new();

    if visit_chain {
        let mut block = start as *mut IrBlock;
        while !block.is_null() {
            blocks.push(function.get_block_index(unsafe { &*block }));
            block = try_get_next_block_in_chain(function, unsafe { &mut *block });
        }
    } else {
        blocks.push(function.get_block_index(start));
    }

    let mut live_ins = 0;
    let mut live_outs = 0;

    for &block_idx in &blocks {
        let block = &function.blocks[block_idx as usize];

        for inst_idx in block.start..=block.finish {
            let inst = &function.instructions[inst_idx as usize];

            if is_pseudo(inst.cmd) {
                continue;
            }

            live_outs += inst.use_count as u32;

            for op in inst.ops.iter() {
                let op: IrOp = *op;
                if op.kind() == IrOpKind::Inst {
                    let mut found = false;
                    for &b_idx in &blocks {
                        let b = &function.blocks[b_idx as usize];
                        if op.index() >= b.start && op.index() <= b.finish {
                            CODEGEN_ASSERT!(live_outs > 0);
                            live_outs -= 1;
                            found = true;
                            break;
                        }
                    }

                    if !found {
                        live_ins += 1;
                    }
                }
            }
        }
    }

    (live_ins, live_outs)
}