-
Notifications
You must be signed in to change notification settings - Fork 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
Implement stackalloc initializers #24249
Implement stackalloc initializers #24249
Conversation
|
@alrz Was the proposal approved by the LDM? #Resolved |
As far as I can tell, the proposal has been approved to merge. though, it's not triaged yet. #Resolved |
|
||
if (expression.InitializerOpt != null) | ||
{ | ||
EmitStackAllocInitializers(expression.Type, expression.InitializerOpt); |
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.
If unused, should still emit init elements to preserve sideeffects
EmitOpCode(ILOpCode.Ldsflda); | ||
EmitToken(field, syntaxNode, diagnostics); | ||
EmitIntConstant(data.Length); | ||
EmitOpCode(ILOpCode.Cpblk, -3); |
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.
Makes sense to emit initblk if all bytes are the same?
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.
Good point.
The only issue could be is if we want to make Span
stackalloc` verifiable, but adjusting verification rules. It is not a problem for now anyways.
In reply to: 162825107 [](ancestors = 162825107)
@@ -1442,9 +1442,17 @@ | |||
<Field Name="Initializers" Type="ImmutableArray<BoundExpression>"/> | |||
</Node> | |||
|
|||
<Node Name="BoundStackAllocArrayInitialization" Base="BoundExpression"> |
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.
Can we reuse BoundArrayInitialization?
I don't think this was discussed in LDM. It's not even a championed issue in csharplang yet. Will bring it up for discussion. #Resolved |
@jcouv is correct. This feature hasn't been sanctioned yet. I think this is something we'd likely need to open a feature branch for. Given the new syntax here there are a number of non-compiler concerns that we'd need to address: intellisense and ENC in particular. #Resolved |
LDM discussed this today and OK'ed the proposal.
|
Yeah, that's messy. we could have avoid that with dotnet/csharplang#877, but I guess we have to live with it now -- unless we're willing to take the breaking change. note, the motivating use case remains intact: // the compiler fails to determine ternary type and tries to convert both operands to the target type
Span<byte> buffer = size < 128 ? stackalloc byte[size] : new byte[size]; except that we won't depend on stackalloc being a direct local init. @VSadov @jcouv is this something we could do at this point? #Resolved |
In the context of ternary stackalloc has natural Span type. |
In the given example “Span” could be “var”. #Resolved |
Correction: |
cad1920
to
ebc2cd1
Compare
ebc2cd1
to
9c31503
Compare
396214b
to
edc09fc
Compare
@@ -4,6 +4,7 @@ | |||
using System.Collections.Generic; | |||
using System.Collections.Immutable; | |||
using System.Diagnostics; | |||
using System.Linq; |
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.
using static System.Linq.ImmutableArrayExtensions
We generally do not want to work with ImmutableArray
through regular Linq extensions #Closed
public class StackAllocInitializerTests : CompilingTestBase | ||
{ | ||
[Fact] | ||
public void NoBestType() |
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 see tests that have a best type which is managed. Can we also cover the case where the best type is void
? #Closed
} | ||
else | ||
{ | ||
// If not used, just emit initializer elements to preserve possible sideeffects |
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.
Could you point me to the test that covers that? I'm not sure how to hit this.
Never mind, found it (TestUnused
) #Resolved
} | ||
} | ||
"; | ||
CompileAndVerify(text, |
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.
Please also verify execution order with expectedOutput:
and printing inside Method
and some other method. #Closed
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.
Done with review pass. A few test suggestions.
I would take a look a unifying syntax nodes and unifying binding logic, to see if that does make the code better.
@VSadov Does this apply to initblk as well? |
@alrz - initblk is ok regardless of the element size. |
Do I need to cover that case in the current PR? that would need GetDataRaw to be called early in ShouldEmitBlockInitializerForStackAlloc which in turn would require a different ArrayInitializerStyle |
@alrz - I think we should drive this PR to completion and then do directed PRs that address specific issues. It may also be acceptable to restrict initblk to the same criteria as cpyblk. Not because it is unsafe to do, but just out of convenience. Anyways, it feels like addressing this issue of when and what optimization happens would be easier in a separate PR. |
@jcouv I've addressed all comments. Not sure about symbol tests, please take look if it covers what you had in mind. |
You mean only after #23951, right? last time I checked it was not zero-initialized. |
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.
One nit and two small test adjustments, then looks good to me. Thanks!
I think both are addressed now. Note that we call |
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
Thanks!! |
Now it makes sense to tune when optimizations happen. The idea is that
|
Proposal: dotnet/csharplang#1122