use super::{GraphAnalysis, ReadWriteSet};
use crate::analysis::ShareSet;
use calyx_ir::{self as ir, RRC};
pub struct VariableDetection;
impl VariableDetection {
pub fn variable_like(
group_ref: &RRC<ir::Group>,
state_share: &ShareSet,
) -> Option<(ir::CellType, ir::Id)> {
let group = group_ref.borrow();
let writes = ReadWriteSet::write_set(group.assignments.iter())
.filter(|cell| state_share.is_shareable_component(cell))
.collect::<Vec<_>>();
if writes.len() != 1 {
log::debug!(
"`{}' is not VariableLike: Writes performed to multiple cells",
group.name()
);
return None;
}
let cell = writes[0].borrow();
let graph = GraphAnalysis::from(&*group);
let go_port = cell.find_with_attr(ir::NumAttr::Go)?;
let activation = graph
.writes_to(&go_port.borrow())
.map(|src| src.borrow().is_constant(1, 1))
.collect::<Vec<_>>();
if activation.len() != 1 || (!activation.is_empty() && !activation[0]) {
log::debug!("`{}' is not variableLike: Assignment to cell's go port is not 1'd1", group.name());
return None;
}
let activation = graph
.writes_to(&group.get("done").borrow())
.filter(|src| !src.borrow().is_constant(1, 1))
.map(|src| src.borrow().get_parent_name() == cell.name())
.collect::<Vec<_>>();
if activation.len() != 1 || (!activation.is_empty() && !activation[0]) {
log::debug!("`{}' is not variableLike: Assignment to group's done port is not cell.done", group.name());
return None;
}
Some((cell.prototype.clone(), cell.name()))
}
}