Refactor: Use root_purity instead of global_purity

This commit refactors the purity analysis from using a
`HashMap<GlobalIdx, Purity>` to a `Vec<Purity>` indexed by
`GlobalIdx.0`.

This change simplifies the data structure and makes purity lookups more
efficient. The `Binder`'s `globals` field has also been removed as it
was not being used.
This commit is contained in:
Michael Schimmel
2026-03-12 16:57:06 +01:00
parent dcb7685d29
commit bf86c76bb6
8 changed files with 123 additions and 131 deletions
+13 -12
View File
@@ -1,11 +1,10 @@
use crate::ast::compiler::bound_nodes::{
Address, AnalyzedNode, BoundKind, GlobalAnalyzedRegistry, GlobalIdx, UpvalueIdx,
Address, AnalyzedNode, BoundKind, GlobalAnalyzedRegistry, UpvalueIdx,
};
use crate::ast::nodes::Node;
use crate::ast::types::{Purity, Value};
use crate::ast::vm::Closure;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use super::folder::Folder;
@@ -17,7 +16,7 @@ pub struct Optimizer {
pub enabled: bool,
max_passes: usize,
pub globals: Option<Rc<RefCell<Vec<Value>>>>,
pub global_purity: Option<Rc<RefCell<HashMap<GlobalIdx, Purity>>>>,
pub root_purity: Option<Rc<RefCell<Vec<Purity>>>>,
pub lambda_registry: Option<Rc<RefCell<GlobalAnalyzedRegistry>>>,
}
@@ -27,7 +26,7 @@ impl Optimizer {
enabled,
max_passes: 5,
globals: None,
global_purity: None,
root_purity: None,
lambda_registry: None,
}
}
@@ -37,8 +36,8 @@ impl Optimizer {
self
}
pub fn with_purity(mut self, purity: Rc<RefCell<HashMap<GlobalIdx, Purity>>>) -> Self {
self.global_purity = Some(purity);
pub fn with_purity(mut self, purity: Rc<RefCell<Vec<Purity>>>) -> Self {
self.root_purity = Some(purity);
self
}
@@ -79,7 +78,7 @@ impl Optimizer {
path: &mut PathTracker,
base_sub: Option<SubstitutionMap>,
) -> Option<Rc<AnalyzedNode>> {
let inliner = Inliner::new(&self.globals, &self.global_purity);
let inliner = Inliner::new(&self.globals, &self.root_purity);
let mut inner_sub = base_sub.unwrap_or_else(|| sub.new_for_inlining());
if inliner.prepare_beta_reduction(params, arg_nodes, body, &mut inner_sub).is_some() {
@@ -105,7 +104,7 @@ impl Optimizer {
) -> Rc<AnalyzedNode> {
let node = &*node_rc;
let folder = Folder::new(&self.globals);
let inliner = Inliner::new(&self.globals, &self.global_purity);
let inliner = Inliner::new(&self.globals, &self.root_purity);
let (new_kind, metrics) = match &node.kind {
BoundKind::Get { addr, name } => {
@@ -215,11 +214,13 @@ impl Optimizer {
if let Address::Global(global_index) = addr
&& value_opt.ty.purity > Purity::Impure
&& let Some(purity_rc) = &self.global_purity
&& let Some(purity_rc) = &self.root_purity
{
purity_rc
.borrow_mut()
.insert(*global_index, value_opt.ty.purity);
let mut pr = purity_rc.borrow_mut();
let idx = global_index.0 as usize;
if idx < pr.len() {
pr[idx] = value_opt.ty.purity;
}
}
if Rc::ptr_eq(&value_opt, value) {
+7 -7
View File
@@ -1,8 +1,8 @@
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, GlobalIdx, LocalSlot};
use crate::ast::compiler::bound_nodes::{Address, AnalyzedNode, BoundKind, LocalSlot};
use crate::ast::types::{Purity, Value};
use crate::ast::vm::Closure;
use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;
use std::rc::Rc;
use super::substitution_map::SubstitutionMap;
@@ -10,17 +10,17 @@ use super::utils::UsageInfo;
pub struct Inliner<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
pub global_purity: &'a Option<Rc<RefCell<HashMap<GlobalIdx, Purity>>>>,
pub root_purity: &'a Option<Rc<RefCell<Vec<Purity>>>>,
}
impl<'a> Inliner<'a> {
pub fn new(
globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
global_purity: &'a Option<Rc<RefCell<HashMap<GlobalIdx, Purity>>>>,
root_purity: &'a Option<Rc<RefCell<Vec<Purity>>>>,
) -> Self {
Self {
globals,
global_purity,
root_purity,
}
}
@@ -48,10 +48,10 @@ impl<'a> Inliner<'a> {
}
if let Address::Global(idx) = addr {
if let Some(purity_rc) = &self.global_purity {
if let Some(purity_rc) = &self.root_purity {
let purity = purity_rc
.borrow()
.get(&idx)
.get(idx.0 as usize)
.cloned()
.unwrap_or(Purity::Impure);
return purity >= Purity::Pure;