calyx_opt/passes/
par_to_seq.rs

1use crate::analysis;
2use crate::traversal::{Action, Named, VisResult, Visitor};
3use calyx_ir::{self as ir, LibrarySignatures};
4
5#[derive(Default)]
6/// Transforms all `par` into `seq`. Uses [analysis::ControlOrder] to get a
7/// sequentialization of `par` such that the program still computes the same
8/// value. When there is no such sequentialization, errors out.
9///
10///
11/// # Example
12/// ```
13/// par {
14///     par { A; B }
15///     C;
16/// }
17/// ```
18/// into
19/// ```
20/// seq { seq { A; B } C; }
21/// ```
22///
23/// To remove uneccessarily nested `par` blocks, run collapse-control.
24pub struct ParToSeq;
25
26impl Named for ParToSeq {
27    fn name() -> &'static str {
28        "par-to-seq"
29    }
30
31    fn description() -> &'static str {
32        "Transform `par` blocks to `seq`"
33    }
34}
35
36impl Visitor for ParToSeq {
37    /// Collapse par { par { A }; B } into par { A; B }.
38    fn finish_par(
39        &mut self,
40        s: &mut ir::Par,
41        _comp: &mut ir::Component,
42        _c: &LibrarySignatures,
43        _comps: &[ir::Component],
44    ) -> VisResult {
45        let total_order =
46            analysis::ControlOrder::<true>::get_total_order(s.stmts.drain(..))?;
47        let par = ir::Control::seq(total_order);
48        Ok(Action::change(par))
49    }
50}