Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/cranelift-codegen-0.91.1/src/egraph/domtree.rs
Line
Count
Source (jump to first uncovered line)
1
//! Extended domtree with various traversal support.
2
3
use crate::dominator_tree::DominatorTree;
4
use crate::ir::{Block, Function};
5
use cranelift_entity::{packed_option::PackedOption, SecondaryMap};
6
7
#[derive(Clone, Debug)]
8
pub(crate) struct DomTreeWithChildren {
9
    nodes: SecondaryMap<Block, DomTreeNode>,
10
    root: Block,
11
}
12
13
#[derive(Clone, Copy, Debug, Default)]
14
struct DomTreeNode {
15
    children: PackedOption<Block>,
16
    next: PackedOption<Block>,
17
}
18
19
impl DomTreeWithChildren {
20
0
    pub(crate) fn new(func: &Function, domtree: &DominatorTree) -> DomTreeWithChildren {
21
0
        let mut nodes: SecondaryMap<Block, DomTreeNode> =
22
0
            SecondaryMap::with_capacity(func.dfg.num_blocks());
23
24
0
        for block in func.layout.blocks() {
25
0
            let idom_inst = match domtree.idom(block) {
26
0
                Some(idom_inst) => idom_inst,
27
0
                None => continue,
28
            };
29
0
            let idom = func
30
0
                .layout
31
0
                .inst_block(idom_inst)
32
0
                .expect("Dominating instruction should be part of a block");
33
0
34
0
            nodes[block].next = nodes[idom].children;
35
0
            nodes[idom].children = block.into();
36
        }
37
38
0
        let root = func.layout.entry_block().unwrap();
39
0
40
0
        Self { nodes, root }
41
0
    }
42
43
0
    pub(crate) fn root(&self) -> Block {
44
0
        self.root
45
0
    }
46
47
0
    pub(crate) fn children<'a>(&'a self, block: Block) -> DomTreeChildIter<'a> {
48
0
        let block = self.nodes[block].children;
49
0
        DomTreeChildIter {
50
0
            domtree: self,
51
0
            block,
52
0
        }
53
0
    }
54
}
55
56
pub(crate) struct DomTreeChildIter<'a> {
57
    domtree: &'a DomTreeWithChildren,
58
    block: PackedOption<Block>,
59
}
60
61
impl<'a> Iterator for DomTreeChildIter<'a> {
62
    type Item = Block;
63
0
    fn next(&mut self) -> Option<Block> {
64
0
        self.block.expand().map(|block| {
65
0
            self.block = self.domtree.nodes[block].next;
66
0
            block
67
0
        })
68
0
    }
69
}