(feat): Creating forward analysis for the dataflow framework#9584
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c3949ebef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /// Add incoming info and mark target ready if all predecessors have contributed. | ||
| fn add_and_maybe_ready( | ||
| &mut self, | ||
| target: BlockId, | ||
| info: TAnalyzer::Info, | ||
| ready: &mut Vec<BlockId>, | ||
| ) { | ||
| self.incoming[target.0] = Some(info); | ||
| self.predecessor_counts[target.0] -= 1; |
There was a problem hiding this comment.
Merge incoming states at join points
At join points with multiple predecessors, this code overwrites any previously stored incoming state (self.incoming[target.0] = Some(info)) and never calls DataflowAnalyzer::merge, so only the last processed edge contributes to the block entry state. In a branching CFG where two paths converge, the earlier path’s info is silently dropped, producing incorrect analysis results even for acyclic graphs that otherwise fit the “topological order” assumption. The trait contract and module docs explicitly describe merging at convergence points, so this should merge with any existing incoming state (using the appropriate entry StatementLocation) instead of overwriting it.
Useful? React with 👍 / 👎.
024ddbf to
2ad86bb
Compare
1c3949e to
b09d4aa
Compare
b09d4aa to
b2daf3d
Compare
2ad86bb to
32bfb79
Compare
eytan-starkware
left a comment
There was a problem hiding this comment.
@eytan-starkware made 1 comment.
Reviewable status: 0 of 7 files reviewed, 1 unresolved discussion (waiting on @orizi and @TomerStarkware).
| /// Add incoming info and mark target ready if all predecessors have contributed. | ||
| fn add_and_maybe_ready( | ||
| &mut self, | ||
| target: BlockId, | ||
| info: TAnalyzer::Info, | ||
| ready: &mut Vec<BlockId>, | ||
| ) { | ||
| self.incoming[target.0] = Some(info); | ||
| self.predecessor_counts[target.0] -= 1; |
orizi
left a comment
There was a problem hiding this comment.
@orizi reviewed all commit messages and made 1 comment.
Reviewable status: 0 of 7 files reviewed, 2 unresolved discussions (waiting on @eytan-starkware and @TomerStarkware).
Cargo.toml line 149 at r2 (raw file):
sha2 = "0.10.9" sha3 = "0.10.8" smallvec = "1.15.1"
optimize later.

Summary
Added a forward dataflow analysis framework to complement the existing backward analysis. This implementation traverses the control flow graph in topological order (from entry towards exits), processing statements in forward order within each block.
Type of change
Please check one:
Why is this change needed?
The codebase already had a backward dataflow analysis framework, but lacked a forward analysis counterpart. Forward analysis is essential for many compiler optimizations and static analyses that need to follow program execution flow from entry to exit points. This implementation enables writing analyzers that track information as it flows through the program in execution order.
What is the behavior or documentation after?
The PR adds:
ForwardDataflowAnalysisclass that traverses the CFG in topological order#[expect(dead_code)]attributes from the core analysis components that are now usedThe implementation also includes two example analyzers in the test module:
Additional context
This implementation completes the dataflow analysis framework by providing both forward and backward analysis capabilities, which are fundamental building blocks for various compiler optimizations and static analyses.