-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Implement generalized accessors using yield-once coroutines #18156
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 Please test. |
@atrick I'd appreciate a review of the SILOptimizer changes here. |
Build failed |
Build failed |
9204401
to
217c651
Compare
@swift-ci Please test. |
Build failed |
Build failed |
For now, the accessors have been underscored as `_read` and `_modify`. I'll prepare an evolution proposal for this feature which should allow us to remove the underscores or, y'know, rename them to `purple` and `lettuce`. `_read` accessors do not make any effort yet to avoid copying the value being yielded. I'll work on it in follow-up patches. Opaque accesses to properties and subscripts defined with `_modify` accessors will use an inefficient `materializeForSet` pattern that materializes the value to a temporary instead of accessing it in-place. That will be fixed by migrating to `modify` over `materializeForSet`, which is next up after the `read` optimizations. SIL ownership verification doesn't pass yet for the test cases here because of a general fault in SILGen where borrows can outlive their borrowed value due to being cleaned up on the general cleanup stack when the borrowed value is cleaned up on the formal-access stack. Michael, Andy, and I discussed various ways to fix this, but it seems clear to me that it's not in any way specific to coroutine accesses. rdar://35399664
217c651
to
7a4aeed
Compare
@swift-ci Please test. |
Build failed |
Build failed |
if (!peekToken().is(tok::colon)) { | ||
// "yield" in the right context begins a yield statement. | ||
if (isContextualYieldKeyword()) { | ||
Tok.setKind(tok::kw_yield); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of mutating token in isStartOfStmt()
. For example, skipUntil
family functions call this method that may accidentally mutates it. I think it's better to leave it tok::identifier
here, then setKind()
in parseStmt()
. In case you really need this, please add case tok::kw_yield: return true
in the switch at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. How's this look? #18179
@rjmccall it looks to me like SIL formal access on the begin_apply's address will be handled correctly with this patch. I suspect that side effect analysis will just be conservative at the begin_apply, in the sense that it continues analyzing the function past the The end_apply will be a problem if there's no restriction on what users can do in the coroutine's "tail". As such, I'm a little surprised that it isn't also modeled as an ApplySite. In the current implementation, its side effects are conservative, and the effects on the call graph should already be modeled by the begin_apply, so it may be ok in general. But I'm pretty sure AccessedStorageAnalysis will be wrong. It currently assumes that formal access can only occur at an ApplySite or begin_access. Ultimately, that should be fixed to view the end_apply's effects as if it were an ApplySite. The most natural way to do that would be to teach SideEffectAnalysis in general to treat end_apply as an ApplySite. How do you feel about that? I don't see an alternative short of preventing the user from performing formal access in the coroutine tail. Of course, for now, I could just hack SideEffectAnalysis to call setWorstEffects at an end_apply. |
There are no restrictions about what can happen in the Beyond that, I don't know what significance treating |
Two things.
†I'd like to assume that an arbitrary release, which may call |
Note that |
I think it's conceptually right to make end_apply and apply everywhere. But I don't think it's worth it. There are too many places in the code that assume an ApplySite is either Full or Partial. This would be neither. It would have a callee but no normal arguments. I think that's sort of what you're saying. In practice, giving end_apply arbitrary side effects will end up being conservatively correct in almost all cases. AccessedStorageAnalysis can be fixed easily. SIL developers will just need to remember that there are other apply-like things to check for now. |
For now, the accessors have been underscored as
_read
and_modify
. I'll prepare an evolution proposal for this feature which should allow us to remove the underscores or, y'know, rename them topurple
andlettuce
._read
accessors do not make any effort yet to avoid copying the value being yielded. I'll work on it in follow-up patches.Opaque accesses to properties and subscripts defined with
_modify
accessors will use an inefficientmaterializeForSet
pattern that materializes the value to a temporary instead of accessing it in-place. That will be fixed by migrating tomodify
overmaterializeForSet
, which is next up after theread
optimizations.SIL ownership verification doesn't pass yet for the test cases here because of a general fault in SILGen where borrows can outlive their borrowed value due to being cleaned up on the general cleanup stack when the borrowed value is cleaned up on the formal-access stack. Michael, Andy, and I discussed various ways to fix this, but it seems clear to me that it's not in any way specific to coroutine accesses.
rdar://35399664