1use calyx_ir as ir;
2
3const NODE_ID: ir::Attribute =
4 ir::Attribute::Internal(ir::InternalAttr::NODE_ID);
5const BEGIN_ID: ir::Attribute =
6 ir::Attribute::Internal(ir::InternalAttr::BEGIN_ID);
7const END_ID: ir::Attribute = ir::Attribute::Internal(ir::InternalAttr::END_ID);
8
9pub struct ControlId;
11
12impl ControlId {
13 fn compute_unique_ids_static(
14 scon: &mut ir::StaticControl,
15 mut cur_state: u64,
16 two_if_ids: bool,
17 ) -> u64 {
18 match scon {
19 ir::StaticControl::Empty(_) => cur_state,
20 ir::StaticControl::Enable(ir::StaticEnable {
21 attributes, ..
22 })
23 | ir::StaticControl::Invoke(ir::StaticInvoke {
24 attributes, ..
25 }) => {
26 attributes.insert(NODE_ID, cur_state);
27 cur_state + 1
28 }
29 ir::StaticControl::Repeat(ir::StaticRepeat {
30 attributes,
31 body,
32 ..
33 }) => {
34 attributes.insert(NODE_ID, cur_state);
35 cur_state += 1;
36 Self::compute_unique_ids_static(body, cur_state, two_if_ids)
37 }
38 ir::StaticControl::Par(ir::StaticPar {
39 stmts, attributes, ..
40 })
41 | ir::StaticControl::Seq(ir::StaticSeq {
42 stmts, attributes, ..
43 }) => {
44 attributes.insert(NODE_ID, cur_state);
45 cur_state += 1;
46 stmts.iter_mut().for_each(|stmt| {
47 let new_state = Self::compute_unique_ids_static(
48 stmt, cur_state, two_if_ids,
49 );
50 cur_state = new_state;
51 });
52 cur_state
53 }
54 ir::StaticControl::If(ir::StaticIf {
55 tbranch,
56 fbranch,
57 attributes,
58 ..
59 }) => {
60 if two_if_ids {
61 attributes.insert(BEGIN_ID, cur_state);
62 cur_state += 1;
63 cur_state = Self::compute_unique_ids_static(
64 tbranch, cur_state, two_if_ids,
65 );
66 cur_state = Self::compute_unique_ids_static(
67 fbranch, cur_state, two_if_ids,
68 );
69 attributes.insert(END_ID, cur_state);
70 cur_state + 1
71 } else {
72 attributes.insert(NODE_ID, cur_state);
73 cur_state += 1;
74 cur_state = Self::compute_unique_ids_static(
75 tbranch, cur_state, two_if_ids,
76 );
77 cur_state = Self::compute_unique_ids_static(
78 fbranch, cur_state, two_if_ids,
79 );
80 cur_state + 1
81 }
82 }
83 }
84 }
85
86 pub fn compute_unique_ids(
115 con: &mut ir::Control,
116 mut cur_state: u64,
117 two_if_ids: bool,
118 ) -> u64 {
119 match con {
120 ir::Control::Enable(ir::Enable { attributes, .. })
121 | ir::Control::Invoke(ir::Invoke { attributes, .. }) => {
122 attributes.insert(NODE_ID, cur_state);
123 cur_state + 1
124 }
125 ir::Control::Par(ir::Par {
126 stmts, attributes, ..
127 })
128 | ir::Control::Seq(ir::Seq {
129 stmts, attributes, ..
130 }) => {
131 attributes.insert(NODE_ID, cur_state);
132 cur_state += 1;
133 stmts.iter_mut().for_each(|stmt| {
134 let new_state =
135 Self::compute_unique_ids(stmt, cur_state, two_if_ids);
136 cur_state = new_state;
137 });
138 cur_state
139 }
140 ir::Control::If(ir::If {
141 tbranch,
142 fbranch,
143 attributes,
144 ..
145 }) => {
146 if two_if_ids {
147 attributes.insert(BEGIN_ID, cur_state);
148 cur_state += 1;
149 cur_state = Self::compute_unique_ids(
150 tbranch, cur_state, two_if_ids,
151 );
152 cur_state = Self::compute_unique_ids(
153 fbranch, cur_state, two_if_ids,
154 );
155 attributes.insert(END_ID, cur_state);
156 cur_state + 1
157 } else {
158 attributes.insert(NODE_ID, cur_state);
159 cur_state += 1;
160 cur_state = Self::compute_unique_ids(
161 tbranch, cur_state, two_if_ids,
162 );
163 cur_state = Self::compute_unique_ids(
164 fbranch, cur_state, two_if_ids,
165 );
166 cur_state + 1
167 }
168 }
169 ir::Control::While(ir::While {
170 body, attributes, ..
171 })
172 | ir::Control::Repeat(ir::Repeat {
173 body, attributes, ..
174 }) => {
175 attributes.insert(NODE_ID, cur_state);
176 cur_state += 1;
177 Self::compute_unique_ids(body, cur_state, two_if_ids)
178 }
179 ir::Control::Static(s) => {
180 Self::compute_unique_ids_static(s, cur_state, two_if_ids)
181 }
182 ir::Control::Empty(_) => cur_state,
183 }
184 }
185
186 pub fn get_guaranteed_attribute<A>(c: &ir::Control, attr: A) -> u64
189 where
190 A: Into<ir::Attribute>,
191 {
192 c.get_attribute(attr.into()).unwrap_or_else(||unreachable!(
193 "called get_guaranteed_attribute, meaning we had to be sure it had the attribute"
194 ))
195 }
196
197 pub fn get_guaranteed_attribute_static<A>(
200 sc: &ir::StaticControl,
201 attr: A,
202 ) -> u64
203 where
204 A: Into<ir::Attribute>,
205 {
206 sc.get_attribute(attr.into()).unwrap_or_else(||unreachable!(
207 "called get_guaranteed_attribute_static, meaning we had to be sure it had the attribute"
208 ))
209 }
210
211 pub fn get_guaranteed_id(c: &ir::Control) -> u64 {
213 Self::get_guaranteed_attribute(c, NODE_ID)
214 }
215
216 pub fn get_guaranteed_id_static(sc: &ir::StaticControl) -> u64 {
218 Self::get_guaranteed_attribute_static(sc, NODE_ID)
219 }
220
221 pub fn add_static_enable_ids_static(
224 scon: &mut ir::StaticControl,
225 mut cur_state: u64,
226 ) -> u64 {
227 match scon {
228 ir::StaticControl::Enable(se) => {
229 se.attributes.insert(NODE_ID, cur_state);
230 cur_state + 1
231 }
232 ir::StaticControl::Invoke(_) | ir::StaticControl::Empty(_) => {
233 cur_state
234 }
235 ir::StaticControl::Par(ir::StaticPar { stmts, .. })
236 | ir::StaticControl::Seq(ir::StaticSeq { stmts, .. }) => {
237 for stmt in stmts {
238 let new_state =
239 Self::add_static_enable_ids_static(stmt, cur_state);
240 cur_state = new_state
241 }
242 cur_state
243 }
244 ir::StaticControl::If(ir::StaticIf {
245 tbranch, fbranch, ..
246 }) => {
247 let mut new_state =
248 Self::add_static_enable_ids_static(tbranch, cur_state);
249 cur_state = new_state;
250 new_state =
251 Self::add_static_enable_ids_static(fbranch, cur_state);
252 new_state
253 }
254 ir::StaticControl::Repeat(ir::StaticRepeat { body, .. }) => {
255 Self::add_static_enable_ids_static(body, cur_state)
256 }
257 }
258 }
259
260 pub fn add_static_enable_ids(
263 con: &mut ir::Control,
264 mut cur_state: u64,
265 ) -> u64 {
266 match con {
267 ir::Control::Enable(_)
268 | ir::Control::Invoke(_)
269 | ir::Control::Empty(_) => cur_state,
270 ir::Control::Par(ir::Par { stmts, .. })
271 | ir::Control::Seq(ir::Seq { stmts, .. }) => {
272 for stmt in stmts {
273 let new_state =
274 Self::add_static_enable_ids(stmt, cur_state);
275 cur_state = new_state
276 }
277 cur_state
278 }
279 ir::Control::If(ir::If {
280 tbranch, fbranch, ..
281 }) => {
282 let mut new_state =
283 Self::add_static_enable_ids(tbranch, cur_state);
284 cur_state = new_state;
285 new_state = Self::add_static_enable_ids(fbranch, cur_state);
286 new_state
287 }
288 ir::Control::While(ir::While { body, .. })
289 | ir::Control::Repeat(ir::Repeat { body, .. }) => {
290 Self::add_static_enable_ids(body, cur_state)
291 }
292 ir::Control::Static(s) => {
293 Self::add_static_enable_ids_static(s, cur_state)
294 }
295 }
296 }
297
298 pub fn get_guaranteed_enable_id(se: &ir::StaticEnable) -> u64 {
301 se.get_attribute(NODE_ID).unwrap_or_else(||unreachable!(
302 "called get_guaranteed_enable_id, meaning we had to be sure it had a NODE_ID attribute"
303 ))
304 }
305}