Skip to content
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

Allow devirt into abstract classes if we saw a non-abstract child #108379

Merged
merged 5 commits into from
Oct 3, 2024

Conversation

MichalStrehovsky
Copy link
Member

We avoid devirtualizing into abstract classes because whole program view might have optimized away the method bodies and devirtualizing them doesn't lead to anything good.

However, if the whole program view had a non-abstract child of the abstract class, whole program can no longer optimize this out and devirtualization should be fine.

Fixes issue encountered in #108153 (comment)

Cc @dotnet/ilc-contrib

We avoid devirtualizing into abstract classes because whole program view might have optimized away the method bodies and devirtualizing them doesn't lead to anything good.

However, if the whole program view had a non-abstract child of this, we can no longer optimize this out and devirtualization should be fine.

Fixes issue encountered in dotnet#108153 (comment)
Copy link
Contributor

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Oct 1, 2024
@MichalStrehovsky
Copy link
Member Author

The failures in outerloop look like this exposed a pre-existing bug, so marking no merge.

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this pull request Oct 1, 2024
This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in dotnet#108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.
MichalStrehovsky added a commit that referenced this pull request Oct 1, 2024
This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in #108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.
@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

MichalStrehovsky added a commit to MichalStrehovsky/runtime that referenced this pull request Oct 2, 2024
This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in dotnet#108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.
@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky
Copy link
Member Author

CI found more places that needed compensation for this new relaxation:

  • We shouldn't allow devirtualizing into constructed abstract classes through unconstructed implementation classes since we try hard to optimize away virtuals on abstract classes. If we're in a situation like in the added test (abstract class is constructed because it has a descendant that overrides the abstract method and we try to devirt a call on a never allocated type into the abstract class, this should be rejected - the test for this was in a wrong spot, with wrong type)
  • Interface methods shouldn't participate in instance method optimization since these methods are callable without a methodtable for the interface (the methodtable can be optimized away despite someone calling the interface method)

@MichalStrehovsky
Copy link
Member Author

/azp run runtime-nativeaot-outerloop

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky MichalStrehovsky merged commit b4c820c into dotnet:main Oct 3, 2024
110 of 116 checks passed
@MichalStrehovsky MichalStrehovsky deleted the abstractdevirt branch October 3, 2024 10:49
sirntar pushed a commit to sirntar/runtime that referenced this pull request Oct 3, 2024
This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in dotnet#108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.
sirntar pushed a commit to sirntar/runtime that referenced this pull request Oct 3, 2024
…tnet#108379)

We avoid devirtualizing into abstract classes because whole program view might have optimized away the method bodies and devirtualizing them doesn't lead to anything good.

However, if the whole program view had a non-abstract child of this, we can no longer optimize this out and devirtualization should be fine.

Fixes issue encountered in dotnet#108153 (comment)
jeffschwMSFT added a commit that referenced this pull request Oct 3, 2024
…108470)

This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in #108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.

Co-authored-by: Jeff Schwartz <jeffschw@microsoft.com>
lambdageek pushed a commit to lambdageek/runtime that referenced this pull request Oct 3, 2024
This code was trying to answer question: "Was this method overriden by something else in a more derived class"? It was walking the base hierarchy in canonical form, but that was leading to methods not resolving at all. The fix is to walk the non-canonical hierarchy and canonicalize after we resolved everything.

I ran into this in dotnet#108379 that unlocked more whole program devirtualization and `StringSearchValuesBase` is in this shape.
lambdageek pushed a commit to lambdageek/runtime that referenced this pull request Oct 3, 2024
…tnet#108379)

We avoid devirtualizing into abstract classes because whole program view might have optimized away the method bodies and devirtualizing them doesn't lead to anything good.

However, if the whole program view had a non-abstract child of this, we can no longer optimize this out and devirtualization should be fine.

Fixes issue encountered in dotnet#108153 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-NativeAOT-coreclr NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants