calyx_opt/passes/
unroll_bound.rs

1use crate::traversal::{Action, Named, VisResult, Visitor};
2use calyx_ir::{self as ir};
3
4/// Fully unroll all `while` loops with a given `@bound`.
5#[derive(Default)]
6pub struct UnrollBounded;
7
8impl Named for UnrollBounded {
9    fn name() -> &'static str {
10        "unroll-bound"
11    }
12
13    fn description() -> &'static str {
14        "fully unroll loops with a given @bound"
15    }
16}
17
18impl Visitor for UnrollBounded {
19    fn start_while(
20        &mut self,
21        s: &mut ir::While,
22        _comp: &mut ir::Component,
23        _sigs: &ir::LibrarySignatures,
24        _comps: &[ir::Component],
25    ) -> VisResult {
26        if let Some(bound) = s.attributes.get(ir::NumAttr::Bound) {
27            let body =
28                *std::mem::replace(&mut s.body, Box::new(ir::Control::empty()));
29            let nb = ir::Control::seq(
30                (0..bound).map(|_| ir::Cloner::control(&body)).collect(),
31            );
32            Ok(Action::change(nb))
33        } else {
34            Ok(Action::Continue)
35        }
36    }
37}