Skip to content

embedded: support class existentials with generic classes #76669

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 14 commits into from
Sep 26, 2024

Conversation

eeckstein
Copy link
Contributor

@eeckstein eeckstein commented Sep 24, 2024

For example:

protocol P: AnyObject {}
class C<T> : P {}

let e: P = C<Int>()

Generic class existentials are supported in embedded swift by specializing witness tables.
This PR enables the very basic generic class existentials. More work needs to be done to e.g. support protocol inheritance, etc.

Also, I refactored the VTableSpecializer: I moved the VTableSpecializer pass into MandatoryPerformanceOptimizations. MandatoryPerformanceOptimizations already did most of the vtable specialization work.
So it makes sense to remove the VTableSpecializerPass completely and do everything in MandatoryPerformanceOptimizations.

This is a follow-up of #76572

@eeckstein
Copy link
Contributor Author

@swift-ci test

@eeckstein
Copy link
Contributor Author

@swift-ci test

@@ -258,8 +258,6 @@ SWIFT_FUNCTION_PASS(DeadStoreElimination, "dead-store-elimination",
"Dead Store Elimination")
PASS(GenericSpecializer, "generic-specializer",
"Generic Function Specialization on Static Types")
PASS(VTableSpecializer, "vtable-specializer",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

@@ -1333,9 +1333,8 @@ void IRGenerator::emitLazyDefinitions() {
assert(LazyFieldDescriptors.empty());
// LazyFunctionDefinitions are allowed, but they must not be generic
for (SILFunction *f : LazyFunctionDefinitions) {
assert(hasValidSignatureForEmbedded(f));
ASSERT(hasValidSignatureForEmbedded(f));
Copy link
Contributor

Choose a reason for hiding this comment

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

This is an assert that is active even in production builds, correct? Should I be preferring those in further patches?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. Yes, I'm always using this ASSERT since we have it, because it's really not good to not catch asserts in an ndebug compiler.

return C2(x: S())
}

open class C3<X> {
public func foo<T>(t: T) {} // expected-error {{classes cannot have non-final generic fuctions in embedded Swift}}
}

func testit3() -> C3<S> {
public func testit3() -> C3<S> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just checking if I got it right: We need all this stuff to be "public" because we moved the checking outside of the VTableSpecializer (where it was processing the vtables eagerly) into PerfDiags where it's done more lazily and non-public things are removed by that point?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's because dead-function-elimination runs before PerfDiags.
But I moved the check back to MandatoryPerformanceOptimizations - and reverted the changes in this test file.

@kubamracek
Copy link
Contributor

@swift-ci please test

@eeckstein eeckstein force-pushed the class-existentials branch 2 times, most recently from de9eca0 to 10ea1cb Compare September 25, 2024 13:59
@eeckstein
Copy link
Contributor Author

@swift-ci test

And use that in some Builder APIs
And move NominalTypeDecl and DeclRef from Type.swift into a new file Declarations.swift.
Also add some APIs to NominalTypeDecl
* add missing APIs
* bridge the entries as values and not as pointers
* add lookup functions in `Context`
* make WitnessTable.Entry.Kind enum cases lower case
The main change here is to associate a witness table with a `ProtocolConformance` instead of a `RootProtocolConformance`.
A `ProtocolConformance` is the base class and can be a `RootProtocolConformance` or a `SpecializedProtocolConformance`.
* `specialize(function:)`
* `deserializeCallees(of:)`
* `createWitnessTable()`
* `createSpecializedVTable`
* `Function.set(isSerialized:)`
…timizations

MandatoryPerformanceOptimizations already did most of the vtable specialization work.
So it makes sense to remove the VTableSpecializerPass completely and do everything in MandatoryPerformanceOptimizations.
@eeckstein
Copy link
Contributor Author

@swift-ci test

@eeckstein eeckstein merged commit 8c5d7ee into swiftlang:main Sep 26, 2024
5 checks passed
@eeckstein eeckstein deleted the class-existentials branch September 26, 2024 05:37
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