Refactor AST nodes to use Rc
This commit refactors various AST node types to use `Rc` (Reference Counting) instead of `Box`. This change is primarily driven by the need for shared ownership and more efficient handling of potentially recursive or shared data structures within the AST. The main benefits of this change include: - **Reduced cloning:** `Rc` allows multiple parts of the AST to refer to the same node without needing to clone the entire node. This is particularly beneficial for optimization passes where nodes might be visited multiple times. - **Enabling sharing:** It makes it easier to represent scenarios where a single AST node might be a child of multiple parent nodes. - **Performance improvements:** By avoiding unnecessary deep copies of AST nodes, this change can lead to performance gains, especially during complex compilation phases.
This commit is contained in:
@@ -2,11 +2,12 @@ use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalS
|
||||
use crate::ast::nodes::Node;
|
||||
use crate::ast::types::Value;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SubstitutionMap {
|
||||
pub values: HashMap<Address, Value>,
|
||||
pub ast_substitutions: HashMap<Address, AnalyzedNode>,
|
||||
pub ast_substitutions: HashMap<Address, Rc<AnalyzedNode>>,
|
||||
pub slot_mapping: HashMap<LocalSlot, LocalSlot>,
|
||||
pub assigned: HashSet<Address>,
|
||||
pub next_slot: u32,
|
||||
@@ -38,7 +39,7 @@ impl SubstitutionMap {
|
||||
}
|
||||
|
||||
pub fn add_ast_substitution(&mut self, addr: Address, node: AnalyzedNode) {
|
||||
self.ast_substitutions.insert(addr, node);
|
||||
self.ast_substitutions.insert(addr, Rc::new(node));
|
||||
}
|
||||
|
||||
pub fn map_slot(&mut self, old_slot: LocalSlot) -> LocalSlot {
|
||||
@@ -81,12 +82,13 @@ impl SubstitutionMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reindex_upvalues(&self, node: AnalyzedNode, mapping: &[Option<u32>]) -> AnalyzedNode {
|
||||
let (new_kind, metrics) = match node.kind {
|
||||
pub fn reindex_upvalues(&self, node_rc: Rc<AnalyzedNode>, mapping: &[Option<u32>]) -> Rc<AnalyzedNode> {
|
||||
let node = &*node_rc;
|
||||
let (new_kind, metrics) = match &node.kind {
|
||||
BoundKind::Get { addr, name } => (
|
||||
BoundKind::Get {
|
||||
addr: self.reindex_addr(addr, mapping),
|
||||
name,
|
||||
addr: self.reindex_addr(*addr, mapping),
|
||||
name: name.clone(),
|
||||
},
|
||||
node.ty.clone(),
|
||||
),
|
||||
@@ -98,14 +100,14 @@ impl SubstitutionMap {
|
||||
} => {
|
||||
let mut next_upvalues = Vec::new();
|
||||
for addr in upvalues {
|
||||
next_upvalues.push(self.reindex_addr(addr, mapping));
|
||||
next_upvalues.push(self.reindex_addr(*addr, mapping));
|
||||
}
|
||||
(
|
||||
BoundKind::Lambda {
|
||||
params,
|
||||
params: params.clone(),
|
||||
upvalues: next_upvalues,
|
||||
body,
|
||||
positional_count,
|
||||
body: body.clone(),
|
||||
positional_count: *positional_count,
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
@@ -115,9 +117,9 @@ impl SubstitutionMap {
|
||||
then_br,
|
||||
else_br,
|
||||
} => {
|
||||
let cond = Box::new(self.reindex_upvalues(*cond, mapping));
|
||||
let then_br = Box::new(self.reindex_upvalues(*then_br, mapping));
|
||||
let else_br = else_br.map(|e| Box::new(self.reindex_upvalues(*e, mapping)));
|
||||
let cond = self.reindex_upvalues(cond.clone(), mapping);
|
||||
let then_br = self.reindex_upvalues(then_br.clone(), mapping);
|
||||
let else_br = else_br.as_ref().map(|e| self.reindex_upvalues(e.clone(), mapping));
|
||||
(
|
||||
BoundKind::If {
|
||||
cond,
|
||||
@@ -129,14 +131,14 @@ impl SubstitutionMap {
|
||||
}
|
||||
BoundKind::Block { exprs } => {
|
||||
let exprs = exprs
|
||||
.into_iter()
|
||||
.map(|e| self.reindex_upvalues(e, mapping))
|
||||
.iter()
|
||||
.map(|e| self.reindex_upvalues(e.clone(), mapping))
|
||||
.collect();
|
||||
(BoundKind::Block { exprs }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Call { callee, args } => {
|
||||
let callee = Box::new(self.reindex_upvalues(*callee, mapping));
|
||||
let args = Box::new(self.reindex_upvalues(*args, mapping));
|
||||
let callee = self.reindex_upvalues(callee.clone(), mapping);
|
||||
let args = self.reindex_upvalues(args.clone(), mapping);
|
||||
(BoundKind::Call { callee, args }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Define {
|
||||
@@ -146,42 +148,58 @@ impl SubstitutionMap {
|
||||
value,
|
||||
captured_by,
|
||||
} => {
|
||||
let value = Box::new(self.reindex_upvalues(*value, mapping));
|
||||
let value = self.reindex_upvalues(value.clone(), mapping);
|
||||
(
|
||||
BoundKind::Define {
|
||||
name,
|
||||
addr,
|
||||
kind,
|
||||
name: name.clone(),
|
||||
addr: *addr,
|
||||
kind: *kind,
|
||||
value,
|
||||
captured_by,
|
||||
captured_by: captured_by.clone(),
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
}
|
||||
BoundKind::Set { addr, value } => {
|
||||
let value = Box::new(self.reindex_upvalues(*value, mapping));
|
||||
(BoundKind::Set { addr, value }, node.ty.clone())
|
||||
let value = self.reindex_upvalues(value.clone(), mapping);
|
||||
(
|
||||
BoundKind::Set {
|
||||
addr: *addr,
|
||||
value,
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
}
|
||||
BoundKind::Tuple { elements } => {
|
||||
let elements = elements
|
||||
.into_iter()
|
||||
.map(|e| self.reindex_upvalues(e, mapping))
|
||||
.iter()
|
||||
.map(|e| self.reindex_upvalues(e.clone(), mapping))
|
||||
.collect();
|
||||
(BoundKind::Tuple { elements }, node.ty.clone())
|
||||
}
|
||||
BoundKind::Record { layout, values } => {
|
||||
let values = values
|
||||
.into_iter()
|
||||
.map(|v| self.reindex_upvalues(v, mapping))
|
||||
.iter()
|
||||
.map(|v| self.reindex_upvalues(v.clone(), mapping))
|
||||
.collect();
|
||||
(BoundKind::Record { layout, values }, node.ty.clone())
|
||||
(BoundKind::Record { layout: layout.clone(), values }, node.ty.clone())
|
||||
}
|
||||
k => (k, node.ty.clone()),
|
||||
BoundKind::Expansion { original_call, bound_expanded } => {
|
||||
let bound_expanded = self.reindex_upvalues(bound_expanded.clone(), mapping);
|
||||
(
|
||||
BoundKind::Expansion {
|
||||
original_call: original_call.clone(),
|
||||
bound_expanded,
|
||||
},
|
||||
node.ty.clone(),
|
||||
)
|
||||
}
|
||||
k => (k.clone(), node.ty.clone()),
|
||||
};
|
||||
Node {
|
||||
Rc::new(Node {
|
||||
identity: node.identity.clone(),
|
||||
kind: new_kind,
|
||||
ty: metrics,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user