luaur_code_gen/functions/
collect_direct_block_jump_path.rs1use crate::enums::ir_block_kind::IrBlockKind;
2use crate::enums::ir_cmd::IrCmd;
3use crate::enums::ir_op_kind::IrOpKind;
4use crate::functions::get_live_in_out_value_count::get_live_in_out_value_count;
5use crate::functions::get_live_out_value_count::get_live_out_value_count;
6use crate::functions::try_get_next_block_in_chain::try_get_next_block_in_chain;
7use crate::macros::codegen_assert::CODEGEN_ASSERT;
8use crate::macros::op_a::op_a;
9use crate::records::ir_block::IrBlock;
10use crate::records::ir_function::IrFunction;
11use alloc::vec::Vec;
12
13pub fn collect_direct_block_jump_path(
14 function: &mut IrFunction,
15 visited: &mut Vec<u8>,
16 mut block: *mut IrBlock,
17) -> Vec<u32> {
18 CODEGEN_ASSERT!(get_live_out_value_count(function, unsafe { &mut *block }) == 0);
19
20 let mut path = Vec::new();
21
22 while !block.is_null() {
23 let mut next_block: *mut IrBlock = core::ptr::null_mut();
24
25 let (is_jump, target_op) = {
26 let term_inst = &mut function.instructions[unsafe { (*block).finish } as usize];
27 (term_inst.cmd == IrCmd::JUMP, op_a(term_inst))
28 };
29
30 if is_jump && target_op.kind() == IrOpKind::Block {
31 let target_block = function.block_op(target_op) as *mut IrBlock;
32 let target_idx = function.get_block_index(unsafe { &*target_block });
33
34 if visited[target_idx as usize] == 0
35 && unsafe { (*target_block).kind } == IrBlockKind::Internal
36 {
37 let (live_ins, live_outs) =
38 get_live_in_out_value_count(function, unsafe { &mut *target_block }, true);
39
40 if live_ins == 0 && live_outs == 0 {
41 visited[target_idx as usize] = 1;
42 path.push(target_idx);
43
44 next_block = target_block;
45
46 loop {
47 let next_in_chain =
48 try_get_next_block_in_chain(function, unsafe { &mut *next_block });
49 if !next_in_chain.is_null() {
50 let next_in_chain_idx =
51 function.get_block_index(unsafe { &*next_in_chain });
52 visited[next_in_chain_idx as usize] = 1;
53 path.push(next_in_chain_idx);
54 next_block = next_in_chain;
55 } else {
56 break;
57 }
58 }
59 }
60 }
61 }
62
63 block = next_block;
64 }
65
66 path
67}