calyx_opt/passes/
remove_ids.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::traversal::{Action, Named, VisResult, Visitor};
use calyx_ir::{self as ir, GetAttributes, LibrarySignatures};

const NODE_ID: ir::Attribute =
    ir::Attribute::Internal(ir::InternalAttr::NODE_ID);
const BEGIN_ID: ir::Attribute =
    ir::Attribute::Internal(ir::InternalAttr::BEGIN_ID);
const END_ID: ir::Attribute = ir::Attribute::Internal(ir::InternalAttr::END_ID);

#[derive(Default)]
/// Removes NODE_ID, BEGIN_ID, and END_ID from each control statement
pub struct RemoveIds;

impl Named for RemoveIds {
    fn name() -> &'static str {
        "remove-ids"
    }

    fn description() -> &'static str {
        "removes the NODE_ID, BEGIN_ID, and END_ID from the control flow"
    }
}

impl Visitor for RemoveIds {
    fn start(
        &mut self,
        comp: &mut ir::Component,
        _ctx: &LibrarySignatures,
        _comps: &[ir::Component],
    ) -> VisResult {
        remove_ids(&mut comp.control.borrow_mut());
        Ok(Action::Stop)
    }
}

fn remove_ids_static(sc: &mut ir::StaticControl) {
    let atts = sc.get_mut_attributes();
    atts.remove(BEGIN_ID);
    atts.remove(END_ID);
    atts.remove(NODE_ID);
    match sc {
        ir::StaticControl::Empty(_) | ir::StaticControl::Invoke(_) => (),
        ir::StaticControl::Enable(ir::StaticEnable { group, .. }) => {
            group.borrow_mut().remove_attribute(NODE_ID)
        }
        ir::StaticControl::Repeat(ir::StaticRepeat { body, .. }) => {
            remove_ids_static(body)
        }
        ir::StaticControl::Seq(ir::StaticSeq { stmts, .. })
        | ir::StaticControl::Par(ir::StaticPar { stmts, .. }) => {
            for stmt in stmts {
                remove_ids_static(stmt);
            }
        }
        ir::StaticControl::If(ir::StaticIf {
            tbranch, fbranch, ..
        }) => {
            remove_ids_static(tbranch);
            remove_ids_static(fbranch);
        }
    }
}

fn remove_ids(c: &mut ir::Control) {
    let atts = c.get_mut_attributes();
    atts.remove(BEGIN_ID);
    atts.remove(END_ID);
    atts.remove(NODE_ID);
    match c {
        ir::Control::Empty(_) | ir::Control::Invoke(_) => (),
        ir::Control::Enable(ir::Enable { group, .. }) => {
            group.borrow_mut().remove_attribute(NODE_ID)
        }
        ir::Control::While(ir::While { body, .. })
        | ir::Control::Repeat(ir::Repeat { body, .. }) => {
            remove_ids(body);
        }
        ir::Control::If(ir::If {
            tbranch, fbranch, ..
        }) => {
            remove_ids(tbranch);
            remove_ids(fbranch);
        }
        ir::Control::Seq(ir::Seq { stmts, .. })
        | ir::Control::Par(ir::Par { stmts, .. }) => {
            for stmt in stmts {
                remove_ids(stmt);
            }
        }
        ir::Control::Static(sc) => remove_ids_static(sc),
    }
}