Fix a stack-discipline bug with inlining coroutines #20335
Merged
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.
Stack-allocating instructions in a function are required to obey a local stack discipline. Inlining a non-coroutine maintains this stack discipline in the caller, but coroutine inlining doesn't necessarily. That's because memory can be allocated after the
begin_apply
and deallocated after theend_apply
, and in fact this is a somewhat likely output of SILGen if a temporary is required during an access. (Memory can also be allocated before thebegin_apply
and deallocated before theend_apply
, and of course we need to handle that, but it's not a likely output of SILGen.)One potential fix would be to require coroutine begin/end to participate in stack discipline, but that would create some pretty big problems for SILGen (which manages both access lifetime and temporary lifetime but uses different cleanup-stack mechanisms for them) and probably also the optimizers. So instead we just clean up stack lifetime by delaying deallocations using the existing
StackNesting
framework. As a compile-time optimization, we can avoid this if the callee doesn't have allocations that are live across theyield
or if the caller's stack is the same at theend_apply
sites as it was atbegin_apply
.