leo_passes/static_single_assignment/
visitor.rs1use crate::{CompilerState, RenameTable};
18
19use leo_ast::{Expression, Identifier, Node, Statement};
20use leo_span::Symbol;
21
22pub struct SsaFormingVisitor<'a> {
23 pub state: &'a mut CompilerState,
24 pub rename_table: RenameTable,
26 pub program: Symbol,
28 pub rename_defs: bool,
30}
31
32impl<'a> SsaFormingVisitor<'a> {
33 pub fn new(state: &'a mut CompilerState, input: crate::SsaFormingInput, program: Symbol) -> Self {
34 Self { state, rename_table: RenameTable::new(None), program, rename_defs: input.rename_defs }
35 }
36
37 pub(crate) fn push(&mut self) {
39 let parent_table = core::mem::take(&mut self.rename_table);
40 self.rename_table = RenameTable::new(Some(Box::from(parent_table)));
41 }
42
43 pub(crate) fn pop(&mut self) -> RenameTable {
45 let parent = self.rename_table.parent.clone().unwrap_or_default();
46 core::mem::replace(&mut self.rename_table, *parent)
47 }
48
49 pub(crate) fn rename_identifier(&mut self, mut identifier: Identifier) -> Identifier {
50 self.rename_table.update(identifier.name, identifier.name, identifier.id);
52
53 let new_name = self.state.assigner.unique_symbol(identifier.name, "$#");
54 self.rename_table.update(identifier.name, new_name, identifier.id);
55 identifier.name = new_name;
56 identifier
57 }
58
59 pub(crate) fn simple_definition(&mut self, identifier: Identifier, rhs: Expression) -> Statement {
60 let type_ = match self.state.type_table.get(&rhs.id()) {
62 Some(type_) => type_,
63 None => unreachable!("Type checking guarantees that all expressions have a type."),
64 };
65 self.state.type_table.insert(identifier.id(), type_);
66 self.rename_table.update(identifier.name, identifier.name, identifier.id);
68 self.state.assigner.simple_definition(identifier, rhs, self.state.node_builder.next_id())
70 }
71
72 pub(crate) fn unique_simple_definition(&mut self, expr: Expression) -> (Identifier, Statement) {
76 let name = self.state.assigner.unique_symbol("$var", "$");
78
79 let place = Identifier { name, span: Default::default(), id: self.state.node_builder.next_id() };
81
82 let statement = self.simple_definition(place, expr);
84
85 (place, statement)
86 }
87}