calyx_opt/analysis/
variable_detection.rs1use super::{GraphAnalysis, read_write_set::AssignmentAnalysis};
2use crate::analysis::ShareSet;
3use calyx_ir::{self as ir, RRC};
4
5pub struct VariableDetection;
7
8impl VariableDetection {
9 pub fn variable_like(
17 group_ref: &RRC<ir::Group>,
18 state_share: &ShareSet,
19 ) -> Option<(ir::CellType, ir::Id)> {
20 let group = group_ref.borrow();
21
22 let writes = group
23 .assignments
24 .iter()
25 .analysis()
26 .cell_writes()
27 .filter(|cell| state_share.is_shareable_component(cell))
28 .collect::<Vec<_>>();
29
30 if writes.len() != 1 {
31 log::debug!(
32 "`{}' is not VariableLike: Writes performed to multiple cells",
33 group.name()
34 );
35 return None;
37 }
38
39 let cell = writes[0].borrow();
40
41 let graph = GraphAnalysis::from(&*group);
45 let go_port =
46 cell.find_unique_with_attr(ir::NumAttr::Go).ok().flatten()?;
47 let activation = graph
48 .writes_to(&go_port.borrow())
49 .map(|src| src.borrow().is_constant(1, 1))
50 .collect::<Vec<_>>();
51 if activation.len() != 1 || (!activation.is_empty() && !activation[0]) {
52 log::debug!(
53 "`{}' is not variableLike: Assignment to cell's go port is not 1'd1",
54 group.name()
55 );
56 return None;
58 }
59
60 let activation = graph
62 .writes_to(&group.get("done").borrow())
63 .filter(|src| !src.borrow().is_constant(1, 1))
65 .map(|src| src.borrow().get_parent_name() == cell.name())
66 .collect::<Vec<_>>();
67 if activation.len() != 1 || (!activation.is_empty() && !activation[0]) {
68 log::debug!(
69 "`{}' is not variableLike: Assignment to group's done port is not cell.done",
70 group.name()
71 );
72 return None;
74 }
75
76 Some((cell.prototype.clone(), cell.name()))
77 }
78}