Skip to main content

luaur_code_gen/functions/
get_live_in_out_value_count.rs

1use crate::enums::ir_op_kind::IrOpKind;
2use crate::functions::is_pseudo::is_pseudo;
3use crate::functions::try_get_next_block_in_chain::try_get_next_block_in_chain;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::ir_block::IrBlock;
6use crate::records::ir_function::IrFunction;
7use crate::records::ir_op::IrOp;
8use alloc::vec::Vec;
9
10pub fn get_live_in_out_value_count(
11    function: &mut IrFunction,
12    start: &mut IrBlock,
13    visit_chain: bool,
14) -> (u32, u32) {
15    let mut blocks = Vec::new();
16
17    if visit_chain {
18        let mut block = start as *mut IrBlock;
19        while !block.is_null() {
20            blocks.push(function.get_block_index(unsafe { &*block }));
21            block = try_get_next_block_in_chain(function, unsafe { &mut *block });
22        }
23    } else {
24        blocks.push(function.get_block_index(start));
25    }
26
27    let mut live_ins = 0;
28    let mut live_outs = 0;
29
30    for &block_idx in &blocks {
31        let block = &function.blocks[block_idx as usize];
32
33        for inst_idx in block.start..=block.finish {
34            let inst = &function.instructions[inst_idx as usize];
35
36            if is_pseudo(inst.cmd) {
37                continue;
38            }
39
40            live_outs += inst.use_count as u32;
41
42            for op in inst.ops.iter() {
43                let op: IrOp = *op;
44                if op.kind() == IrOpKind::Inst {
45                    let mut found = false;
46                    for &b_idx in &blocks {
47                        let b = &function.blocks[b_idx as usize];
48                        if op.index() >= b.start && op.index() <= b.finish {
49                            CODEGEN_ASSERT!(live_outs > 0);
50                            live_outs -= 1;
51                            found = true;
52                            break;
53                        }
54                    }
55
56                    if !found {
57                        live_ins += 1;
58                    }
59                }
60            }
61        }
62    }
63
64    (live_ins, live_outs)
65}