luaur_code_gen/functions/
get_live_in_out_value_count.rs1use 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}