calyx_opt/passes_experimental/
metadata_table_gen.rs

1use crate::traversal::{Action, ConstructVisitor, Named, VisResult, Visitor};
2
3//use calyx_frontend::SetAttr::Pos;
4use calyx_frontend::LibrarySignatures;
5use calyx_ir::source_info::{FileId, LineNum, SourceInfoTable};
6use calyx_ir::{Component, GetAttributes, StaticPar, StaticRepeat, StaticSeq};
7use calyx_utils::WithPos;
8use std::collections::HashMap;
9use std::path::PathBuf;
10
11/// Metadata creates and stores the source info table for the currently running program
12pub struct Metadata {
13    src_table: SourceInfoTable,
14    file_ids: HashMap<String, FileId>,
15}
16
17impl Metadata {
18    /// Create an empty metadata table
19    #[allow(clippy::new_without_default)]
20    pub fn new() -> Self {
21        Self {
22            src_table: SourceInfoTable::new_empty(),
23            file_ids: HashMap::new(),
24        }
25    }
26
27    pub fn add_control_node<A: GetAttributes>(&mut self, node: &mut A) {
28        let attr = node.get_mut_attributes();
29        let node_pos = attr.copy_span();
30        let (f, (line, endline)) = node_pos.get_line_num();
31        let fnum = self.file_ids.get(f).unwrap();
32        let pos = self.src_table.push_position(
33            *fnum,
34            LineNum::new(line as u32),
35            Some(LineNum::new(endline as u32)),
36        );
37        attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
38    }
39}
40
41impl Named for Metadata {
42    fn name() -> &'static str {
43        "metadata-table-generation"
44    }
45    fn description() -> &'static str {
46        "generates metadata table for a file not containing one"
47    }
48}
49
50impl ConstructVisitor for Metadata {
51    fn from(_ctx: &calyx_ir::Context) -> calyx_utils::CalyxResult<Self>
52    where
53        Self: Sized,
54    {
55        Ok(Self::new())
56    }
57
58    fn clear_data(&mut self) {
59        // preserve across components
60        // hacky oops
61    }
62}
63impl Visitor for Metadata {
64    fn start_context(&mut self, ctx: &mut calyx_ir::Context) -> VisResult {
65        if let Some(x) = std::mem::take(&mut ctx.source_info_table) {
66            self.src_table = x;
67        }
68        Ok(Action::Continue)
69    }
70
71    // this visits each component
72    fn start(
73        &mut self,
74        comp: &mut calyx_ir::Component,
75        _sigs: &calyx_ir::LibrarySignatures,
76        _comps: &[calyx_ir::Component],
77    ) -> VisResult {
78        // implement visiting each component and adding the positions
79        // how this works:
80        // components have attributes !!
81        // check if file exists for component definition
82        let binding = comp.attributes.copy_span();
83        let (file, (line, endline)) = binding.get_line_num();
84
85        // add file to source table (if not already in)
86        if !self.file_ids.contains_key(file) {
87            let id = self.src_table.push_file(PathBuf::from(file));
88            self.file_ids.insert(String::from(file), id);
89        }
90
91        // add source position of the component itself
92        let component_file_id = self.file_ids.get(file).unwrap();
93        let component_pos = self.src_table.push_position(
94            *component_file_id,
95            LineNum::new(line as u32),
96            Some(LineNum::new(endline as u32)),
97        );
98        comp.attributes
99            .insert_set(calyx_frontend::SetAttr::Pos, component_pos.value());
100
101        // visit all groups in component
102        for rrcgrp in comp.groups.iter() {
103            let mut grp = rrcgrp.borrow_mut();
104            let attr = &mut grp.attributes;
105            let pos_data = attr.copy_span();
106            let (f, (line_start, line_end)) = pos_data.get_line_num();
107            let fid = self.file_ids.get(f).unwrap(); // this def should be in file_ids
108            let pos = self.src_table.push_position(
109                *fid,
110                LineNum::new(line_start as u32),
111                Some(LineNum::new(line_end as u32)),
112            );
113            // add tag to group attributes
114            attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
115        }
116
117        // visit all comb groups in context
118        for rrc_comb_group in comp.comb_groups.iter() {
119            let mut grp = rrc_comb_group.borrow_mut();
120            let attr = &mut grp.attributes;
121            let pos_data = attr.copy_span();
122            let (f, (line_start, line_end)) = pos_data.get_line_num();
123            let fid = self.file_ids.get(f).unwrap(); // this def should be in file_ids
124            let pos = self.src_table.push_position(
125                *fid,
126                LineNum::new(line_start as u32),
127                Some(LineNum::new(line_end as u32)),
128            );
129            // add tag to group attributes
130            attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
131        }
132
133        // visit all static groups in context
134        for rrc_static_group in comp.static_groups.iter() {
135            let mut grp = rrc_static_group.borrow_mut();
136            let attr = &mut grp.attributes;
137            let pos_data = attr.copy_span();
138            let (f, (line_start, line_end)) = pos_data.get_line_num();
139            let fid = self.file_ids.get(f).unwrap(); // this def should be in file_ids
140            let pos = self.src_table.push_position(
141                *fid,
142                LineNum::new(line_start as u32),
143                Some(LineNum::new(line_end as u32)),
144            );
145            // add tag to group attributes
146            attr.insert_set(calyx_frontend::SetAttr::Pos, pos.value());
147        }
148        Ok(Action::Continue)
149    }
150
151    fn finish_context(&mut self, ctx: &mut calyx_ir::Context) -> VisResult {
152        ctx.source_info_table = Some(std::mem::take(&mut self.src_table));
153        Ok(Action::Continue)
154    }
155
156    fn enable(
157        &mut self,
158        s: &mut calyx_ir::Enable,
159        _comp: &mut calyx_ir::Component,
160        _sigs: &calyx_ir::LibrarySignatures,
161        _comps: &[calyx_ir::Component],
162    ) -> VisResult {
163        self.add_control_node(s);
164        Ok(Action::Continue)
165    }
166
167    // control nodes
168    fn start_seq(
169        &mut self,
170        s: &mut calyx_ir::Seq,
171        _comp: &mut calyx_ir::Component,
172        _sigs: &calyx_ir::LibrarySignatures,
173        _comps: &[calyx_ir::Component],
174    ) -> VisResult {
175        self.add_control_node(s);
176        Ok(Action::Continue)
177    }
178
179    fn start_par(
180        &mut self,
181        s: &mut calyx_ir::Par,
182        _comp: &mut calyx_ir::Component,
183        _sigs: &calyx_ir::LibrarySignatures,
184        _comps: &[calyx_ir::Component],
185    ) -> VisResult {
186        self.add_control_node(s);
187        Ok(Action::Continue)
188    }
189
190    fn start_if(
191        &mut self,
192        s: &mut calyx_ir::If,
193        _comp: &mut calyx_ir::Component,
194        _sigs: &calyx_ir::LibrarySignatures,
195        _comps: &[calyx_ir::Component],
196    ) -> VisResult {
197        self.add_control_node(s);
198        Ok(Action::Continue)
199    }
200
201    fn start_static_seq(
202        &mut self,
203        s: &mut StaticSeq,
204        _comp: &mut Component,
205        _sigs: &LibrarySignatures,
206        _comps: &[Component],
207    ) -> VisResult {
208        self.add_control_node(s);
209        Ok(Action::Continue)
210    }
211
212    fn start_static_par(
213        &mut self,
214        s: &mut StaticPar,
215        _comp: &mut Component,
216        _sigs: &LibrarySignatures,
217        _comps: &[Component],
218    ) -> VisResult {
219        self.add_control_node(s);
220        Ok(Action::Continue)
221    }
222
223    fn start_static_repeat(
224        &mut self,
225        s: &mut StaticRepeat,
226        _comp: &mut Component,
227        _sigs: &LibrarySignatures,
228        _comps: &[Component],
229    ) -> VisResult {
230        self.add_control_node(s);
231        Ok(Action::Continue)
232    }
233
234    fn start_while(
235        &mut self,
236        s: &mut calyx_ir::While,
237        _comp: &mut calyx_ir::Component,
238        _sigs: &calyx_ir::LibrarySignatures,
239        _comps: &[calyx_ir::Component],
240    ) -> VisResult {
241        self.add_control_node(s);
242        Ok(Action::Continue)
243    }
244
245    fn start_repeat(
246        &mut self,
247        s: &mut calyx_ir::Repeat,
248        _comp: &mut calyx_ir::Component,
249        _sigs: &calyx_ir::LibrarySignatures,
250        _comps: &[calyx_ir::Component],
251    ) -> VisResult {
252        self.add_control_node(s);
253        Ok(Action::Continue)
254    }
255}