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