calyx_opt/passes/
collapse_control.rs1use crate::traversal::{Action, Named, VisResult, Visitor};
2use calyx_ir::{self as ir, GetAttributes, LibrarySignatures};
3
4#[derive(Default)]
5pub struct CollapseControl {}
52
53impl Named for CollapseControl {
54 fn name() -> &'static str {
55 "collapse-control"
56 }
57
58 fn description() -> &'static str {
59 "Collapse nested seq and par."
60 }
61}
62
63impl Visitor for CollapseControl {
64 fn finish_seq(
66 &mut self,
67 s: &mut ir::Seq,
68 _comp: &mut ir::Component,
69 _c: &LibrarySignatures,
70 _comps: &[ir::Component],
71 ) -> VisResult {
72 if s.stmts.is_empty() {
73 return Ok(Action::change(ir::Control::empty()));
74 }
75 if s.stmts.len() == 1 {
76 return Ok(Action::change(s.stmts.pop().unwrap()));
77 }
78 let mut seqs: Vec<ir::Control> = vec![];
79 for con in s.stmts.drain(..) {
80 if con.has_attribute(ir::BoolAttr::NewFSM) {
81 seqs.push(con)
83 } else {
84 match con {
85 ir::Control::Seq(mut data) => {
86 seqs.append(&mut data.stmts);
87 }
88 _ => seqs.push(con),
89 }
90 }
91 }
92 s.stmts = seqs;
93 Ok(Action::Continue)
94 }
95
96 fn finish_par(
98 &mut self,
99 s: &mut ir::Par,
100 _comp: &mut ir::Component,
101 _c: &LibrarySignatures,
102 _comps: &[ir::Component],
103 ) -> VisResult {
104 if s.stmts.is_empty() {
105 return Ok(Action::change(ir::Control::empty()));
106 }
107 if s.stmts.len() == 1 {
108 return Ok(Action::change(s.stmts.pop().unwrap()));
109 }
110 let mut pars: Vec<ir::Control> = vec![];
111 for con in s.stmts.drain(..) {
112 match con {
113 ir::Control::Par(mut data) => {
114 pars.append(&mut data.stmts);
115 }
116 _ => pars.push(con),
117 }
118 }
119 s.stmts = pars;
120 Ok(Action::Continue)
121 }
122
123 fn finish_static_par(
125 &mut self,
126 s: &mut ir::StaticPar,
127 _comp: &mut ir::Component,
128 _sigs: &LibrarySignatures,
129 _comps: &[ir::Component],
130 ) -> VisResult {
131 if s.stmts.is_empty() {
132 return Ok(Action::static_change(ir::StaticControl::empty()));
133 }
134 if s.stmts.len() == 1 {
135 let mut replacement_ctrl = s.stmts.pop().unwrap();
137 let attrs = std::mem::take(&mut s.attributes);
138 replacement_ctrl
139 .get_mut_attributes()
140 .copy_from(attrs, vec![ir::BoolAttr::OneHot]);
141
142 return Ok(Action::static_change(replacement_ctrl));
143 }
144 let mut pars: Vec<ir::StaticControl> = vec![];
145 for con in s.stmts.drain(..) {
146 match con {
147 ir::StaticControl::Par(mut data) => {
148 pars.append(&mut data.stmts);
149 }
150 _ => pars.push(con),
151 }
152 }
153 s.stmts = pars;
154 Ok(Action::Continue)
155 }
156
157 fn finish_static_seq(
159 &mut self,
160 s: &mut ir::StaticSeq,
161 _comp: &mut ir::Component,
162 _sigs: &LibrarySignatures,
163 _comps: &[ir::Component],
164 ) -> VisResult {
165 if s.stmts.is_empty() {
166 return Ok(Action::static_change(ir::StaticControl::empty()));
167 }
168 if s.stmts.len() == 1 {
169 let mut replacement_ctrl = s.stmts.pop().unwrap();
171 let attrs = std::mem::take(&mut s.attributes);
172 replacement_ctrl
173 .get_mut_attributes()
174 .copy_from(attrs, vec![ir::BoolAttr::OneHot]);
175 return Ok(Action::static_change(replacement_ctrl));
176 }
177 let mut seqs: Vec<ir::StaticControl> = vec![];
178 for con in s.stmts.drain(..) {
179 match con {
180 ir::StaticControl::Seq(mut data) => {
181 seqs.append(&mut data.stmts);
182 }
183 _ => seqs.push(con),
184 }
185 }
186 s.stmts = seqs;
187 Ok(Action::Continue)
188 }
189
190 fn finish_static_repeat(
203 &mut self,
204 s: &mut ir::StaticRepeat,
205 _comp: &mut ir::Component,
206 _sigs: &LibrarySignatures,
207 _comps: &[ir::Component],
208 ) -> VisResult {
209 if s.num_repeats == 0 {
210 return Ok(Action::static_change(ir::StaticControl::empty()));
211 }
212 if s.num_repeats == 1 {
213 return Ok(Action::static_change(s.body.take_static_control()));
214 }
215 Ok(Action::Continue)
216 }
217
218 fn finish_repeat(
219 &mut self,
220 s: &mut ir::Repeat,
221 _comp: &mut ir::Component,
222 _sigs: &LibrarySignatures,
223 _comps: &[ir::Component],
224 ) -> VisResult {
225 if s.num_repeats == 0 {
226 return Ok(Action::change(ir::Control::empty()));
227 }
228 if s.num_repeats == 1 {
229 return Ok(Action::change(s.body.take_control()));
230 }
231 Ok(Action::Continue)
232 }
233}