luaur_code_gen/functions/
compute_cfg_immediate_dominators.rs1use crate::functions::compute_block_ordering::compute_block_ordering;
2use crate::functions::find_common_dominator::find_common_dominator;
3use crate::functions::predecessors::predecessors;
4use crate::records::block_ordering::BlockOrdering;
5use crate::records::ir_function::IrFunction;
6
7pub fn compute_cfg_immediate_dominators(function: &mut IrFunction) {
8 let block_count = function.blocks.len();
9
10 function.cfg.idoms.clear();
11 function.cfg.idoms.resize(block_count, !0u32);
12
13 if block_count == 0 {
14 return;
15 }
16
17 let mut ordering: Vec<BlockOrdering> = Vec::new();
18 let mut blocks_in_post_order: Vec<u32> = Vec::new();
19 compute_block_ordering(
20 function,
21 &mut ordering,
22 None,
23 Some(&mut blocks_in_post_order),
24 );
25
26 function.cfg.idoms[0] = 0;
27
28 let mut updated = true;
29 while updated {
30 updated = false;
31
32 if blocks_in_post_order.len() < 2 {
33 break;
34 }
35
36 for i in (0..blocks_in_post_order.len() - 1).rev() {
37 let block_idx = blocks_in_post_order[i];
38 let mut new_idom = !0u32;
39
40 for pred_idx in predecessors(&function.cfg, block_idx) {
41 let pred_idom = function.cfg.idoms[pred_idx as usize];
42
43 if pred_idom != !0u32 {
44 if new_idom == !0u32 {
45 new_idom = pred_idx;
46 } else {
47 new_idom = find_common_dominator(
48 &function.cfg.idoms,
49 &ordering,
50 new_idom,
51 pred_idx,
52 );
53 }
54 }
55 }
56
57 if new_idom != function.cfg.idoms[block_idx as usize] {
58 function.cfg.idoms[block_idx as usize] = new_idom;
59 updated = true;
60 }
61 }
62 }
63
64 function.cfg.idoms[0] = !0u32;
65}