Skip to main content

luaur_code_gen/functions/
compute_cfg_immediate_dominators.rs

1use 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}