calyx_opt/passes/
dead_group_removal.rs

1use crate::traversal::{Action, Named, VisResult, Visitor};
2use calyx_ir::{self as ir, LibrarySignatures};
3use std::collections::HashSet;
4
5/// Removes unused groups and combinational groups from components.
6/// A group is considered in use when it shows up in an [ir::Enable].
7/// A combinational group is considered in use when it is a part of an
8/// [ir::If] or [ir::While] or [ir::Invoke].
9#[derive(Default)]
10pub struct DeadGroupRemoval {
11    used_groups: HashSet<ir::Id>,
12    used_comb_groups: HashSet<ir::Id>,
13}
14
15impl Named for DeadGroupRemoval {
16    fn name() -> &'static str {
17        "dead-group-removal"
18    }
19
20    fn description() -> &'static str {
21        "removes unsed groups from components"
22    }
23}
24
25impl Visitor for DeadGroupRemoval {
26    fn enable(
27        &mut self,
28        s: &mut ir::Enable,
29        _comp: &mut ir::Component,
30        _sigs: &ir::LibrarySignatures,
31        _comps: &[ir::Component],
32    ) -> VisResult {
33        self.used_groups.insert(s.group.borrow().name());
34        Ok(Action::Continue)
35    }
36
37    fn static_enable(
38        &mut self,
39        s: &mut ir::StaticEnable,
40        _comp: &mut ir::Component,
41        _sigs: &ir::LibrarySignatures,
42        _comps: &[ir::Component],
43    ) -> VisResult {
44        self.used_groups.insert(s.group.borrow().name());
45        Ok(Action::Continue)
46    }
47
48    fn finish_if(
49        &mut self,
50        s: &mut ir::If,
51        _comp: &mut ir::Component,
52        _sigs: &ir::LibrarySignatures,
53        _comps: &[ir::Component],
54    ) -> VisResult {
55        if let Some(cg) = &s.cond {
56            self.used_comb_groups.insert(cg.borrow().name());
57        }
58        Ok(Action::Continue)
59    }
60
61    fn invoke(
62        &mut self,
63        s: &mut ir::Invoke,
64        _comp: &mut ir::Component,
65        _sigs: &ir::LibrarySignatures,
66        _comps: &[ir::Component],
67    ) -> VisResult {
68        if let Some(cg) = &s.comb_group {
69            self.used_comb_groups.insert(cg.borrow().name());
70        }
71        Ok(Action::Continue)
72    }
73
74    fn finish_while(
75        &mut self,
76        s: &mut ir::While,
77        _comp: &mut ir::Component,
78        _sigs: &ir::LibrarySignatures,
79        _comps: &[ir::Component],
80    ) -> VisResult {
81        if let Some(cg) = &s.cond {
82            self.used_comb_groups.insert(cg.borrow().name());
83        }
84        Ok(Action::Continue)
85    }
86
87    fn finish(
88        &mut self,
89        comp: &mut ir::Component,
90        _sigs: &LibrarySignatures,
91        _comps: &[ir::Component],
92    ) -> VisResult {
93        // Groups that are driven by their `go` signals should not be
94        // removed.
95        for group in comp.get_groups().iter() {
96            for assign in &group.borrow().assignments {
97                let dst = assign.dst.borrow();
98                if dst.is_hole() && dst.name == "go" {
99                    self.used_groups.insert(dst.get_parent_name());
100                }
101            }
102        }
103
104        for assign in &comp.continuous_assignments {
105            let dst = assign.dst.borrow();
106            if dst.is_hole() && dst.name == "go" {
107                self.used_groups.insert(dst.get_parent_name());
108            }
109        }
110
111        for group in comp.get_static_groups().iter() {
112            for assign in &group.borrow().assignments {
113                let dst = assign.dst.borrow();
114                if dst.is_hole() && dst.name == "go" {
115                    self.used_groups.insert(dst.get_parent_name());
116                }
117            }
118        }
119
120        // Remove Groups that are not used
121        comp.get_groups_mut()
122            .retain(|g| self.used_groups.contains(&g.borrow().name()));
123        comp.get_static_groups_mut()
124            .retain(|g| self.used_groups.contains(&g.borrow().name()));
125        comp.comb_groups
126            .retain(|cg| self.used_comb_groups.contains(&cg.borrow().name()));
127
128        Ok(Action::Stop)
129    }
130}