-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Add an effects(releasenone) function effects attribute #14924
Add an effects(releasenone) function effects attribute #14924
Conversation
@swift-ci Please test |
lib/AST/Attr.cpp
Outdated
case EffectsKind::ReadWrite: | ||
case EffectsKind::ReleaseNone: | ||
return "effects(releasenone)"; | ||
case EffectsKind::ReadWrite: |
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.
Unintentional outdent?
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.
Thanks I have fixed this in a later commit.
Do you have a test case where code without the annotation is not ARC optimized, while code with it is? |
Compare the SIL of useFoobar with and without the
|
Looking good 🎉 I've seen the exact same sort of retain/releases around opaque hasher calls; this looks to be exactly what we need. (I'm working on reverting #14913 to use a simple |
@aschwaighofer is that test part of this PR? Where can I see the effects of this and how do I know what is and isn't guaranteed? |
No this test is not part of the commit. Right now you have to read the commit message. This commit only tests that side effect analysis returns that a function may read or write but does not release. Everything else follows from that. When I come back from vacation I will add something to the docs. |
The test case above is confusing (because it actually does release). I only did it this way to be able to test single file (without the store to the globale side effects analysis would have figured norelease on its own). releasenone = may read, may write, but (as if) no release happens |
Not to hold this up, since it's immediately required and doesn't make things too much worse, but... Effects annotations will only be decipherable to me when we have a 1-1 mapping from attribute to effect. To get the equivalent of today's [readnone] you would need "[noread] [nowrite] [noretain] [norelease]", with only some combinations legal. i.e. you can't use any other effect attribute unless you also explicitly write [norelease]. Then we need the param-only variants, [noglobalread] [noglobalwrite] (which also require [norelease]). I don't think it makes sense to talk about global retain/release. Then, in the optimization guide we can just define each of these attributes independently with the caveat that releasing may involve arbitrary reads or writes. |
Oh, we may want to be able to use annotations to say we release without accessing globals or writing in a deinit, I just think it's error prone to add constraints by omission. i.e. "[noglobalread] [noglobalwrite]" would still be an error without also adding some sort of "deinit" attribute. |
A ``@effects(releasenone)`` function might read/write global state but does not perform a release.
d98f66f
to
6fe0633
Compare
@swift-ci Please smoke test |
@milseman Second attempt at the example. I need two files to make it less confusing. Without -wmo the optimizer does not see the function bodies across file boundaries and cannot reason about whether a function may release or not. A function becomes a black box (except for its annotations).
With the annotation the ARC optimizer knows that
Compare to:
|
@swift-ci Please test |
Build failed |
Build failed |
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.
LGTM
strong_release %0 : $Builtin.NativeObject | ||
%10 = tuple() | ||
return %10 : $() | ||
} |
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.
👍
@aschwaighofer (out of scope for this PR) how does the optimizer test optimizations across module boundaries? How does the optimizer test |
Most of the SILOptimizer test cases are written in SIL. In SIL you can declare but not define a function. See for example the test case I added. This way the test case controls whether the implementation is available or not. If you write a test case with swift source you can compile in -wmo mode or not and you could use two files to control visibility. If you want to test across module boundary specifically you would generate a swift module. The example I posted first was what I used for my testing when I added the attribute (I could have split this into two files but it was quicker for me this way). I then made the mistake to assume you were only interested in seeing the attribute working and so I posted the example I had on hand. |
A
@effects(releasenone)
function might read/write global state but does not perform a release.