[4.2] Perform value operations opaquely on ABI-inaccessible types #16642
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is the swift-4.2-branch version of #16615.
Track whether types are fixed-ABI and ABI-accessible at the SIL level.
Fixed ABI means that we can do value operations on the type without any metadata: value-allocations, copies, and destroys. It's currently equivalent to being fixed-size, but (1) being fixed-size isn't useful by itself at the SIL level and (2) you can imagine resilience or generics micro-optimizations where there's like an attribute that tells us the size of a type without actually telling us how to copy it. All types are fixed-ABI except:
ABI-accessible means that it's legal to perform value operations on the type. We cannot perform value operations on a type
T
if it's not fixed-ABI and we can't construct metadata for it in the current file. The latter will be true ifT
is private to a different file (in non-WMO builds) or internal to a different module because the metadata-accessor symbol will be private or hidden, respectively. Importantly, in these cases, it always illegal to useT
directly in the current file, which means that SIL generated from that source code won't contain any direct value operations onT
. However, we may be able use some typeC
that's itself permitted to useT
and which is accessible to the current file. IfC
contains subobjects of typeT
, value operations onC
must perform value operations onT
recursively. This is okay as long as we don't either:T
orC
into value operations on its subobjects.(Note that we cannot simply treat
C
as an opaque type because we may need to perform operations on it that would not be legal on a totally opaque type, such as directly accessing a known-stored property. It is tempting to try to define that away by saying that we never use direct property access on such types and instead go through property accessors. However, this would require us to guarantee the emission of property accessors for properties, which we'd like to avoid. Also, it's not actually possible to define this problem completely, because the current file might define a typeC2
which containsC
as a subobject. The same recursive trouble applies toC2
as would apply toC
, but we must be able to directly access the properties ofC2
in order to define its constructors and accessors. Any model which can support directly accessing the properties ofC2
can equally support it forC
as well.)The SIL optimizer currently never tries to expand value operations on objects in memory. (It does sometimes expand value operations on scalars, and this may be a problem for the opaque-values effort.) However, IRGen currently recursively expands value operations on non-resilient types. That is fixed as the final commit in this PR.
The SIL verification that I've added here is definitely incomplete.
Fixes rdar://39763787 / SR-7549.