Motivation
In the current implementation of Koopa IR, it is relatively easy to inadvertently violate IR invariants, leading to "broken" IR states that are difficult to diagnose. Common scenarios include:
- Inconsistent Use-Def Chains: Modifying instructions via
kind_mut() without manually synchronizing the corresponding used_by information.
- Structural Desynchronization: Instructions existing in the
Layout (execution order) but missing from the DataFlowGraph (data storage), or vice-versa.
- SSA Violations: Moving instructions such that a value is used before its definition point (dominance violation).
Currently, these issues are often handled silently or trigger obscure panics deep within the codegen or later optimization passes. This makes debugging significantly harder, as the root cause (the pass that broke the IR) is disconnected from the symptoms. As an educational framework, Koopa should empower users to identify exactly when and where their IR became invalid.
Proposal
We propose introducing a Verifier abstraction and a VerifierManager to ensure IR integrity throughout the compilation pipeline.
1. The Verifier Trait
A core trait that allows for both global (Program) and local (Function) level checks. To provide high-quality error messages, Verifiers will be granted access to certain internal fields (via pub(crate) visibility or extension traits).
pub trait Verifier {
/// Returns the human-readable name of the verifier for error reporting.
fn name(&self) -> &str;
/// Performs integrity checks on the entire IR program.
fn verify_program(&self, _program: &Program) {}
/// Performs integrity checks on a specific function.
fn verify_function(&self, _func: Function, _data: &FunctionData) {}
}
2. Built-in Verifiers
Koopa will ship with a set of standard verifiers:
UseDefVerifier: Ensures every Value in the DFG has a perfectly synchronized used_by set.
CfgVerifier: Validates basic block termination and layout-DFG consistency.
DominanceVerifier: (Planned) Validates SSA dominance properties.
3. Verification Management & Pass Integration
To provide maximum flexibility, we propose two ways to run verifiers:
- Explicit Pass Wrapping: Provide
VerifierModulePass<V> and VerifierFunctionPass<V> so verifiers can be treated as standard passes and manually registered at specific points in the PassManager.
- Automatic Verification (The
VerifierManager): A dedicated manager that can be configured to run a suite of verifiers automatically after each optimization pass.
Why a dedicated Manager?
While manual registration works, it is redundant and error-prone for users to re-add a "VerifyPass" after every single optimization. A VerifierManager integrated into the PassManager execution loop allows for a "Verify-Each" mode (similar to LLVM's -verify-each), ensuring that the IR is validated at every step of the transformation.
Benefits
- Fail-Fast Debugging: Catch IR corruption immediately after the problematic pass, rather than during codegen.
- Educational Clarity: Detailed error messages help students understand the subtle invariants of SSA and IR structures.
- Extensibility: Users can easily define and register custom verifiers for their own specific optimization constraints.
Motivation
In the current implementation of Koopa IR, it is relatively easy to inadvertently violate IR invariants, leading to "broken" IR states that are difficult to diagnose. Common scenarios include:
kind_mut()without manually synchronizing the correspondingused_byinformation.Layout(execution order) but missing from theDataFlowGraph(data storage), or vice-versa.Currently, these issues are often handled silently or trigger obscure panics deep within the
codegenor later optimization passes. This makes debugging significantly harder, as the root cause (the pass that broke the IR) is disconnected from the symptoms. As an educational framework, Koopa should empower users to identify exactly when and where their IR became invalid.Proposal
We propose introducing a
Verifierabstraction and aVerifierManagerto ensure IR integrity throughout the compilation pipeline.1. The
VerifierTraitA core trait that allows for both global (Program) and local (Function) level checks. To provide high-quality error messages, Verifiers will be granted access to certain internal fields (via
pub(crate)visibility or extension traits).2. Built-in Verifiers
Koopa will ship with a set of standard verifiers:
UseDefVerifier: Ensures everyValuein the DFG has a perfectly synchronizedused_byset.CfgVerifier: Validates basic block termination and layout-DFG consistency.DominanceVerifier: (Planned) Validates SSA dominance properties.3. Verification Management & Pass Integration
To provide maximum flexibility, we propose two ways to run verifiers:
VerifierModulePass<V>andVerifierFunctionPass<V>so verifiers can be treated as standard passes and manually registered at specific points in thePassManager.VerifierManager): A dedicated manager that can be configured to run a suite of verifiers automatically after each optimization pass.Why a dedicated Manager?
While manual registration works, it is redundant and error-prone for users to re-add a "VerifyPass" after every single optimization. A
VerifierManagerintegrated into thePassManagerexecution loop allows for a "Verify-Each" mode (similar to LLVM's-verify-each), ensuring that the IR is validated at every step of the transformation.Benefits