Skip to content

perf(repsel): admit conditional return-shape producers (#7170 R2) - #8007

Merged
proggeramlug merged 2 commits into
mainfrom
perf/7170-conditional-return-shapes
Aug 13, 2026
Merged

perf(repsel): admit conditional return-shape producers (#7170 R2)#8007
proggeramlug merged 2 commits into
mainfrom
perf/7170-conditional-return-shapes

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Admit returned conditional expressions as Ptr<Shape> producers when every recursively reachable result arm is a fresh allocation of the same admissible class. This is the first producer-side R2 increment identified by #7170's post-R1 measurement.

Changes

  • Recursively flatten conditional result arms in producer_return_class, while keeping conditions and unsupported expression forms out of the proof.
  • Fail closed for non-fresh arms, disagreeing classes, logical operators, and conditional arms that return locals; direct return local retains its existing Phase 3b proof.
  • Preserve the optimization report's honest returned expression operand syntax bucket while marking only proven conditional result allocations as served.
  • Add positive, nested, disagreeing-class, non-fresh-arm, and report-classification regression coverage.

The proof continues to use the existing class-admission, containment, module-barrier, and caller-slot/rooting machinery; this introduces no new pointer position.

Related issue

Refs #7170 (R2 producer increment; the broader issue remains open for logical expressions and cross-module/method consumers).

Test plan

  • cargo check --profile perry-dev -p perry-codegen
  • cargo test --profile perry-dev -p perry-codegen --lib ptr_shape_returns --no-fail-fast (31 passed)
  • cargo test --profile perry-dev -p perry-codegen --lib opt_report_tests --no-fail-fast (21 passed)
  • cargo fmt -p perry-codegen -- --check
  • git diff --check
  • cargo build --release clean
  • Full affected-crate/workspace suite passes
  • Added or updated a #[test] in the affected crate
  • Docs update not required: no CLI, stdlib, or runtime API changed
  • Platform UI build not applicable

The focused test executables were linked against the installed Windows LLVM package with only its available x86/AArch64 targets enabled locally; that temporary manifest adjustment was restored and is not part of this PR.

Screenshots / output

Not applicable; compiler analysis/report behavior only.

Checklist

  • I have NOT bumped the workspace version or edited CLAUDE.md / CHANGELOG.md
  • My commits follow the repository's commit-prefix convention
  • I've read CONTRIBUTING.md and agree to the Code of Conduct

Summary by CodeRabbit

  • New Features

    • Improved return-shape inference for functions and wrapped closure producers using conditional expressions.
    • Conditional branches can now support optimized fixed-offset field access when every branch returns a fresh instance of the same class.
  • Bug Fixes

    • Prevented invalid optimization facts for non-fresh, mismatched, nested-local, or conditional-condition allocations.
  • Tests

    • Added coverage for nested conditionals, caller propagation, and rejected return-shape cases.
    • Updated optimization reports to accurately identify served allocation sources.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Conditional return-shape inference now supports recursively nested conditional arms when each arm creates a fresh allocation of the same class. Optimization reports mark only proven return-shape sources as served.

Changes

Conditional return-shape support

Layer / File(s) Summary
Collect conditional return sources
crates/perry-codegen/src/collectors/ptr_shape_returns.rs, crates/perry-codegen/src/collectors/ptr_shape_returns_tests.rs
The analysis recursively collects fresh allocations from conditional arms. It accepts matching classes and rejects non-fresh or mismatched branches.
Classify return-shape allocation sites
crates/perry-codegen/src/collectors/ptr_shape_report.rs
Return scanning marks direct returns and qualifying conditional result arms as is_return_shape_source. Conditions, constructor arguments, and unrelated nested operands remain ordinary operands.
Validate optimization-report accounting
crates/perry-codegen/src/collectors/ptr_shape_opt_report_tests.rs, changelog.d/8007-conditional-return-shapes.md
Tests verify served conditional result arms and unserved conditions. The changelog documents the supported and rejected cases.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to 72c5c

The change broadens conditional return-shape optimization only for proven fresh allocations of one admissible class, with focused regression coverage and validation checks documented. No actionable merge-blocking risk remains beyond normal review follow-up.

Sequence Diagram(s)

sequenceDiagram
  participant ReturnExpression
  participant producer_return_class
  participant collect_fresh_return_sources
  participant CallerSeeding
  ReturnExpression->>producer_return_class: provide conditional return expression
  producer_return_class->>collect_fresh_return_sources: collect fresh branch sources
  collect_fresh_return_sources->>producer_return_class: return fresh sources
  producer_return_class->>CallerSeeding: seed caller from one agreed class
Loading

Possibly related PRs

  • PerryTS/perry#7037: Introduced the return-shape reporting machinery extended by this PR.
  • PerryTS/perry#7107: Introduced the return-shape analysis extended for conditional branches here.
  • PerryTS/perry#7176: Modified the same reporting and test paths for consumed return-shape allocations.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: admitting conditional return-shape producers.
Description check ✅ Passed The description includes all required sections, explains the implementation and scope, and documents focused tests plus remaining unchecked validation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/7170-conditional-return-shapes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
crates/perry-codegen/src/collectors/ptr_shape_returns_tests.rs (1)

344-348: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover a seeded local in a conditional arm.

Expr::LocalGet(999) fails because it has no seeded class. The test also passes if recursive traversal incorrectly treats a conditional arm as a direct return. Add a local initialized with new C() and return it from one conditional arm. Assert that no fact is produced.

Based on learnings: Phase 3b permits LocalGet only for a bare return local; a conditional arm must remain rejected.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry-codegen/src/collectors/ptr_shape_returns_tests.rs` around lines
344 - 348, Update conditional_return_with_any_non_fresh_arm_gets_no_fact to seed
a local with new_c(), return that local from one conditional arm, and keep the
other arm fresh/non-fresh as needed to exercise the rejection. Assert that no
fact is produced, ensuring LocalGet is accepted only for a bare return local and
not when nested in a conditional arm.

Source: Learnings

crates/perry-codegen/src/collectors/ptr_shape_opt_report_tests.rs (1)

817-839: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Identify the condition allocation in the assertion.

The served and unserved counts do not prove that the condition stays unserved. A defect that serves the condition and skips one result arm still passes this test. Give the three allocations distinct report identities and assert that the condition row is unserved and both result-arm rows are served.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry-codegen/src/collectors/ptr_shape_opt_report_tests.rs` around
lines 817 - 839, Update the conditional allocation test around run_as_producer
to give the condition and both result arms distinct report identities, then
assert each identity’s tier explicitly: the condition allocation must be
unserved, while both then_expr and else_expr allocations must be served. Replace
the aggregate served/unserved count assertions so a swapped allocation
classification cannot pass.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/perry-codegen/src/collectors/ptr_shape_opt_report_tests.rs`:
- Around line 817-839: Update the conditional allocation test around
run_as_producer to give the condition and both result arms distinct report
identities, then assert each identity’s tier explicitly: the condition
allocation must be unserved, while both then_expr and else_expr allocations must
be served. Replace the aggregate served/unserved count assertions so a swapped
allocation classification cannot pass.

In `@crates/perry-codegen/src/collectors/ptr_shape_returns_tests.rs`:
- Around line 344-348: Update
conditional_return_with_any_non_fresh_arm_gets_no_fact to seed a local with
new_c(), return that local from one conditional arm, and keep the other arm
fresh/non-fresh as needed to exercise the rejection. Assert that no fact is
produced, ensuring LocalGet is accepted only for a bare return local and not
when nested in a conditional arm.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a37df1ff-4bc8-41da-ac21-5322ee6ca8ea

📥 Commits

Reviewing files that changed from the base of the PR and between 843ef62 and 72c5c98.

📒 Files selected for processing (5)
  • changelog.d/8007-conditional-return-shapes.md
  • crates/perry-codegen/src/collectors/ptr_shape_opt_report_tests.rs
  • crates/perry-codegen/src/collectors/ptr_shape_report.rs
  • crates/perry-codegen/src/collectors/ptr_shape_returns.rs
  • crates/perry-codegen/src/collectors/ptr_shape_returns_tests.rs

@proggeramlug
proggeramlug merged commit d059140 into main Aug 13, 2026
1 of 18 checks passed
@proggeramlug
proggeramlug deleted the perf/7170-conditional-return-shapes branch August 13, 2026 02:46
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