To enable ABIs which store extra info in the frame, add two new slots to
the coroutine allocator function table. For example, a frame could have
a header containing a context pointer at a negative offset from the
address returned from `swift_coro_alloc_frame`. The frame deallocation
function would then know to deallocate more space correspondingly.
Follow up to https://github.com/swiftlang/swift/pull/84635/.
The metadata accessor for a variadic generic type takes as arguments
packs of metadata records and witness tables, and each such pack is
passed in a buffer. So the call to any such accessor is not correctly
annotated memory(none).
rdar://161606892
When TMO is enabled, change IRGen to pass the newly introduced runtime function `swift_coroFrameAlloc` (and pass an additional argument — the hash value) instead of `malloc` when it inserts calls to `coro_id_retcon_once`.
The hashValue is computed based on the current function name (computed in `getDiscriminatorForString`)
rdar://141235957
While materializing one metadata pack, another pack may need to be
materialized. When that happens, the inner pack's dynamically sized
allocation must be deallocated within the same dominance scope.
The CFG within which the inner dynamically sized pack is allocated isn't
visible from SIL; that explains why the existing infrastructure around
`de`/`alloc_pack_metadata` instructions fails to produce a deallocation
at the appropriate point.
In the fullness of time, this emitted code should be optimized such that
the inner loop is hoisted out of its current outer loop.
rdar://141718098
Large tuples of values (e.g char[32]) can be passed directly at the abi
boundry but expand to a big explosion of values.
Peephole this explosion at argument passing and return value passing
points to avoid code size growth associated with the explosion.
Some requirement machine work
Rename requirement to Value
Rename more things to Value
Fix integer checking for requirement
some docs and parser changes
Minor fixes
Those functions are effectively outlined functions with an alwaysinline
attribute. By removing their debug info and relying on the inliner to propagate
the call site location to the inlined instructions, we restore the "original"
locations as if the function had never been outlined.
This is technically relying on an implementation detail of the inliner, but it
seems to be the simplest way of addressing this issue.
This teaches IRGen to only emit a lifetime operation (retain or release) for a C++ foreign reference type if the pointer is not `nullptr`.
Previously the compiler would in some cases emit a release call for `nullptr`, which breaks the assumption that the argument to a custom release function is `_Nonnull`. For instance:
```
var globalOptional: MyRefType? = nil
func foo() { globalOptional = MyRefType.create() }
```
When emitting IR for the assignment operation to `globalOptional`, the compiler would emit code to first retrieve the existing value of `globalOptional` and release it. If the value is `nil`, it does not need to be released.
rdar://97532642
When an @objc @implementation class requires the use of `ClassMetadataStrategy::Update` because some of its stored properties do not have fixed sizes, we adjust the direct field offsets during class realization by emitting a custom metadata update function which calls a new entry point in the Swift runtime. That entry point adjusts field offsets like `swift_updateClassMetadata2()`, but it only assumes that the class has Objective-C metadata, not Swift metadata.
This commit introduces an alternative mechanism which does the same thing without using any Swift-only metadata. It’s a rough implementation with important limitations:
• We’re currently using the field offset vector, which means that field offsets are being emitted into @objc @implementation classes; these will be removed.
• The new Swift runtime entry point duplicates a lot of `swift_updateClassMetadata2()`’s implementation; it will be refactored into something much smaller and more compact.
• Availability bounds for this feature have not yet been implemented.
Future commits in this PR will correct these issues.
Call `swift_clearSensitive` after destroying or taking "sensitive" struct types.
Also, support calling C-functions with "sensitive" parameters or return values. In SIL, sensitive types are address-only and so are sensitive parameters/return values.
Though, (small) sensitive C-structs are passed directly to/from C-functions. We need re-abstract such parameter and return values for C-functions.
* Allow normal function results of @yield_once coroutines
* Address review comments
* Workaround LLVM coroutine codegen problem: it assumes that unwind path never returns.
This is not true to Swift coroutines as unwind path should end with error result.
This adds SIL-level support and LLVM codegen for normal results of a coroutine.
The main user of this will be autodiff as VJP of a coroutine must be a coroutine itself (in order to produce the yielded result) and return a pullback closure as a normal result.
For now only direct results are supported, but this seems to be enough for autodiff purposes.
When metadata record for a generic type is locally cached as ::Complete,
the metadata is known to be complete in that scope. If it's for a
generic type, being complete means that all of its recursive generic
arguments are also complete.
Previously, though, that fact was not exploited. So a metadata record
for such an argument which was originally obtained via an incomplete
request would remain cached in that incomplete state even when a generic
type in which it appeared as a generic argument was cached as complete.
At worst, the result was a runtime call (checkMetadataState) to promote
the complete the metadata record for the recursive argument.
Here, when a bound generic type's metadata is locally cached as
complete, its recursive generic arguments are visited; for each such
type for which a metadata record is already locally cached, the
preexisting record is recached as complete.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
Deallocate dynamic allocas done for metadata/wtable packs. These
stackrestore calls are inserted on the dominance frontier and then stack
nesting is fixed up. That was achieved as follows:
Added a new IRGen pass PackMetadataMarkerInserter; it
- determines if there are any instructions which might allocate on-stack
pack metadata
- if there aren't, no changes are made
- if there are, alloc_pack_metadata just before instructions that could
allocate pack metadata on the stack and dealloc_pack_metadata on the
dominance frontier of those instructions
- fixup stack nesting
During IRGen, the allocations done for metadata/wtable packs are
recorded and IRGenSILFunction associates them with the instruction that
lowered. It must be the instruction after some alloc_pack_metadata
instruction. Then, when visiting the dealloc_pack_metadata instructions
corresponding to that alloc_pack_metadata, deallocate those packs.