Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

(optimization): Using equality analysis to improve match optimization#9893

Open
eytan-starkware wants to merge 1 commit intomainstarkware-libs/cairo:mainfrom
eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimizationstarkware-libs/cairo:eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimizationCopy head branch name to clipboard
Open

(optimization): Using equality analysis to improve match optimization#9893
eytan-starkware wants to merge 1 commit intomainstarkware-libs/cairo:mainfrom
eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimizationstarkware-libs/cairo:eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimizationCopy head branch name to clipboard

Conversation

@eytan-starkware
Copy link
Copy Markdown
Contributor

@eytan-starkware eytan-starkware commented May 6, 2026

Summary

Extends the match optimizer to fold matches whose variant is already known via equality analysis, not just when a local EnumConstruct statement is present in the same block. When equality analysis can determine the variant of a matched variable at a block's exit, the match is replaced with a direct goto to the corresponding arm, provided the matched value is droppable and the payload variable is copyable and in scope.

To support this:

  • DefSites now stores Option<DefLocation> instead of DefLocation, replacing the UNRESOLVED sentinel with None for variables in unreachable blocks. The assertion that all slots are resolved is removed.
  • EqualityState gains a mutable get_enum_construct method that performs path compression via find.
  • MatchOptimizerContext now holds equality analysis results, dominator information, and def-site information, and exposes get_enum_variant and is_visible_at_block_end helpers.
  • try_get_fix_info is generalized to accept a variant, an inner VarUsage, an optional (stmt_idx, output_var) for construct removal, and a fix_block, decoupling it from the StatementEnumConstruct type.
  • FixInfo replaces statement_location + remove_enum_construct + n_same_block_statement with fix_block and enum_construct_removal: Option<(usize, usize)>, which is None for equality-anchored folds.
  • optimize_matches now takes a db parameter, threaded through from OptimizationPhase.

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 previous match optimizer only eliminated a match when the matched enum value was constructed by a StatementEnumConstruct immediately upstream. Cases where the variant was already known through equality analysis (e.g., after a prior match on the same variable) were not folded, leaving redundant multi-arm matches in the lowered IR.


What was the behavior or documentation before?

A match on a variable whose variant was already known via equality analysis was left as-is, producing multiple blocks and redundant match arms in the lowered output.


What is the behavior or documentation after?

When equality analysis knows the variant of a matched variable at a block's exit and the payload is visible and copyable, the match is folded into a direct goto to the correct arm at that point, collapsing the redundant blocks. Test data reflects the reduced block count in the optimized output.


Related issue or discussion (if any)

None.


Additional context

The regression test unresolved_assert_fires is removed because the UNRESOLVED sentinel and its associated assertion no longer exist; unreachable-block variables are now represented as None in DefSites.

@reviewable-StarkWare
Copy link
Copy Markdown

This change is Reviewable

@cursor
Copy link
Copy Markdown

cursor Bot commented May 6, 2026

PR Summary

Medium Risk
Changes match-folding logic and related analyses, which can alter lowered IR shape and downstream codegen/gas usage; correctness depends on new visibility/copy/drop gates and dominator/def-site accuracy.

Overview
Extends match optimization to fold match_enum even when there is no local EnumConstruct, by using equality analysis to detect a known enum variant at a block’s exit and rewriting the block end to a direct Goto to the corresponding arm (with extra guards for droppable/copyable payloads and dominance/def-site visibility).

Refactors def-site analysis to return Option<DefLocation> (removing the UNRESOLVED sentinel/assert and treating unreachable definitions as None), and exposes a path-compressing EqualityState::get_enum_construct to support the new fold.

Threads db into optimize_matches, restructures FixInfo to support both construct-anchored and equality-anchored folds, updates golden match/equality test data accordingly, and adjusts a Starknet ABI dispatcher gas expectation.

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

@eytan-starkware eytan-starkware changed the base branch from eytan_graphite/_feat_added_an_optimization_dump_for_each_phase_under_a_special_log_target to graphite-base/9893 May 6, 2026 10:31
@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimization branch from eec8a84 to 87fb9bb Compare May 6, 2026 10:31
@eytan-starkware eytan-starkware changed the base branch from graphite-base/9893 to main May 6, 2026 10:32
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.

Reviewed by Cursor Bugbot for commit 87fb9bb. Configure here.

self.fixes.push(fix_info);
return info;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Equality fold corrupts candidate on unreachable failure path

Medium Severity

Inside try_get_fix_info, std::mem::take empties candidate.arm_demands[arm_idx] before the only return None check. If try_get_fix_info returns None, the equality-fold call site falls through to Some(candidate) without discarding the corrupted candidate. This differs from the construct-anchored call site which sets info.candidate = None on failure. Currently the None path is unreachable from the equality fold (because additional_remappings is always empty), but the asymmetry is fragile — adding any new early-return to try_get_fix_info would silently corrupt the candidate's arm demand, causing incorrect demand propagation for downstream construct-anchored folds targeting the same arm.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 87fb9bb. Configure here.

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimization branch from 87fb9bb to 5f6644d Compare May 6, 2026 10:51
@ilyalesokhin-starkware
Copy link
Copy Markdown
Contributor

crates/cairo-lang-lowering/src/optimizations/match_optimizer.rs line 352 at r2 (raw file):

    /// the construct in the same block, used for an integrity assertion. `None` for
    /// equality-anchored folds (no local construct to remove).
    enum_construct_removal: Option<(usize, usize)>,

define a struct

Code quote:

(usize, usize)

@ilyalesokhin-starkware
Copy link
Copy Markdown
Contributor

crates/cairo-lang-lowering/src/optimizations/match_optimizer.rs line 421 at r2 (raw file):

        var: VariableId,
    ) -> Option<(ConcreteVariant<'db>, VariableId)> {
        self.equalities[block_id.0].as_mut().and_then(|s| s.get_enum_construct(var))

Suggestion:

 self.equalities[block_id.0].as_mut()?.get_enum_construct(var)

@ilyalesokhin-starkware
Copy link
Copy Markdown
Contributor

crates/cairo-lang-lowering/src/optimizations/match_optimizer.rs line 596 at r2 (raw file):

                if let Some((variant, payload_var)) =
                    self.get_enum_variant(block_id, candidate.match_variable)
                    && self.is_visible_at_block_end(payload_var, block_id)

how can candidate.match_variable be an enum that was constructed by payload_var, without payload_var being visable at the end of the block?

Code quote:

                    self.get_enum_variant(block_id, candidate.match_variable)
                    && self.is_visible_at_block_end(payload_var, block_id)

@eytan-starkware eytan-starkware force-pushed the eytan_graphite/_optimization_using_equality_analysis_to_improve_match_optimization branch from 5f6644d to 35a7393 Compare May 7, 2026 07:29
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.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.