Skip to content

(feat): add array support to equality analysis#9802

Merged
eytan-starkware merged 1 commit intomainfrom
eytan_graphite/_feat_add_array_support_to_equality_analysis
Apr 6, 2026
Merged

(feat): add array support to equality analysis#9802
eytan-starkware merged 1 commit intomainfrom
eytan_graphite/_feat_add_array_support_to_equality_analysis

Conversation

@eytan-starkware
Copy link
Copy Markdown
Contributor

@eytan-starkware eytan-starkware commented Mar 30, 2026

Summary

Extends the equality analysis to track array operations (array_new, array_append, array_pop_front, array_snapshot_pop_front, array_snapshot_pop_back) by reusing the existing struct hashcons infrastructure. Arrays are now represented as (TypeId, Vec<VariableId>) mappings, and pop operations act as destructures that can recover original elements and remaining arrays.


Type of change

Please check one:

  • Bug fix (fixes incorrect behavior)
  • New feature
  • Performance improvement
  • Documentation change with concrete technical impact
  • Style, wording, formatting, or typo-only change

Why is this change needed?

The equality analysis previously only tracked snapshot/desnap, box/unbox, and struct construct relationships. Array operations were not analyzed, meaning the system couldn't detect when array elements could be recovered from pop operations or when two arrays with equivalent elements should be considered equivalent. This limited optimization opportunities for array-heavy code.


What was the behavior or documentation before?

The equality analysis ignored array operations entirely. Calls to array_new, array_append, and array pop functions were treated as opaque operations with no tracked relationships between inputs and outputs.


What is the behavior or documentation after?

The analysis now:

  • Tracks array_new() as creating an empty array construct
  • Tracks array_append(arr, elem) as extending the array's element list
  • Handles array_pop_front by recovering the first element (as boxed) and remaining array
  • Handles array_snapshot_pop_front and array_snapshot_pop_back by properly managing snapshot/box relationships
  • Detects when two arrays with identical element sequences are equivalent

Related issue or discussion (if any)

None specified.


Additional context

The implementation cleverly reuses the existing struct hashcons infrastructure since both structs and arrays map (TypeId, Vec<VariableId>). The analysis correctly handles the complex snapshot and boxing relationships that occur during array pop operations, ensuring that unboxing popped elements yields the correct snapshot types rather than falsely equating snapshot and non-snapshot values.


Note

Medium Risk
Updates core dataflow/equality logic to model array operations via hashcons and match-arm transfers, which could affect downstream optimizations that rely on these equivalences. Scope is contained to the equality analysis and its tests but changes touch control-flow transfer behavior and extern call interpretation.

Overview
Adds array awareness to EqualityAnalysis by reusing the existing struct hashcons to record array_new/array_append construct chains and by interpreting array_pop_front/array_snapshot_pop_front/array_snapshot_pop_back extern matches as destructures that relate the popped (boxed) element and remaining array (including snapshot/box wrappers).

Updates the analysis API to require a Database handle for resolving corelib extern IDs, and revises the file-based tests to inline trait calls into extern array calls and adds multiple new test cases covering construct tracking, pop element recovery, snapshot pop chains, and None-arm empty-array handling.

Reviewed by Cursor Bugbot for commit 718ee31. Bugbot is set up for automated code reviews on this repo. Configure here.

@reviewable-StarkWare
Copy link
Copy Markdown

This change is Reviewable

Copy link
Copy Markdown
Contributor Author

eytan-starkware commented Mar 30, 2026

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feat_add_array_support_to_equality_analysis branch from bd180d8 to 1f639eb Compare March 31, 2026 12:52
@eytan-starkware eytan-starkware marked this pull request as ready for review March 31, 2026 12:52
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread crates/cairo-lang-lowering/src/analysis/equality_analysis.rs
Copy link
Copy Markdown
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eytan-starkware resolved 1 discussion.
Reviewable status: 0 of 3 files reviewed, all discussions resolved (waiting on orizi and TomerStarkware).

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feat_add_array_support_to_equality_analysis branch from 1f639eb to 960b5dd Compare March 31, 2026 18:55
Copy link
Copy Markdown
Collaborator

@TomerStarkware TomerStarkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TomerStarkware reviewed all commit messages and made 1 comment.
Reviewable status: 0 of 3 files reviewed, 1 unresolved discussion (waiting on eytan-starkware and orizi).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 382 at r3 (raw file):

        if id == self.array_pop_front || id == self.array_pop_front_consume {
            // Some arm: var_ids = [remaining_arr, boxed_elem]
            if arm.var_ids.len() == 2 {

Use arm_selector to distinguish the arms

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feat_add_array_support_to_equality_analysis branch from 960b5dd to a34743e Compare April 5, 2026 09:37
Copy link
Copy Markdown
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eytan-starkware made 1 comment.
Reviewable status: 0 of 3 files reviewed, 1 unresolved discussion (waiting on orizi and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 382 at r3 (raw file):

Previously, TomerStarkware wrote…

Use arm_selector to distinguish the arms

Done.

Copy link
Copy Markdown
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@orizi reviewed 1 file and all commit messages, and made 1 comment.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 788 at r4 (raw file):

                    let ty = self.lowered.variables[call_stmt.outputs[0]].ty;
                    info.set_struct_construct(ty, vec![], call_stmt.outputs[0]);
                } else if id == self.array_append {

how about cases of:

arr.append(3);
let mut span = arr.span();
let x = *span.pop_back();

x is 3 - but since we knew nothing about arr - we didn't propagate through it.

this possibly means that we still want a somewhat different rep for arrays - WDYT?

Copy link
Copy Markdown
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@orizi made 1 comment.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 788 at r4 (raw file):

Previously, orizi wrote…

how about cases of:

arr.append(3);
let mut span = arr.span();
let x = *span.pop_back();

x is 3 - but since we knew nothing about arr - we didn't propagate through it.

this possibly means that we still want a somewhat different rep for arrays - WDYT?

(and in any case add a test with a TODO for this sort of case)

Copy link
Copy Markdown
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eytan-starkware made 1 comment.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on orizi and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 788 at r4 (raw file):

Previously, orizi wrote…

(and in any case add a test with a TODO for this sort of case)

There is a todo to deal with this (maybe on the next PRs) and . I have a concept of Unknown vars I introduce in https://reviewable.io/reviews/starkware-libs/cairo/9804. Array specifically will be somewhat limited as we don't know the len, so I might add support a bit later for this specific case. Would be better to discuss on that PR

Copy link
Copy Markdown
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@orizi made 1 comment.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on eytan-starkware and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 788 at r4 (raw file):

Previously, eytan-starkware wrote…

There is a todo to deal with this (maybe on the next PRs) and . I have a concept of Unknown vars I introduce in https://reviewable.io/reviews/starkware-libs/cairo/9804. Array specifically will be somewhat limited as we don't know the len, so I might add support a bit later for this specific case. Would be better to discuss on that PR

my claim is that array is very different from structs - since the "unknown var" is a subspan of the array of unknown size. and in struct it is very well known.

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_feat_add_array_support_to_equality_analysis branch from a34743e to 718ee31 Compare April 6, 2026 11:40
Copy link
Copy Markdown
Contributor Author

@eytan-starkware eytan-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eytan-starkware made 1 comment.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on orizi and TomerStarkware).


crates/cairo-lang-lowering/src/analysis/equality_analysis.rs line 788 at r4 (raw file):

Previously, orizi wrote…

my claim is that array is very different from structs - since the "unknown var" is a subspan of the array of unknown size. and in struct it is very well known.

I understand that. Added a test with a todo.

Copy link
Copy Markdown
Collaborator

@orizi orizi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@orizi reviewed 2 files and all commit messages, and resolved 1 discussion.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on TomerStarkware).

Copy link
Copy Markdown
Collaborator

@TomerStarkware TomerStarkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@TomerStarkware reviewed all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on eytan-starkware).

@eytan-starkware eytan-starkware added this pull request to the merge queue Apr 6, 2026
Merged via the queue into main with commit f652dc4 Apr 6, 2026
54 checks passed
@orizi orizi deleted the eytan_graphite/_feat_add_array_support_to_equality_analysis branch April 23, 2026 11:39
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.

4 participants