Refactor optimizer utilities

Removes unused `flatten_tuple` function from optimizer utilities. The
functionality was moved to the `Folder` struct, making it more
contextually appropriate. This change streamlines the utility module and
improves code organization.
This commit is contained in:
Michael Schimmel
2026-02-25 21:26:12 +01:00
parent cf87bbeac5
commit 81c805f07e
6 changed files with 456 additions and 460 deletions
+26 -8
View File
@@ -1,6 +1,4 @@
use crate::ast::compiler::bound_nodes::{ use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx, UpvalueIdx};
Address, AnalyzedNode, BoundKind, GlobalIdx, UpvalueIdx,
};
use crate::ast::nodes::Node; use crate::ast::nodes::Node;
use crate::ast::types::{Purity, Value}; use crate::ast::types::{Purity, Value};
use crate::ast::vm::Closure; use crate::ast::vm::Closure;
@@ -8,9 +6,9 @@ use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use super::substitution_map::SubstitutionMap;
use super::folder::Folder; use super::folder::Folder;
use super::inliner::Inliner; use super::inliner::Inliner;
use super::substitution_map::SubstitutionMap;
use super::utils::{PathTracker, UsageInfo}; use super::utils::{PathTracker, UsageInfo};
pub struct Optimizer { pub struct Optimizer {
@@ -177,6 +175,9 @@ impl Optimizer {
let args = self.visit_node(*args, sub, path); let args = self.visit_node(*args, sub, path);
if self.enabled { if self.enabled {
let mut arg_nodes = Vec::new();
self.flatten_tuple(args.clone(), &mut arg_nodes);
if let BoundKind::Lambda { if let BoundKind::Lambda {
params, params,
body, body,
@@ -192,7 +193,7 @@ impl Optimizer {
path.inlining_depth += 1; path.inlining_depth += 1;
let mut inner_sub = SubstitutionMap::new(); let mut inner_sub = SubstitutionMap::new();
let collapsed = if inliner let collapsed = if inliner
.prepare_beta_reduction(params, &args, body, &mut inner_sub) .prepare_beta_reduction(params, &arg_nodes, body, &mut inner_sub)
.is_some() .is_some()
{ {
Some(self.visit_node((**body).clone(), &mut inner_sub, path)) Some(self.visit_node((**body).clone(), &mut inner_sub, path))
@@ -231,7 +232,7 @@ impl Optimizer {
path.inlining_stack.insert(*idx); path.inlining_stack.insert(*idx);
path.inlining_depth += 1; path.inlining_depth += 1;
let collapsed = if inliner let collapsed = if inliner
.prepare_beta_reduction(params, &args, body, &mut inner_sub) .prepare_beta_reduction(params, &arg_nodes, body, &mut inner_sub)
.is_some() .is_some()
{ {
Some(self.visit_node((**body).clone(), &mut inner_sub, path)) Some(self.visit_node((**body).clone(), &mut inner_sub, path))
@@ -273,7 +274,7 @@ impl Optimizer {
let collapsed = if inliner let collapsed = if inliner
.prepare_beta_reduction( .prepare_beta_reduction(
&closure.parameter_node, &closure.parameter_node,
&args, &arg_nodes,
&inlined_body, &inlined_body,
&mut closure_sub, &mut closure_sub,
) )
@@ -291,7 +292,7 @@ impl Optimizer {
} }
} }
if let Some(folded) = folder.try_fold_pure(&callee, &args) { if let Some(folded) = folder.try_fold_pure(&callee, &arg_nodes) {
return folded; return folded;
} }
} }
@@ -533,4 +534,21 @@ impl Optimizer {
ty: metrics, ty: metrics,
} }
} }
fn flatten_tuple(&self, node: AnalyzedNode, into: &mut Vec<AnalyzedNode>) {
match node.kind {
BoundKind::Tuple { elements } => {
for el in elements {
self.flatten_tuple(el, into);
}
}
BoundKind::Record { fields } => {
for (_, v) in fields {
self.flatten_tuple(v, into);
}
}
BoundKind::Nop => {}
_ => into.push(node),
}
}
} }
+8 -9
View File
@@ -4,8 +4,6 @@ use crate::ast::types::{Purity, StaticType, Value};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use super::utils::flatten_tuple;
pub struct Folder<'a> { pub struct Folder<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>, pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
} }
@@ -50,17 +48,19 @@ impl<'a> Folder<'a> {
} }
} }
pub fn try_fold_pure(&self, callee: &AnalyzedNode, args: &AnalyzedNode) -> Option<AnalyzedNode> { pub fn try_fold_pure(
if callee.ty.purity < Purity::Pure || args.ty.purity < Purity::Pure { &self,
callee: &AnalyzedNode,
arg_nodes: &[AnalyzedNode],
) -> Option<AnalyzedNode> {
if callee.ty.purity < Purity::Pure {
return None; return None;
} }
let mut arg_nodes = Vec::new();
flatten_tuple(args.clone(), &mut arg_nodes);
let mut arg_values = Vec::with_capacity(arg_nodes.len()); let mut arg_values = Vec::with_capacity(arg_nodes.len());
for node in arg_nodes { for node in arg_nodes {
if let BoundKind::Constant(val) = node.kind { if let BoundKind::Constant(val) = &node.kind {
arg_values.push(val); arg_values.push(val.clone());
} else { } else {
return None; return None;
} }
@@ -80,4 +80,3 @@ impl<'a> Folder<'a> {
Some(self.make_constant_node(result, callee)) Some(self.make_constant_node(result, callee))
} }
} }
+3 -6
View File
@@ -6,7 +6,7 @@ use std::collections::{HashMap, HashSet};
use std::rc::Rc; use std::rc::Rc;
use super::substitution_map::SubstitutionMap; use super::substitution_map::SubstitutionMap;
use super::utils::{flatten_tuple, UsageInfo}; use super::utils::UsageInfo;
pub struct Inliner<'a> { pub struct Inliner<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>, pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
@@ -64,18 +64,15 @@ impl<'a> Inliner<'a> {
pub fn prepare_beta_reduction( pub fn prepare_beta_reduction(
&self, &self,
params: &AnalyzedNode, params: &AnalyzedNode,
args: &AnalyzedNode, arg_vals: &[AnalyzedNode],
body: &AnalyzedNode, body: &AnalyzedNode,
sub: &mut SubstitutionMap, sub: &mut SubstitutionMap,
) -> Option<()> { ) -> Option<()> {
let mut body_usage = UsageInfo::default(); let mut body_usage = UsageInfo::default();
body_usage.collect(body); body_usage.collect(body);
let mut arg_vals = Vec::new();
flatten_tuple(args.clone(), &mut arg_vals);
let mut slot_index = 0; let mut slot_index = 0;
self.map_params_to_args(params, &arg_vals, &mut slot_index, sub, &body_usage); self.map_params_to_args(params, arg_vals, &mut slot_index, sub, &body_usage);
if slot_index != arg_vals.len() { if slot_index != arg_vals.len() {
return None; return None;
+1 -1
View File
@@ -8,4 +8,4 @@ pub use engine::Optimizer;
pub use folder::Folder; pub use folder::Folder;
pub use inliner::Inliner; pub use inliner::Inliner;
pub use substitution_map::SubstitutionMap; pub use substitution_map::SubstitutionMap;
pub use utils::{PathTracker, UsageInfo, flatten_tuple}; pub use utils::{PathTracker, UsageInfo};
@@ -1,6 +1,6 @@
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot, UpvalueIdx}; use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot, UpvalueIdx};
use crate::ast::nodes::Node; use crate::ast::nodes::Node;
use crate::ast::types::{Value}; use crate::ast::types::Value;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
#[derive(Default)] #[derive(Default)]
-18
View File
@@ -168,21 +168,3 @@ impl UsageInfo {
} }
} }
} }
// --- Structural Helpers ---
pub fn flatten_tuple(node: AnalyzedNode, into: &mut Vec<AnalyzedNode>) {
match node.kind {
BoundKind::Tuple { elements } => {
for el in elements {
flatten_tuple(el, into);
}
}
BoundKind::Record { fields } => {
for (_, v) in fields {
flatten_tuple(v, into);
}
}
BoundKind::Nop => {}
_ => into.push(node),
}
}