mod fold;
mod dce;
mod propagate;
mod gvn;
mod licm;
mod closed_form;
mod ctfe;
mod deforest;
mod abstract_interp;
pub mod supercompile;
pub mod effects;
pub mod bta;
pub mod partial_eval;
use std::collections::HashMap;
use crate::arena::Arena;
use crate::ast::stmt::{Expr, Stmt};
use crate::intern::{Interner, Symbol};
pub fn optimize_for_projection<'a>(
stmts: Vec<Stmt<'a>>,
expr_arena: &'a Arena<Expr<'a>>,
stmt_arena: &'a Arena<Stmt<'a>>,
interner: &mut Interner,
) -> Vec<Stmt<'a>> {
let bta_cache = bta::analyze_with_sccs(&stmts, interner);
let mut current = stmts;
let mut variant_count: HashMap<Symbol, usize> = HashMap::new();
for _ in 0..16 {
let folded = fold::fold_stmts(current, expr_arena, stmt_arena, interner);
let propagated = propagate::propagate_stmts(folded, expr_arena, stmt_arena, interner);
let (specialized, changes) = partial_eval::specialize_stmts_with_state(
propagated, expr_arena, stmt_arena, interner, &mut variant_count,
Some(&bta_cache),
);
current = specialized;
if changes == 0 {
break;
}
}
let ctfe_d = ctfe::ctfe_stmts(current, expr_arena, stmt_arena, interner);
fold::fold_stmts(ctfe_d, expr_arena, stmt_arena, interner)
}
pub fn optimize_program<'a>(
stmts: Vec<Stmt<'a>>,
expr_arena: &'a Arena<Expr<'a>>,
stmt_arena: &'a Arena<Stmt<'a>>,
interner: &mut Interner,
) -> Vec<Stmt<'a>> {
let bta_cache = bta::analyze_with_sccs(&stmts, interner);
let mut current = stmts;
let mut variant_count: HashMap<Symbol, usize> = HashMap::new();
for _ in 0..16 {
let folded = fold::fold_stmts(current, expr_arena, stmt_arena, interner);
let propagated = propagate::propagate_stmts(folded, expr_arena, stmt_arena, interner);
let (specialized, changes) = partial_eval::specialize_stmts_with_state(
propagated, expr_arena, stmt_arena, interner, &mut variant_count,
Some(&bta_cache),
);
current = specialized;
if changes == 0 {
break;
}
}
let ctfe_d = ctfe::ctfe_stmts(current, expr_arena, stmt_arena, interner);
let refolded = fold::fold_stmts(ctfe_d, expr_arena, stmt_arena, interner);
let cse_d = gvn::cse_stmts(refolded, expr_arena, stmt_arena, interner);
let licm_d = licm::licm_stmts(cse_d, stmt_arena, interner);
let closed = closed_form::closed_form_stmts(licm_d, expr_arena, stmt_arena, interner);
let deforested = deforest::deforest_stmts(closed, expr_arena, stmt_arena, interner);
let range_analyzed = abstract_interp::abstract_interp_stmts(deforested, expr_arena, stmt_arena);
let dce_d = dce::eliminate_dead_code(range_analyzed, stmt_arena, expr_arena);
supercompile::supercompile_stmts(dce_d, expr_arena, stmt_arena, interner)
}