/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 | | } |