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