-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Support generating loadable types in serialized function when package-cmo is enabled. #73478
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
@swift-ci smoke test |
@swift-ci smoke test |
Hmm, I think we are working around the fact that type lowering does not correctly answer the question whether a type is loadable in the context we are looking at. Today, type lowering takes the type expansion context (resilience expansion, etc) into account. I think we need to add another context item: are we lowering for abstraction purposes (i.e. in SILGen to decide the ABI of function signatures and so parameters need the right abstraction) or are we later in the pipeline (in which case we should check whether we can ignore the resilience expansion if |
@swift-ci smoke test |
It seems like the resilience of a type shouldn't change throughout the compilation. If resilience is disabled for package types, that should be represented throughout the whole compilation, right? The |
@swift-ci smoke test |
…iently built module when package serialization is enabled, return maximal resilience expansion in SILFunction::getResilienceExpansion(). This allows aggregate types to be generated as loadable SIL types which otherwise are address-only in a serialized function. During type lowering, opaque flag setting is also skipped if package serialization is enabled. Resolves rdar://127400743
@swift-ci smoke test |
Resilience does not change. But the context in which we are ask to "expand" a type changes. This is captured by the TypeExpansionContext/ResilienceExpansion abstractions. The TypeExpansionContext is consulted whenever we want to know what kind of abstraction pattern to access a type: e.g loadable or by-address, passing direct or indirect, ... What is being proposed is to model the fact in the TypeExpansionContext that we are allowed to treat types as loadable inside of serialized (~ inlinable) function bodies under the right circumstances: In the world where we don't use package-CMO and bypass-resilience a serialized (~ inlinable) function is not allowed to use a "loadable" abstraction pattern:
This is because this SIL could be still inlined into another module/binary that does not have access to type layout and so it is not okay to assume loadability. However, it is okay once you remove the
With package CMO and
However, when a module that imports another module in the same package that defines the resilient type decides the ABI of the function it still needs to treat it as address-only and pass by address.
This means there need to be two distinct states that TypeExpansionContext models: The one that we use when we lower the signature to decide to pass indirectly for ABI purposes:
The other one that tells us it is okay to use a loadable access pattern inside the function body.
|
I am still struggling with this a bit. Maybe I still don't understand these APIs, but it seems like one of these APIs is being used incorrectly or is implemented incorrectly. Focusing on the overload of This is a huge problem for codegen, if we compile your above example on main:
This produces the following codegen:
Those undefs are because we are trying to turn an empty explosion into a resilient type, because we now disagree on a type's resilience outside of a package resilience domain. Concretely, my suggestions here are:
|
As discussed offline, clients that explicitly opt in to bypass resilience checks to Core types have access to the type layout and are required to be built together with Core, while clients that don't opt in should have indirect access. This is why |
The latest updates in this PR no longer involve changes to TypeExpansionContext. |
Looks good. I assume we remove the serialized flag upon deserialization? Otherwise, we might run into issues with sil-verify-all. |
Are you referring to serializePackageEnabled bit? The flag is still there. The removed part in checkResilience is no longer hit because when package serialization is enabled, the returned resilience expansion is now maximal. |
I referred to the client module that imports the serialized sil. Will that also be compiled with allow-non-resilient-package access? |
The override of ‘getResilienceExpansion’ will only work in modules that are compiled with ’experimental-allow-non-resilient-access’? Once you deserialize the function into another module the override will only work if that importing module was also compiled with ‘experimental-allow-non-resilient-access’ or that module has removed the serialize flag upon importing? |
To support generating loadable types in a serialized function, return maximal resilience expansion in SILFunction::getResilienceExpansion() if package serialization is enabled for modules built resiliently.
This allows aggregate types to be generated as loadable SIL types which otherwise are address-only
in a serialized function. During type lowering, opaque flag setting is also skipped if package serialization
is enabled.
Resolves rdar://127400743