calyx_opt/passes/
dead_group_removal.rs1use crate::traversal::{Action, Named, VisResult, Visitor};
2use calyx_ir::{self as ir, LibrarySignatures};
3use std::collections::HashSet;
4
5#[derive(Default)]
10pub struct DeadGroupRemoval {
11 used_groups: HashSet<ir::Id>,
12 used_comb_groups: HashSet<ir::Id>,
13}
14
15impl DeadGroupRemoval {
16 fn push_group_names(
19 group_names: &mut Vec<ir::Id>,
20 port: &ir::RRC<ir::Port>,
21 ) {
22 if let ir::PortParent::Group(group_wref) = &port.borrow().parent {
23 group_names.push(group_wref.upgrade().borrow().name());
24 }
25 }
26}
27
28impl Named for DeadGroupRemoval {
29 fn name() -> &'static str {
30 "dead-group-removal"
31 }
32
33 fn description() -> &'static str {
34 "removes unsed groups from components"
35 }
36}
37
38impl Visitor for DeadGroupRemoval {
39 fn enable(
40 &mut self,
41 s: &mut ir::Enable,
42 _comp: &mut ir::Component,
43 _sigs: &ir::LibrarySignatures,
44 _comps: &[ir::Component],
45 ) -> VisResult {
46 self.used_groups.insert(s.group.borrow().name());
47 Ok(Action::Continue)
48 }
49
50 fn fsm_enable(
51 &mut self,
52 s: &mut calyx_ir::FSMEnable,
53 _comp: &mut calyx_ir::Component,
54 _sigs: &LibrarySignatures,
55 _comps: &[calyx_ir::Component],
56 ) -> VisResult {
57 self.used_groups.extend(
59 s.fsm
60 .borrow()
61 .get_called_port_parents(DeadGroupRemoval::push_group_names),
62 );
63 Ok(Action::Continue)
64 }
65
66 fn static_enable(
67 &mut self,
68 s: &mut ir::StaticEnable,
69 _comp: &mut ir::Component,
70 _sigs: &ir::LibrarySignatures,
71 _comps: &[ir::Component],
72 ) -> VisResult {
73 self.used_groups.insert(s.group.borrow().name());
74 Ok(Action::Continue)
75 }
76
77 fn finish_if(
78 &mut self,
79 s: &mut ir::If,
80 _comp: &mut ir::Component,
81 _sigs: &ir::LibrarySignatures,
82 _comps: &[ir::Component],
83 ) -> VisResult {
84 if let Some(cg) = &s.cond {
85 self.used_comb_groups.insert(cg.borrow().name());
86 }
87 Ok(Action::Continue)
88 }
89
90 fn invoke(
91 &mut self,
92 s: &mut ir::Invoke,
93 _comp: &mut ir::Component,
94 _sigs: &ir::LibrarySignatures,
95 _comps: &[ir::Component],
96 ) -> VisResult {
97 if let Some(cg) = &s.comb_group {
98 self.used_comb_groups.insert(cg.borrow().name());
99 }
100 Ok(Action::Continue)
101 }
102
103 fn finish_while(
104 &mut self,
105 s: &mut ir::While,
106 _comp: &mut ir::Component,
107 _sigs: &ir::LibrarySignatures,
108 _comps: &[ir::Component],
109 ) -> VisResult {
110 if let Some(cg) = &s.cond {
111 self.used_comb_groups.insert(cg.borrow().name());
112 }
113 Ok(Action::Continue)
114 }
115
116 fn finish(
117 &mut self,
118 comp: &mut ir::Component,
119 _sigs: &LibrarySignatures,
120 _comps: &[ir::Component],
121 ) -> VisResult {
122 for group in comp.get_groups().iter() {
125 for assign in &group.borrow().assignments {
126 let dst = assign.dst.borrow();
127 if dst.is_hole() && dst.name == "go" {
128 self.used_groups.insert(dst.get_parent_name());
129 }
130 }
131 }
132
133 for assign in &comp.continuous_assignments {
134 let dst = assign.dst.borrow();
135 if dst.is_hole() && dst.name == "go" {
136 self.used_groups.insert(dst.get_parent_name());
137 }
138 }
139
140 for group in comp.get_static_groups().iter() {
141 for assign in &group.borrow().assignments {
142 let dst = assign.dst.borrow();
143 if dst.is_hole() && dst.name == "go" {
144 self.used_groups.insert(dst.get_parent_name());
145 }
146 }
147 }
148
149 for fsm in comp.get_fsms().iter() {
151 self.used_groups.extend(
152 fsm.borrow().get_called_port_parents(
153 DeadGroupRemoval::push_group_names,
154 ),
155 );
156 }
157
158 comp.get_groups_mut()
160 .retain(|g| self.used_groups.contains(&g.borrow().name()));
161 comp.get_static_groups_mut()
162 .retain(|g| self.used_groups.contains(&g.borrow().name()));
163 comp.comb_groups
164 .retain(|cg| self.used_comb_groups.contains(&cg.borrow().name()));
165
166 Ok(Action::Stop)
167 }
168}