Skip to content

Do not rewrite supertypes in AbstractTypeRefining #7720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 21, 2025

Conversation

tlively
Copy link
Member

@tlively tlively commented Jul 14, 2025

Keeping descriptor chains valid while rewriting subtyping is
complicated. Make it simpler to optimize descriptor and described types
in a future PR by not rewriting supertypes at all in
AbstractTypeRefining.

To avoid losing optimization power in the default optimization
pipelines, run Unsubtyping after AbstractTypeRefining. This makes -O3
slightly faster when optimizing Sheets calcengine (possibly because
having fewer subtype relationships leads to less work in later
optimizations) and improves code size by 0.1%. The improvements increase
when running -O3 -O3, with a 1.7% code size improvement relative to the
same pipeline before this change.

@tlively tlively requested a review from kripken July 14, 2025 16:54
@tlively tlively marked this pull request as draft July 14, 2025 16:56
// supertype, which is not allowed. We could fix this by walking up the
// supertype chain to find a supertype that is not being rewritten, but
// changing subtype relationships and keep descriptor chains valid is
// nontrivial. Instead, avoid changing subtype relationships entirely.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// nontrivial. Instead, avoid changing subtype relationships entirely.
// nontrivial. Instead, avoid changing subtype relationships entirely:
// leave that for Unsubtyping.

// C. But if we rewrote C's supertype, C would declare itself to be its own
// supertype, which is not allowed. We could fix this by walking up the
// supertype chain to find a supertype that is not being rewritten, but
// changing subtype relationships and keep descriptor chains valid is
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// changing subtype relationships and keep descriptor chains valid is
// changing subtype relationships and keeping descriptor chains valid is

}
return super;
// We do not want to update subtype relationships.
return oldType.getDeclaredSuperType();
Copy link
Member

Choose a reason for hiding this comment

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

This is identical to the function being overridden, so it can be removed. We do not need to declare AbstractTypeRefiningTypeMapper at all, I think.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the function being overridden will rewrite the supertype according to the type mapping.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, TypeMapper overrides GlobalTypeRewriter... I looked too far back, sorry.

Base automatically changed from fix-cast-desc-i31 to main July 15, 2025 20:10
tlively added 2 commits July 17, 2025 18:18
Speed up Unsubtyping by over 2x via algorithmic and other improvements.

The most expensive part of the Unsubtyping analysis is the handling of
casts. For each cast source and destination pair, each type that remains
a subtype of the source and was originally a subtype of the destination
must remain a subtype of the destination for the cast to continue
succeeding.

Previously, Unsubtyping analyzed these cast relationships for all types
as a single unit of work whenever it reached a fixed point from
examining other sources of subtyping constraints. This led to duplicated
work because the subtype, cast source, and cast destination triples
analyzed once would be analyzed again the next time casts were
considered.

Avoid this duplicated cast analysis by incrementally analyzing casts
whenever a new subtyping is discovered. Maintain the invariant that each
new subtyping either joins a subtyping tree rooted at the discovered
subtype into the discovered supertype's tree, or reparents the subtype
below some (possibly indirect) subtype of its old parent. In the former
case, the subtype and all of its descendents are evaluated against all
casts originating from all their new supertypes in the tree they have
joined. In the latter case, they must already have been evaluated
against all casts originating at the old supertype and its ancestors, so
they need only to be evaluated against their new supertypes up to the
old supertype. Once a particular type is evaluated against casts
originating from a particular supertype, that type will never be
evaluated against those casts again.

This algorithmic improvement accounts for most of the speedup. The rest
of the speedup is from doing less work while collecting the initial
subtyping constraints in a parallel function analysis. The old
implementation used an instance of Unsubtyping to collect constraints in
each function, which would end up doing some analysis to find additional
constraints. The new implementation does not do any analysis of
transitively required constraints during the initial parallel function
analysis.
Keeping descriptor chains valid while rewriting subtyping is
complicated. Make it simpler to optimize descriptor and described types
in a future PR by not rewriting supertypes at all in
AbstractTypeRefining.

To avoid losing optimization power in the default optimization
pipelines, run Unsubtyping after AbstractTypeRefining. This makes -O3
slightly faster when optimizing Sheets calcengine (possibly because
having fewer subtype relationships leads to less work in later
optimizations) and improves code size by 0.1%. The improvements increase
when running -O3 -O3, with a 1.7% code size improvement relative to the
same pipeline before this change.
@tlively tlively force-pushed the abstract-type-refining-desc branch from ff51aee to f422c68 Compare July 18, 2025 01:19
@tlively tlively changed the title [DRAFT] Do not rewrite supertypes in AbstractTypeRefining Do not rewrite supertypes in AbstractTypeRefining Jul 18, 2025
@tlively tlively marked this pull request as ready for review July 18, 2025 01:26
@tlively tlively changed the base branch from main to unsubtyping-rewrite July 18, 2025 01:30
@tlively
Copy link
Member Author

tlively commented Jul 18, 2025

Note to self: review tests for staleness.

Base automatically changed from unsubtyping-rewrite to main July 21, 2025 23:46
@tlively tlively merged commit a84b026 into main Jul 21, 2025
16 checks passed
@tlively tlively deleted the abstract-type-refining-desc branch July 21, 2025 23:47
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.

2 participants