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:
@@ -86,11 +86,11 @@ impl<'a> Analyzer<'a> {
|
||||
BoundKind::FieldAccessor(k) => (BoundKind::FieldAccessor(*k), Purity::Pure),
|
||||
|
||||
BoundKind::GetField { rec, field } => {
|
||||
let rec_m = self.visit(Rc::new((**rec).clone()));
|
||||
let rec_m = self.visit(rec.clone());
|
||||
let p = rec_m.ty.purity;
|
||||
(
|
||||
BoundKind::GetField {
|
||||
rec: Box::new(rec_m),
|
||||
rec: Rc::new(rec_m),
|
||||
field: *field,
|
||||
},
|
||||
p,
|
||||
@@ -98,11 +98,11 @@ impl<'a> Analyzer<'a> {
|
||||
}
|
||||
|
||||
BoundKind::Set { addr, value } => {
|
||||
let val_m = self.visit(Rc::new((**value).clone()));
|
||||
let val_m = self.visit(value.clone());
|
||||
(
|
||||
BoundKind::Set {
|
||||
addr: *addr,
|
||||
value: Box::new(val_m),
|
||||
value: Rc::new(val_m),
|
||||
},
|
||||
Purity::Impure,
|
||||
)
|
||||
@@ -115,14 +115,14 @@ impl<'a> Analyzer<'a> {
|
||||
value,
|
||||
captured_by,
|
||||
} => {
|
||||
let val_m = self.visit(Rc::new((**value).clone()));
|
||||
let val_m = self.visit(value.clone());
|
||||
let p = val_m.ty.purity;
|
||||
(
|
||||
BoundKind::Define {
|
||||
name: name.clone(),
|
||||
addr: *addr,
|
||||
kind: *kind,
|
||||
value: Box::new(val_m),
|
||||
value: Rc::new(val_m),
|
||||
captured_by: captured_by.clone(),
|
||||
},
|
||||
p,
|
||||
@@ -134,9 +134,9 @@ impl<'a> Analyzer<'a> {
|
||||
then_br,
|
||||
else_br,
|
||||
} => {
|
||||
let cond_m = self.visit(Rc::new((**cond).clone()));
|
||||
let then_m = self.visit(Rc::new((**then_br).clone()));
|
||||
let else_m = else_br.as_ref().map(|e| self.visit(Rc::new((**e).clone())));
|
||||
let cond_m = self.visit(cond.clone());
|
||||
let then_m = self.visit(then_br.clone());
|
||||
let else_m = else_br.as_ref().map(|e| self.visit(e.clone()));
|
||||
|
||||
let mut p = cond_m.ty.purity.min(then_m.ty.purity);
|
||||
if let Some(ref em) = else_m {
|
||||
@@ -144,9 +144,9 @@ impl<'a> Analyzer<'a> {
|
||||
}
|
||||
(
|
||||
BoundKind::If {
|
||||
cond: Box::new(cond_m),
|
||||
then_br: Box::new(then_m),
|
||||
else_br: else_m.map(Box::new),
|
||||
cond: Rc::new(cond_m),
|
||||
then_br: Rc::new(then_m),
|
||||
else_br: else_m.map(Rc::new),
|
||||
},
|
||||
p,
|
||||
)
|
||||
@@ -176,20 +176,20 @@ impl<'a> Analyzer<'a> {
|
||||
}
|
||||
|
||||
BoundKind::Destructure { pattern, value } => {
|
||||
let pat_m = self.visit(Rc::new((**pattern).clone()));
|
||||
let val_m = self.visit(Rc::new((**value).clone()));
|
||||
let pat_m = self.visit(pattern.clone());
|
||||
let val_m = self.visit(value.clone());
|
||||
(
|
||||
BoundKind::Destructure {
|
||||
pattern: Box::new(pat_m),
|
||||
value: Box::new(val_m),
|
||||
pattern: Rc::new(pat_m),
|
||||
value: Rc::new(val_m),
|
||||
},
|
||||
Purity::Impure,
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Call { callee, args } => {
|
||||
let callee_m = self.visit(Rc::new((**callee).clone()));
|
||||
let args_m = self.visit(Rc::new((**args).clone()));
|
||||
let callee_m = self.visit(callee.clone());
|
||||
let args_m = self.visit(args.clone());
|
||||
|
||||
if let BoundKind::Get {
|
||||
addr: Address::Global(idx),
|
||||
@@ -217,22 +217,22 @@ impl<'a> Analyzer<'a> {
|
||||
let p = callee_m.ty.purity.min(args_m.ty.purity).min(p_func);
|
||||
(
|
||||
BoundKind::Call {
|
||||
callee: Box::new(callee_m),
|
||||
args: Box::new(args_m),
|
||||
callee: Rc::new(callee_m),
|
||||
args: Rc::new(args_m),
|
||||
},
|
||||
p,
|
||||
)
|
||||
}
|
||||
|
||||
BoundKind::Again { args } => {
|
||||
let args_m = self.visit(Rc::new((**args).clone()));
|
||||
let args_m = self.visit(args.clone());
|
||||
if let Some(lambda_id) = self.lambda_stack.last() {
|
||||
self.recursive_identities.insert(lambda_id.clone());
|
||||
is_recursive = true;
|
||||
}
|
||||
(
|
||||
BoundKind::Again {
|
||||
args: Box::new(args_m),
|
||||
args: Rc::new(args_m),
|
||||
},
|
||||
Purity::Impure,
|
||||
)
|
||||
@@ -244,9 +244,9 @@ impl<'a> Analyzer<'a> {
|
||||
} => {
|
||||
let mut analyzed_inputs = Vec::with_capacity(inputs.len());
|
||||
for input in inputs {
|
||||
analyzed_inputs.push(self.visit(Rc::new(input.clone())));
|
||||
analyzed_inputs.push(Rc::new(self.visit(input.clone())));
|
||||
}
|
||||
let a_lambda = Box::new(self.visit(Rc::new((**lambda).clone())));
|
||||
let a_lambda = Rc::new(self.visit(lambda.clone()));
|
||||
(
|
||||
BoundKind::Pipe {
|
||||
inputs: analyzed_inputs,
|
||||
@@ -261,9 +261,9 @@ impl<'a> Analyzer<'a> {
|
||||
let mut new_exprs = Vec::with_capacity(exprs.len());
|
||||
let mut p = Purity::Pure;
|
||||
for e in exprs {
|
||||
let em = self.visit(Rc::new(e.clone()));
|
||||
let em = self.visit(e.clone());
|
||||
p = p.min(em.ty.purity);
|
||||
new_exprs.push(em);
|
||||
new_exprs.push(Rc::new(em));
|
||||
}
|
||||
(BoundKind::Block { exprs: new_exprs }, p)
|
||||
}
|
||||
@@ -272,9 +272,9 @@ impl<'a> Analyzer<'a> {
|
||||
let mut new_elements = Vec::with_capacity(elements.len());
|
||||
let mut p = Purity::Pure;
|
||||
for e in elements {
|
||||
let em = self.visit(Rc::new(e.clone()));
|
||||
let em = self.visit(e.clone());
|
||||
p = p.min(em.ty.purity);
|
||||
new_elements.push(em);
|
||||
new_elements.push(Rc::new(em));
|
||||
}
|
||||
(
|
||||
BoundKind::Tuple {
|
||||
@@ -288,9 +288,9 @@ impl<'a> Analyzer<'a> {
|
||||
let mut new_values = Vec::with_capacity(values.len());
|
||||
let mut p = Purity::Pure;
|
||||
for v in values {
|
||||
let vm = self.visit(Rc::new(v.clone()));
|
||||
let vm = self.visit(v.clone());
|
||||
p = p.min(vm.ty.purity);
|
||||
new_values.push(vm);
|
||||
new_values.push(Rc::new(vm));
|
||||
}
|
||||
(
|
||||
BoundKind::Record {
|
||||
@@ -305,11 +305,11 @@ impl<'a> Analyzer<'a> {
|
||||
original_call,
|
||||
bound_expanded,
|
||||
} => {
|
||||
let expanded_m = self.visit(Rc::new((**bound_expanded).clone()));
|
||||
let expanded_m = self.visit(bound_expanded.clone());
|
||||
(
|
||||
BoundKind::Expansion {
|
||||
original_call: original_call.clone(),
|
||||
bound_expanded: Box::new(expanded_m.clone()),
|
||||
bound_expanded: Rc::new(expanded_m.clone()),
|
||||
},
|
||||
expanded_m.ty.purity,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user