Skip to main content

Crate pass_lang

Crate pass_lang 

Source
Expand description

§pass_lang

A pass manager: an ordered pipeline of optimization and transform passes, and the plugin seam capability crates register their passes into.

A compiler improves and lowers a program by running a series of passes over it — constant folding, dead-code elimination, inlining, lowering steps. The pieces those passes share — running in a defined order, repeating until the program stops changing, stopping cleanly when one fails, recording what happened — are the same regardless of what the passes rewrite. pass-lang is that shared machinery, and nothing more.

It is generic over the unit a pass rewrites. A Pass<T> transforms a T — an intermediate representation, a single function, a whole module, an abstract syntax tree, or a struct bundling an IR with the diagnostics and analysis a pass needs. A PassManager<T> holds passes in registration order and runs them; it is the scheduler and never touches the unit itself. The crate owns no IR and wires no first-party dependency — the same shape as LLVM’s pass manager (generic over Module / Function / Loop) or Cranelift’s pass pipeline.

§Running a pipeline

Implement Pass for each transform, register the transforms with PassManager::add, and run them — once with PassManager::run, or repeatedly to a fixpoint with PassManager::run_to_fixpoint. Each run returns a Report of what every pass did.

§Example

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))
    }
}

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

let mut unit = vec![0, 1, 0, 2, 3];
let report = pm.run(&mut unit).expect("the pass does not fail");

assert_eq!(unit, vec![1, 2, 3]);
assert_eq!(report.changes(), 1);

§Features

  • std (default) — the standard library; without it the crate is #![no_std] and needs only alloc.
  • serde — derives serde::Serialize for the reporting types (Outcome, PassRun, Report) so a run report can be logged or inspected.

§Stability

The public surface is frozen and stable as of 1.0.0: it follows Semantic Versioning, with no breaking changes before 2.0. The full surface and the SemVer promise are catalogued in docs/API.md.

Structs§

PassError
The error a Pass returns when it cannot complete its work.
PassManager
An ordered pipeline of passes over a unit of type T.
PassRun
One entry in a Report: a pass that ran and what it did.
Report
A record of one PassManager run.

Enums§

Outcome
Whether a pass changed the unit on a given run.

Traits§

Pass
A single transform or analysis over a unit of type T — the plugin seam.