-
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
Avoid creating result temp for switch-expressions #69194
base: main
Are you sure you want to change the base?
Changes from all commits
1c24d15
ef864e8
8700a94
80b45e7
5f1f000
3cd0617
edd02ad
ffe56a2
e0e0f87
755afc6
92d93d8
6d5275d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -1525,6 +1525,18 @@ | |||||||
<Field Name="WasTargetTyped" Type="bool" /> | ||||||||
</Node> | ||||||||
|
||||||||
<Node Name="BoundLoweredSwitchExpression" Base="BoundExpression" HasValidate="true"> | ||||||||
<Field Name="Type" Type="TypeSymbol" Override="true" Null="disallow"/> | ||||||||
<Field Name="Statements" Type="ImmutableArray<BoundStatement>"/> | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
<Field Name="SwitchArms" Type="ImmutableArray<BoundLoweredSwitchExpressionArm>"/> | ||||||||
</Node> | ||||||||
|
||||||||
<Node Name="BoundLoweredSwitchExpressionArm" Base="BoundNode"> | ||||||||
<Field Name="Locals" Type="ImmutableArray<LocalSymbol>"/> | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are the same locals in roslyn/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_SwitchExpression.cs Lines 114 to 116 in 37bdfe3
BoundScope is rewritten in MethodToClassRewriter , otherwise DefineScopeLocals is used on locals. To cover the first part, I think we could use this existing node in the spiller (I suppose that's where this is relevant) and insert BoundScope instead of rewriting the node itself with assignments, if that sounds right to you I can try it in the next iteration.
|
||||||||
<Field Name="Statements" Type="ImmutableArray<BoundStatement>"/> | ||||||||
<Field Name="Value" Type="BoundExpression" Null="disallow"/> | ||||||||
</Node> | ||||||||
|
||||||||
<Node Name="BoundDecisionDag" Base="BoundNode"> | ||||||||
<Field Name="RootNode" Type="BoundDecisionDagNode" Null="disallow"/> | ||||||||
</Node> | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -575,7 +575,7 @@ public BoundNode VisitStatement(BoundNode node) | |
return VisitSideEffect(node); | ||
} | ||
|
||
public ImmutableArray<BoundStatement> VisitSideEffects(ImmutableArray<BoundStatement> statements) | ||
public ImmutableArray<T> VisitSideEffects<T>(ImmutableArray<T> statements) where T : BoundNode | ||
{ | ||
#if DEBUG | ||
int prevStack = _expectedStackDepth; | ||
|
@@ -1467,6 +1467,26 @@ public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) | |
return node.Update(boundExpression, node.Cases, node.DefaultLabel, node.LengthBasedStringSwitchDataOpt); | ||
} | ||
|
||
#if DEBUG | ||
public override BoundNode VisitLoweredSwitchExpression(BoundLoweredSwitchExpression node) | ||
{ | ||
return node.Update( | ||
VisitSideEffects(node.Statements), | ||
VisitSideEffects(node.SwitchArms), | ||
VisitType(node.Type)); | ||
} | ||
#endif | ||
|
||
public override BoundNode VisitLoweredSwitchExpressionArm(BoundLoweredSwitchExpressionArm node) | ||
{ | ||
var statements = VisitSideEffects(node.Statements); | ||
var value = VisitExpression(node.Value, ExprContext.Value); | ||
PopEvalStack(); | ||
_counter++; | ||
EnsureOnlyEvalStack(); | ||
Comment on lines
+1484
to
+1486
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as exception filters which basically throws away the value and fence it against whatever comes after. I wonder if this is more restrictive than what's done for conditional operators? Also, I didn't understand what is being compensated for here since there's no skipped node. |
||
return node.Update(node.Locals, statements, value); | ||
} | ||
|
||
public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) | ||
{ | ||
var statements = VisitSideEffects(node.Statements); | ||
|
@@ -2300,6 +2320,13 @@ BoundExpression visitArgumentsAndUpdateCall(BoundCall node, BoundExpression? rec | |
} | ||
#nullable disable | ||
|
||
public override BoundNode VisitLoweredSwitchExpressionArm(BoundLoweredSwitchExpressionArm switchArm) | ||
{ | ||
var result = base.VisitLoweredSwitchExpressionArm(switchArm); | ||
_nodeCounter++; | ||
return result; | ||
} | ||
|
||
public override BoundNode VisitCatchBlock(BoundCatchBlock node) | ||
{ | ||
var exceptionSource = node.ExceptionSourceOpt; | ||
|
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.
It feels like a BoundNode_Validate.cs file could be used to gather all these in one place.