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

[opt] Devirtualize package class methods more aggressively. #73540

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

zoecarver
Copy link
Collaborator

Package class methods cannot be overridden outside of the module, so all callees should be statically knowable, and we can usually devirtualize them.

@@ -91,7 +91,8 @@ static bool isEffectivelyFinalMethod(FullApplySite applySite, CanType classType,

auto *cmi = cast<MethodInst>(applySite.getCallee());

if (!calleesAreStaticallyKnowable(applySite.getModule(), cmi->getMember()))
if (!calleesAreStaticallyKnowable(applySite.getModule(), cmi->getMember()) &&
(!cd || cd->getFormalAccess() != AccessLevel::Package))
Copy link
Contributor

Choose a reason for hiding this comment

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

I think getEffectiveAccess() check is more accurate in SIL optimizer. Also don't we want the same for public access? It also can't be subclassed or overriden outside of defining module.

Copy link
Member

Choose a reason for hiding this comment

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

Why is package access special (i.e different to internal access)?

If the code following this check depends on module.isWholeModule() for internal and public access (see implementation calleesAreStaticallyKnowable) in one of the calls (which I assume might be the case), then why is this not the case for package access level?

@@ -193,6 +193,22 @@ package func getPkgModuleKlassMemberTBD() -> Int {
return ModuleTBD.pkgModuleKlassMember()
}

// CHECK-LABEL: sil package @$s4Main23callsPackageClassMethod1cSi6Module0cD0C_tF : $@convention(thin) (@guaranteed PackageClass) -> Int
// CHECK-NOT: class_method
Copy link
Contributor

Choose a reason for hiding this comment

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

This file contains tests in non-resilient mode; could you also add cases to package-cmo-resilient-mode.swift?

// CHECK-NOT: apply
// CHECK: return
public func callsPackageClassMethod(c: PackageClass) -> Int {
return c.test()
Copy link
Member

Choose a reason for hiding this comment

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

Why is it okay to remove the virtual method call?

A function that has a PackageClass argument could be receiving a PackageClass or a PackageClassDerived instance?

Copy link
Member

Choose a reason for hiding this comment

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

Did we elimate the method dispatch with a conditional branch on the type? (The speculative devirtualizer does stuff like that)

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.

None yet

3 participants