calyx_opt/passes/
canonical.rsuse crate::analysis;
use crate::traversal::{Action, ConstructVisitor, Named, VisResult, Visitor};
use calyx_ir::Guard;
use calyx_ir::{self as ir, LibrarySignatures};
pub struct Canonicalize {
order: analysis::DataflowOrder,
}
impl ConstructVisitor for Canonicalize {
fn from(ctx: &ir::Context) -> calyx_utils::CalyxResult<Self>
where
Self: Sized,
{
let order = analysis::DataflowOrder::new(ctx.lib.signatures())?;
Ok(Canonicalize { order })
}
fn clear_data(&mut self) {
}
}
impl Named for Canonicalize {
fn name() -> &'static str {
"canonicalize"
}
fn description() -> &'static str {
"canonicalize the program"
}
}
impl Visitor for Canonicalize {
fn start(
&mut self,
comp: &mut ir::Component,
_ctx: &LibrarySignatures,
_comps: &[ir::Component],
) -> VisResult {
comp.for_each_assignment(|assign| {
if let Guard::Port(p) = &(*assign.guard) {
if p.borrow().is_constant(1, 1) {
assign.guard = Guard::True.into()
}
}
});
comp.for_each_static_assignment(|assign| {
if let Guard::Port(p) = &(*assign.guard) {
if p.borrow().is_constant(1, 1) {
assign.guard = Guard::True.into()
}
}
});
for gr in comp.get_groups().iter() {
let mut group = gr.borrow_mut();
let done_assign = group.done_cond_mut();
if let Guard::Port(p) = &(*done_assign.guard) {
if done_assign.src.borrow().is_constant(1, 1) {
done_assign.src = p.clone(); done_assign.guard = Guard::True.into();
}
}
let assigns = std::mem::take(&mut group.assignments);
group.assignments = self.order.dataflow_sort(assigns)?;
}
for gr in comp.get_static_groups().iter() {
let mut group = gr.borrow_mut();
let assigns = std::mem::take(&mut group.assignments);
group.assignments = self.order.dataflow_sort(assigns)?;
}
for cgr in comp.comb_groups.iter() {
let assigns = std::mem::take(&mut cgr.borrow_mut().assignments);
cgr.borrow_mut().assignments = self.order.dataflow_sort(assigns)?;
}
let cont_assigns = std::mem::take(&mut comp.continuous_assignments);
comp.continuous_assignments = self.order.dataflow_sort(cont_assigns)?;
Ok(Action::Stop)
}
}