E-Graphs + Equality Saturation: Optimizer Design Playbook

2026-03-08 · software

E-Graphs + Equality Saturation: Optimizer Design Playbook

Date: 2026-03-08
Category: knowledge
Domain: software / compiler engineering / optimization systems

Why this matters

Traditional optimizers are usually rewrite pipelines:

This creates the classic phase-ordering problem: good rewrites can block later better rewrites depending on sequence.

Equality saturation (EqSat) changes the shape of the problem:

If you build query planners, ML graph optimizers, symbolic simplifiers, or codegen superoptimizers, this is often a better architecture than hand-tuned pass ordering.


Core mental model

1) E-graph = compact set of equivalent expressions

An e-graph stores expressions by equivalence class:

With congruence closure, if children are equivalent, parent expressions can become equivalent too.

2) EqSat loop

  1. Start from initial expression/program.
  2. Repeatedly apply rewrite rules to add equal forms into the e-graph.
  3. Stop by budget/saturation limit.
  4. Run extraction: choose best representative from root e-class under objective.

So optimization is no longer “which rewrite first?” but “what search space + what objective?”


Why modern EqSat became practical

The egg work (POPL 2021) pushed EqSat from theory into an engineering-friendly toolkit:

This matters because real optimizers need more than purely syntactic rewrites; they need semantic side conditions and analysis-aware pruning.


Where this works well (with evidence)

A) Tensor graph superoptimization (Tensat)

EqSat was used to optimize DL tensor graphs and reported:

Takeaway: EqSat is not only elegant; it can win on both quality and compile-time in graph-optimization regimes.

B) DSP vectorization (Diospyros)

Diospyros pipeline uses:

Takeaway: EqSat is viable for low-level performance codegen, not just algebra simplification toys.

C) Datalog + EqSat unification (egglog)

egglog shows a useful direction when your optimizer needs:

Takeaway: for long-running or continuously updated optimization workloads, fixpoint-style systems can reduce ad-hoc glue code.


Practical architecture blueprint

1) IR boundary first

Before rewrites, decide the optimization IR:

Bad IR design sinks EqSat projects faster than bad rewrite rules.

2) Rule system with explicit safety contracts

Each rule should carry:

Do not put semantic assumptions only in comments.

3) Saturation controls

Use hard budgets from day one:

EqSat can explode combinatorially; budget controls are product features, not temporary hacks.

4) Extraction objective

Use a multi-term cost function, e.g.:

[ J = w_1 \cdot \text{latency} + w_2 \cdot \text{memory} + w_3 \cdot \text{code size} + w_4 \cdot \text{risk penalty} ]

Where risk penalty can encode numerical stability loss, portability loss, or backend-specific hazards.

5) Explainability artifacts

Keep optimization explainable:

Without this, debugging objective drift becomes painful.


Rollout strategy (minimal regret)

Phase 1 — Shadow mode

Run EqSat offline against production-like workloads:

Phase 2 — Guarded canary

Enable EqSat for low-risk segments only:

Phase 3 — Objective tuning loop

Tune weights and rule sets with explicit KPI targets:

Phase 4 — Expand + specialize

Split rule packs by domain:

One giant global rule pack is usually slower and harder to govern.


Common failure modes


10-point implementation checklist


One-line takeaway

EqSat turns optimization from brittle pass-order engineering into search-space + objective engineering—usually a better abstraction for complex optimizers.


References