calyx_opt/passes_experimental/
external_to_ref.rs

1use crate::traversal::{Action, ConstructVisitor, Named, VisResult, Visitor};
2use calyx_ir::{self as ir, GetAttributes, LibrarySignatures};
3use calyx_utils::CalyxResult;
4
5/// Turns memory cell primitives with the `@external(1)` attribute into
6/// `ref` memory cells without the `@external` attribute.
7pub struct ExternalToRef;
8
9impl Named for ExternalToRef {
10    fn name() -> &'static str {
11        "external-to-ref"
12    }
13
14    fn description() -> &'static str {
15        "Turn memory cells marked with `@external(1) into `ref` memory cells."
16    }
17}
18
19impl ConstructVisitor for ExternalToRef {
20    fn from(_ctx: &ir::Context) -> CalyxResult<Self>
21    where
22        Self: Sized,
23    {
24        let external_to_ref = ExternalToRef;
25        Ok(external_to_ref)
26    }
27
28    fn clear_data(&mut self) {}
29}
30
31impl Visitor for ExternalToRef {
32    fn start(
33        &mut self,
34        comp: &mut ir::Component,
35        _ctx: &LibrarySignatures,
36        _comps: &[ir::Component],
37    ) -> VisResult {
38        // Iterate over each cell in the component
39        for cell in comp.cells.iter() {
40            let mut cell_ref = cell.borrow_mut();
41            if cell_ref.get_attributes().has(ir::BoolAttr::External) {
42                // Change the cell type to `ref` and remove the external attribute
43                cell_ref.get_mut_attributes().remove(ir::BoolAttr::External);
44                cell_ref.set_reference(true);
45            }
46        }
47        // Continue visiting other nodes in the AST
48        Ok(Action::Continue)
49    }
50}