srdatalog.ir.core.passes¶
Pass kinds, registration decorators, and driver.
A pass is a transformation on the IR. Two flavors:
Lowering — matches an op of one dialect, produces ops of another
(or of a target dialect). Each Lowering carries the op
class it matches, an apply callable that performs the
transformation, declared consumes / produces dialect
names for dependency validation, and a name for diagnostics.
Rewrite — matches an op, produces ops of the same dialect. Used for internal optimizations like the IIR-sorted-array count-as-product or hint-narrowing rules.
Per the project memory note (feedback_decorator_registries.md),
registration uses Triton-style decorators rather than imperative
register_X(OpClass, fn) calls or class-based dispatch:
from srdatalog.ir.core import lowering, rewrite, verifier
from srdatalog.ir.dialects.relation.sorted_array import DIALECT
@lowering(DIALECT, mir.ExecutePipeline,
consumes=('mir',), produces=('iir.cf', 'relation.sorted_array'))
def _lower_execute_pipeline(ep, ctx):
...
@rewrite(DIALECT, SaPrefCoop)
def _hint_introduction(op, ctx):
...
@verifier(DIALECT)
def _verify_sorted_array(prog):
return [] # list of VerificationError
The decorators mutate dialect.lowerings / dialect.rewrites /
dialect.verifier in place. Decoration is the only registration
path — there is no imperative API exposed.
The PassDriver walks compiler.dialects to validate dependencies
(every Lowering’s consumes must be in the registered dialect set;
otherwise raise PassDependencyError). Actual op-level dispatch is
left to callers for now (production code calls lowering functions
directly); the registry exists so external consumers can introspect
“who lowers what” and so future stages can add a tree-walking dispatcher.
See docs/ir_lowering_semantics.md, section 21.
Module Contents¶
Classes¶
A lowering rule from one dialect to another. |
|
Runs registered rewrites and lowerings. |
|
A rewrite rule within a single dialect. |
Functions¶
Data¶
API¶
- class srdatalog.ir.core.passes.Lowering[source]¶
A lowering rule from one dialect to another.
Fields: matches — the Op subclass this rule matches (e.g. MirColumnJoin). apply — callable taking (op, context) and returning the replacement IR (single op or list of ops; type depends on the target dialect’s contract). name — short identifier for diagnostics and pass tracing. consumes — dialect names whose ops this lowering reads. Used by PassDriver to validate that every required dialect is registered before the lowering runs. produces — dialect names whose ops this lowering emits. Used by PassDriver for topological ordering of multi-pass pipelines (a pass that produces dialect D must run before any pass that consumes D).
- apply: collections.abc.Callable[[Any, Any], Any]¶
None
- exception srdatalog.ir.core.passes.PassDependencyError(pass_name: str, missing_dialect: str, in_dialect: str)[source]¶
Bases:
ExceptionA registered pass declared
consumes=(D, ...)but dialect D is not registered with the Compiler. Raised by PassDriver.run before any pass executes.The recommended posture (per docs/stage3a_execution_plan.md §9) is loud failure over silent fallback: a pipeline opting out of a dialect’s passes does so by not registering those passes, not by not registering the dialect.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- class srdatalog.ir.core.passes.PassDriver(compiler: srdatalog.ir.core.dialect.Compiler)[source]¶
Runs registered rewrites and lowerings.
Today the driver does dependency validation (catches “pass P consumes dialect D not enabled”) and verifier dispatch. Op-level dispatch (a tree walker that finds the registered Lowering for each op kind and applies it) lands when the first production consumer needs it; until then, callers invoke lowering functions directly and the registry serves as introspection metadata.
The driver does not know about specific dialects. New dialects participate by being registered; the driver consults the registry.
Initialization
- run(prog: Any) Any[source]¶
Run all registered passes against
prog. Returns the (possibly transformed) program.Validates pass dependencies first; raises PassDependencyError on unmet consumes. Then runs verifiers and returns prog unchanged (op-level dispatch is caller-driven for now; see class docstring).
- class srdatalog.ir.core.passes.Rewrite[source]¶
A rewrite rule within a single dialect.
Same shape as Lowering, but conventionally produces ops of the same dialect as
matches.consumes/producestypically equal the dialect’s own name; PassDriver still uses them for dependency validation if a rewrite reads ops from a sibling dialect.- apply: collections.abc.Callable[[Any, Any], Any]¶
None
- srdatalog.ir.core.passes.__all__¶
[‘Lowering’, ‘PassDependencyError’, ‘PassDriver’, ‘Rewrite’, ‘lowering’, ‘rewrite’, ‘verifier’]
- srdatalog.ir.core.passes.lowering(dialect: srdatalog.ir.core.dialect.Dialect, matches: type, *, consumes: tuple[str, ...] = (), produces: tuple[str, ...] = (), name: str = '') collections.abc.Callable[[collections.abc.Callable[[Any, Any], Any]], collections.abc.Callable[[Any, Any], Any]][source]¶
Decorator: wrap fn as a Lowering and register on dialect.lowerings.
Usage:
@lowering(MY_DIALECT, mir.SomeOp, consumes=('mir',), produces=('iir.cf', 'relation.sorted_array')) def _lower_some_op(op, ctx): return ...Returns the original function (so other decorators can stack).
- srdatalog.ir.core.passes.rewrite(dialect: srdatalog.ir.core.dialect.Dialect, matches: type, *, consumes: tuple[str, ...] = (), produces: tuple[str, ...] = (), name: str = '') collections.abc.Callable[[collections.abc.Callable[[Any, Any], Any]], collections.abc.Callable[[Any, Any], Any]][source]¶
Decorator: wrap fn as a Rewrite and register on dialect.rewrites.
Usage:
@rewrite(MY_DIALECT, SomeOp) def _hint_introduction(op, ctx): return ...
- srdatalog.ir.core.passes.verifier(dialect: srdatalog.ir.core.dialect.Dialect) collections.abc.Callable[[collections.abc.Callable[[Any], Any]], collections.abc.Callable[[Any], Any]][source]¶
Decorator: register fn as the dialect’s verifier.
Usage:
@verifier(MY_DIALECT) def _verify(prog): return [] # list of VerificationError, [] = OKRaises ValueError if the dialect already has a verifier registered.