Skip to content

refactor(interpreter): unify callable roots - #724

Open
zhenrongliew wants to merge 2 commits into
dl/interp-frame-compositionfrom
dl/interp-callable-root
Open

refactor(interpreter): unify callable roots#724
zhenrongliew wants to merge 2 commits into
dl/interp-frame-compositionfrom
dl/interp-callable-root

Conversation

@zhenrongliew

@zhenrongliew zhenrongliew commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #723. Unify callable entry across forward and backward interpreters: separate body discovery from forward argument binding, route backward roots through linkers, honor FunctionTarget.stage.

Three problems:

  1. Callable-body discovery was entangled with forward argument binding.

FunctionEntry was parameterised on the engine and took a value product:

pub trait FunctionEntry<I: Interp>: Dialect {
    fn function_entry(&self, args: Product<I::Value>, interp: &mut I)
        -> Result<CallableBody<I::Value>, I::Error>;
}

This made it inherently incompatible with backward interpreters, the signature permitted argument-sensitive body selection — so a backward interpreters could not discover structure without fabricating a dummy Product<LiveSet>.

  1. The backward interpreters bypassed the linker
    analyze(stage, body: impl Into<Body>) skipped symbol/specialization resolution, target-stage selection, and linker policy entirely.

Both backward engines now take Lk = SameStageLinker, hold a linker field, and expose with_linker, matching the concrete and forward engines:

pub fn analyze(&mut self, stage: CompileStage, callee: Callee) -> Result<BodyScope, E>

Every engine root now shares one validated prefix, through a single resolve_callable:

caller stage + Callee
    -> Linker::resolve
    -> FunctionTarget
    -> FunctionEntry dispatch at FunctionTarget.stage
    -> CallableBody
    -> engine-specific boundary initialization
  1. Dense Liveness graph analysis silently did nothing
    DirectBodyBlocks in returned Vec::new() for DiGraph/UnGraph, so the solver ran to completion over an empty owner set and reported success having done no work.
    Tests now assert that both demand and classic liveness reject graph bodies explicitly.

…ody to be function definition. Actual body terminology remains unchanged for CFG, Block, graphs, Function.body, Lambda.body, and CallableBody.body.
… functionality

- Updated the `FunctionEntry` trait to remove the argument passing, simplifying callable statement handling.
- Refactored the `function_cfg` method to streamline the retrieval of function bodies and their corresponding CFGs.
- Enhanced the `analyze_classic_liveness` and `analyze_dense_toy` functions to utilize the new `Callee` structure for function calls.
- Adjusted test cases to align with the new callable structure, ensuring consistent analysis across various scenarios.
- Removed unnecessary complexity in the interpreter's handling of function entries and CFG retrieval, promoting cleaner code and better maintainability.
- Deleted redundant code and improved documentation for clarity on the new structure and its implications for future development.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant