-
Notifications
You must be signed in to change notification settings - Fork 793
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
Conversation
src/passes/AbstractTypeRefining.cpp
Outdated
// 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// nontrivial. Instead, avoid changing subtype relationships entirely. | |
// nontrivial. Instead, avoid changing subtype relationships entirely: | |
// leave that for Unsubtyping. |
src/passes/AbstractTypeRefining.cpp
Outdated
// 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// 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(); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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.
ff51aee
to
f422c68
Compare
Note to self: review tests for staleness. |
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.