Skip to content

[embedded] Fix class_method devirtualizer to consider specialized VTables #69678

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 1 commit into from
Nov 7, 2023

Conversation

kubamracek
Copy link
Contributor

The performance devirtualizer can introduce / re-introduce generic functions in embedded Swift mode, after MandatoryPerformanceOptimizations has made sure everything is specialized. See the attached test case (actually it's just an existing test but built with -Osize), which currently triggers an IRGen crash due to a generic function being referenced:

Assertion failed: (!f->isGeneric()), function addLazyFunction, file GenDecl.cpp, line 1567.
...
 #8 0x000000010079ace4 swift::irgen::IRGenerator::addLazyFunction(swift::SILFunction*)
 #9 0x000000010079d118 swift::irgen::IRGenModule::getAddrOfSILFunction(swift::SILFunction*, swift::ForDefinition_t, bool, bool)
#10 0x00000001008ffaac (anonymous namespace)::IRGenSILFunction::visitFunctionRefBaseInst(swift::FunctionRefBaseInst*)
#11 0x00000001008e98c0 (anonymous namespace)::IRGenSILFunction::visitSILBasicBlock(swift::SILBasicBlock*)
#12 0x00000001008e1fa8 (anonymous namespace)::IRGenSILFunction::emitSILFunction()
#13 0x00000001008df6b0 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*)
#14 0x0000000100798ba0 swift::irgen::IRGenerator::emitGlobalTopLevel(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>> const&)

Turns out that the Devirtualizer pass turns this

  %2 = alloc_ref $GenericFooableClass<Int>
  %4 = end_init_let_ref %2 : $GenericFooableClass<Int>
  %7 = class_method %4 : $GenericFooableClass<Int>, #GenericFooableClass.foo : <T> (GenericFooableClass<T>) -> () -> (), $@convention(method) (@guaranteed GenericFooableClass<Int>) -> ()
  %8 = apply %7(%4) : $@convention(method) (@guaranteed GenericFooableClass<Int>) -> ()

into:

  %2 = alloc_ref $GenericFooableClass<Int>
  %4 = end_init_let_ref %2 : $GenericFooableClass<Int>
  // function_ref GenericFooableClass.foo()
  %7 = function_ref @$s4main19GenericFooableClassC3fooyyF : $@convention(method) <τ_0_0> (@guaranteed GenericFooableClass<τ_0_0>) -> ()
  %8 = apply %7<Int>(%4) : $@convention(method) <τ_0_0> (@guaranteed GenericFooableClass<τ_0_0>) -> ()

But it should instead call the specialization (from the specialized VTable), not the generic function (from the regular VTable).

@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek kubamracek added the embedded Embedded Swift label Nov 6, 2023
@kubamracek
Copy link
Contributor Author

@swift-ci please test

@kubamracek
Copy link
Contributor Author

@swift-ci please test Windows platform

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm!

@kubamracek
Copy link
Contributor Author

@swift-ci please test Windows platform

@kubamracek kubamracek merged commit 71612e6 into swiftlang:main Nov 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
embedded Embedded Swift
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants