From 04f2203900cbbf92b5ca682698c96ede8d76b861 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Wed, 25 Feb 2026 20:35:12 +0100 Subject: [PATCH] Refactor: Move utils to separate module Moves `PathTracker` and `UsageInfo` to the `utils` module to improve code organization. --- src/ast/compiler/optimizer/engine.rs | 33 +--- src/ast/compiler/optimizer/inliner.rs | 4 +- src/ast/compiler/optimizer/mod.rs | 3 +- .../compiler/optimizer/substitution_map.rs | 142 +-------------- src/ast/compiler/optimizer/utils.rs | 172 +++++++++++++++++- 5 files changed, 179 insertions(+), 175 deletions(-) diff --git a/src/ast/compiler/optimizer/engine.rs b/src/ast/compiler/optimizer/engine.rs index 16adbfb..af8dcd7 100644 --- a/src/ast/compiler/optimizer/engine.rs +++ b/src/ast/compiler/optimizer/engine.rs @@ -5,12 +5,13 @@ use crate::ast::nodes::Node; use crate::ast::types::{Purity, Value}; use crate::ast::vm::Closure; use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::rc::Rc; -use super::substitution_map::{SubstitutionMap, UsageInfo}; +use super::substitution_map::SubstitutionMap; use super::folder::Folder; use super::inliner::Inliner; +use super::utils::{PathTracker, UsageInfo}; pub struct Optimizer { pub enabled: bool, @@ -20,34 +21,6 @@ pub struct Optimizer { pub lambda_registry: Option>>>, } -struct PathTracker { - inlining_depth: usize, - inlining_stack: HashSet, - identity_stack: HashSet, -} - -impl PathTracker { - fn new() -> Self { - Self { - inlining_depth: 0, - inlining_stack: HashSet::new(), - identity_stack: HashSet::new(), - } - } - - fn enter_lambda(&mut self, identity: &crate::ast::types::Identity) -> bool { - if self.identity_stack.contains(identity) { - return false; - } - self.identity_stack.insert(identity.clone()); - true - } - - fn exit_lambda(&mut self, identity: &crate::ast::types::Identity) { - self.identity_stack.remove(identity); - } -} - impl Optimizer { pub fn new(enabled: bool) -> Self { Self { diff --git a/src/ast/compiler/optimizer/inliner.rs b/src/ast/compiler/optimizer/inliner.rs index 16280ac..5fde093 100644 --- a/src/ast/compiler/optimizer/inliner.rs +++ b/src/ast/compiler/optimizer/inliner.rs @@ -5,8 +5,8 @@ use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::rc::Rc; -use super::substitution_map::{SubstitutionMap, UsageInfo}; -use super::utils::flatten_tuple; +use super::substitution_map::SubstitutionMap; +use super::utils::{flatten_tuple, UsageInfo}; pub struct Inliner<'a> { pub globals: &'a Option>>>, diff --git a/src/ast/compiler/optimizer/mod.rs b/src/ast/compiler/optimizer/mod.rs index a793532..44f8b9f 100644 --- a/src/ast/compiler/optimizer/mod.rs +++ b/src/ast/compiler/optimizer/mod.rs @@ -7,4 +7,5 @@ pub mod utils; pub use engine::Optimizer; pub use folder::Folder; pub use inliner::Inliner; -pub use substitution_map::{SubstitutionMap, UsageInfo}; +pub use substitution_map::SubstitutionMap; +pub use utils::{PathTracker, UsageInfo, flatten_tuple}; diff --git a/src/ast/compiler/optimizer/substitution_map.rs b/src/ast/compiler/optimizer/substitution_map.rs index 298b0e6..36cc520 100644 --- a/src/ast/compiler/optimizer/substitution_map.rs +++ b/src/ast/compiler/optimizer/substitution_map.rs @@ -1,148 +1,8 @@ use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot, UpvalueIdx}; use crate::ast::nodes::Node; -use crate::ast::types::{Identity, Value}; -use crate::ast::vm::Closure; +use crate::ast::types::{Value}; use std::collections::{HashMap, HashSet}; -#[derive(Default)] -pub struct UsageInfo { - pub used: HashSet
, - pub assigned: HashSet
, - pub used_identities: HashSet, -} - -impl UsageInfo { - pub fn is_assigned(&self, addr: &Address) -> bool { - self.assigned.contains(addr) - } - - pub fn is_used(&self, addr: &Address) -> bool { - self.used.contains(addr) - } - - pub fn collect(&mut self, node: &AnalyzedNode) { - match &node.kind { - BoundKind::Destructure { pattern, value } => { - self.collect_pattern(pattern); - self.collect(value); - } - BoundKind::Constant(v) => { - if let Value::Object(obj) = v - && let Some(closure) = obj.as_any().downcast_ref::() - { - self.used_identities - .insert(closure.function_node.identity.clone()); - self.collect(&closure.function_node); - } - } - BoundKind::Get { addr, .. } => { - self.used.insert(*addr); - } - BoundKind::Set { addr, value } => { - self.assigned.insert(*addr); - self.collect(value); - } - BoundKind::Lambda { - params, - body, - upvalues, - .. - } => { - self.used_identities.insert(node.identity.clone()); - - let mut inner_info = UsageInfo::default(); - inner_info.collect(params); - inner_info.collect(body); - - // Propagate globals and identities - for addr in &inner_info.used { - if let Address::Global(_) = addr { - self.used.insert(*addr); - } - } - for addr in &inner_info.assigned { - if let Address::Global(_) = addr { - self.assigned.insert(*addr); - } - } - self.used_identities.extend(inner_info.used_identities); - - // Map used upvalues to parent scope - for addr in &inner_info.used { - if let Address::Upvalue(idx) = addr - && let Some(parent_addr) = upvalues.get(idx.0 as usize) - { - self.used.insert(*parent_addr); - } - } - // Map assigned upvalues to parent scope - for addr in &inner_info.assigned { - if let Address::Upvalue(idx) = addr - && let Some(parent_addr) = upvalues.get(idx.0 as usize) - { - self.assigned.insert(*parent_addr); - } - } - } - BoundKind::Block { exprs } => { - for e in exprs { - self.collect(e); - } - } - BoundKind::If { - cond, - then_br, - else_br, - } => { - self.collect(cond); - self.collect(then_br); - if let Some(e) = else_br { - self.collect(e); - } - } - BoundKind::Call { callee, args } => { - self.collect(callee); - self.collect(args); - } - BoundKind::Tuple { elements } => { - for e in elements { - self.collect(e); - } - } - BoundKind::Record { fields } => { - for (k, v) in fields { - self.collect(k); - self.collect(v); - } - } - BoundKind::Define { value, .. } => { - self.collect(value); - } - BoundKind::Expansion { bound_expanded, .. } => { - self.collect(bound_expanded); - } - _ => {} - } - } - - pub fn collect_pattern(&mut self, node: &AnalyzedNode) { - match &node.kind { - BoundKind::Define { addr, .. } => { - self.assigned.insert(*addr); - } - BoundKind::Set { addr, .. } => { - self.assigned.insert(*addr); - } - BoundKind::Tuple { elements } => { - for el in elements { - self.collect_pattern(el); - } - } - _ => {} - } - } -} - #[derive(Default)] pub struct SubstitutionMap { pub values: HashMap, diff --git a/src/ast/compiler/optimizer/utils.rs b/src/ast/compiler/optimizer/utils.rs index d04b5e4..e431e52 100644 --- a/src/ast/compiler/optimizer/utils.rs +++ b/src/ast/compiler/optimizer/utils.rs @@ -1,5 +1,175 @@ -use crate::ast::compiler::bound_nodes::{AnalyzedNode, BoundKind}; +use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx}; +use crate::ast::types::{Identity, Value}; +use crate::ast::vm::Closure; +use std::collections::HashSet; +// --- PathTracker --- +#[derive(Default)] +pub struct PathTracker { + pub inlining_depth: usize, + pub inlining_stack: HashSet, + pub identity_stack: HashSet, +} + +impl PathTracker { + pub fn new() -> Self { + Self::default() + } + + pub fn enter_lambda(&mut self, identity: &Identity) -> bool { + if self.identity_stack.contains(identity) { + return false; + } + self.identity_stack.insert(identity.clone()); + true + } + + pub fn exit_lambda(&mut self, identity: &Identity) { + self.identity_stack.remove(identity); + } +} + +// --- UsageInfo --- +#[derive(Default)] +pub struct UsageInfo { + pub used: HashSet
, + pub assigned: HashSet
, + pub used_identities: HashSet, +} + +impl UsageInfo { + pub fn is_assigned(&self, addr: &Address) -> bool { + self.assigned.contains(addr) + } + + pub fn is_used(&self, addr: &Address) -> bool { + self.used.contains(addr) + } + + pub fn collect(&mut self, node: &AnalyzedNode) { + match &node.kind { + BoundKind::Destructure { pattern, value } => { + self.collect_pattern(pattern); + self.collect(value); + } + BoundKind::Constant(v) => { + if let Value::Object(obj) = v + && let Some(closure) = obj.as_any().downcast_ref::() + { + self.used_identities + .insert(closure.function_node.identity.clone()); + self.collect(&closure.function_node); + } + } + BoundKind::Get { addr, .. } => { + self.used.insert(*addr); + } + BoundKind::Set { addr, value } => { + self.assigned.insert(*addr); + self.collect(value); + } + BoundKind::Lambda { + params, + body, + upvalues, + .. + } => { + self.used_identities.insert(node.identity.clone()); + + let mut inner_info = UsageInfo::default(); + inner_info.collect(params); + inner_info.collect(body); + + // Propagate globals and identities + for addr in &inner_info.used { + if let Address::Global(_) = addr { + self.used.insert(*addr); + } + } + for addr in &inner_info.assigned { + if let Address::Global(_) = addr { + self.assigned.insert(*addr); + } + } + self.used_identities.extend(inner_info.used_identities); + + // Map used upvalues to parent scope + for addr in &inner_info.used { + if let Address::Upvalue(idx) = addr + && let Some(parent_addr) = upvalues.get(idx.0 as usize) + { + self.used.insert(*parent_addr); + } + } + // Map assigned upvalues to parent scope + for addr in &inner_info.assigned { + if let Address::Upvalue(idx) = addr + && let Some(parent_addr) = upvalues.get(idx.0 as usize) + { + self.assigned.insert(*parent_addr); + } + } + } + BoundKind::Block { exprs } => { + for e in exprs { + self.collect(e); + } + } + BoundKind::If { + cond, + then_br, + else_br, + } => { + self.collect(cond); + self.collect(then_br); + if let Some(e) = else_br { + self.collect(e); + } + } + BoundKind::Call { callee, args } => { + self.collect(callee); + self.collect(args); + } + BoundKind::Tuple { elements } => { + for e in elements { + self.collect(e); + } + } + BoundKind::Record { fields } => { + for (k, v) in fields { + self.collect(k); + self.collect(v); + } + } + BoundKind::Define { value, .. } => { + self.collect(value); + } + BoundKind::Expansion { bound_expanded, .. } => { + self.collect(bound_expanded); + } + _ => {} + } + } + + pub fn collect_pattern(&mut self, node: &AnalyzedNode) { + match &node.kind { + BoundKind::Define { addr, .. } => { + self.assigned.insert(*addr); + } + BoundKind::Set { addr, .. } => { + self.assigned.insert(*addr); + } + BoundKind::Tuple { elements } => { + for el in elements { + self.collect_pattern(el); + } + } + _ => {} + } + } +} + +// --- Structural Helpers --- pub fn flatten_tuple(node: AnalyzedNode, into: &mut Vec) { match node.kind { BoundKind::Tuple { elements } => {