pass-lang 1.0.0

Optimization/transform pass manager with a plugin seam.
Documentation

Installation

[dependencies]
pass-lang = "1.0"

Or from the terminal:

cargo add pass-lang

Usage

Implement Pass for each transform, register them in order with PassManager::add, and run the pipeline. Each pass reports whether it changed the unit, so the manager can drive the pipeline to a fixpoint and tell you what happened.

use pass_lang::{Outcome, Pass, PassError, PassManager};

// The unit is whatever a pass rewrites — here, a list of integers.
struct DropZeros;
impl Pass<Vec<i64>> for DropZeros {
    fn name(&self) -> &'static str {
        "drop-zeros"
    }
    fn run(&mut self, unit: &mut Vec<i64>) -> Result<Outcome, PassError> {
        let before = unit.len();
        unit.retain(|&x| x != 0);
        Ok(Outcome::from_changed(unit.len() != before))
    }
}

// Halve every value greater than one.
struct Halve;
impl Pass<Vec<i64>> for Halve {
    fn name(&self) -> &'static str {
        "halve"
    }
    fn run(&mut self, unit: &mut Vec<i64>) -> Result<Outcome, PassError> {
        let mut changed = false;
        for x in unit.iter_mut() {
            if *x > 1 {
                *x /= 2;
                changed = true;
            }
        }
        Ok(Outcome::from_changed(changed))
    }
}

let mut pm = PassManager::new();
pm.add(DropZeros).add(Halve);

let mut unit = vec![0, 8, 0, 4];
let report = pm.run_to_fixpoint(&mut unit, 16).expect("no pass fails");

assert_eq!(unit, vec![1, 1]); // zeros dropped, 8 and 4 halved to 1
assert!(report.converged());

A pass that cannot proceed returns a PassError instead of panicking; the manager stops the pipeline and names the pass that failed. The unit type is anything a pass rewrites — an IR, a function, a module, an AST, or a struct bundling an IR with the diagnostics and analysis a pass needs.

Runnable examples: examples/expr_optimizer.rs (constant folding and algebraic simplification to a fixpoint, with the error path), examples/text_normalizer.rs (the same machinery over a String), and examples/contextual_passes.rs (a unit that bundles code with a diagnostics log, so passes share context without a global).

cargo run --example expr_optimizer
cargo run --example text_normalizer
cargo run --example contextual_passes

Documentation

Contributing

See dev/DIRECTIVES.md for engineering standards and the definition of done. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.