Introduce Purity enum for optimizer

Refactor the optimizer to use a Purity enum instead of a boolean for
tracking function purity. This allows for a more granular representation
of purity:

- `Impure`: Functions with side effects.
- `SideEffectFree`: Functions without side effects but may not be
  deterministic (e.g., `now()`, `random()`).
- `Pure`: Functions without side effects and are deterministic.

This change enhances the optimizer's ability to perform more aggressive
optimizations by accurately determining function purity.
This commit is contained in:
Michael Schimmel
2026-02-22 08:42:22 +01:00
parent 329b885c4b
commit f35606616b
4 changed files with 86 additions and 60 deletions
+5 -5
View File
@@ -12,7 +12,7 @@ use crate::ast::compiler::bound_nodes::{Address, BoundNode};
use crate::ast::compiler::dumper::Dumper;
use crate::ast::compiler::lambda_collector::LambdaCollector;
use crate::ast::compiler::macros::{MacroEvaluator, MacroExpander, MacroRegistry};
use crate::ast::compiler::optimizer::Optimizer;
use crate::ast::compiler::optimizer::{Optimizer, Purity};
use crate::ast::compiler::specializer::{FunctionRegistry, MonoCache, Specializer};
use crate::ast::compiler::tco::{ExecNode, TCO};
use crate::ast::rtl;
@@ -21,7 +21,7 @@ use crate::ast::rtl::intrinsics;
pub struct Environment {
pub global_names: Rc<RefCell<HashMap<Symbol, u32>>>,
pub global_types: Rc<RefCell<HashMap<u32, StaticType>>>,
pub global_purity: Rc<RefCell<HashMap<u32, bool>>>,
pub global_purity: Rc<RefCell<HashMap<u32, Purity>>>,
pub global_values: Rc<RefCell<Vec<Value>>>,
pub function_registry: Rc<RefCell<HashMap<u32, BoundNode>>>,
pub typed_function_registry: Rc<RefCell<HashMap<u32, TypedNode>>>,
@@ -116,7 +116,7 @@ impl Environment {
&self,
name: &str,
ty: StaticType,
is_pure: bool,
purity_level: Purity,
func: impl Fn(Vec<Value>) -> Value + 'static,
) {
let mut names = self.global_names.borrow_mut();
@@ -127,7 +127,7 @@ impl Environment {
let idx = values.len() as u32;
names.insert(Symbol::from(name), idx);
types.insert(idx, ty);
purity.insert(idx, is_pure);
purity.insert(idx, purity_level);
values.push(Value::Function(Rc::new(func)));
}
@@ -140,7 +140,7 @@ impl Environment {
let idx = values.len() as u32;
names.insert(Symbol::from(name), idx);
types.insert(idx, ty);
purity.insert(idx, true); // Constants are always pure
purity.insert(idx, Purity::Pure); // Constants are always pure
values.push(val);
}