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:
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user