public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) { BoundSpillSequenceBuilder builder = null; var expression = VisitExpression(ref builder, node.Expression); return(UpdateStatement(builder, node.Update(expression, node.Cases, node.DefaultLabel, node.EqualityMethod))); }
public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) { AddGoto(node.DefaultLabel); foreach ((_, LabelSymbol label) in node.Cases) { AddGoto(label); } return(base.VisitSwitchDispatch(node)); }
private bool GenerateSwitchDispatch(BoundDecisionDagNode node, HashSet <BoundDecisionDagNode> loweredNodes) { Debug.Assert(!loweredNodes.Contains(node)); // We only generate a switch dispatch if we have two or more value tests in a row if (!(node is BoundTestDecisionDagNode firstTestNode && firstTestNode.Test is BoundDagValueTest firstTest && firstTestNode.WhenFalse is BoundTestDecisionDagNode whenFalse && whenFalse.Test is BoundDagValueTest secondTest && !loweredNodes.Contains(whenFalse) && !this._dagNodeLabels.ContainsKey(whenFalse) && firstTest.Input == secondTest.Input && firstTest.Input.Type.IsValidV6SwitchGoverningType())) { // https://github.com/dotnet/roslyn/issues/12509 Could optimize float, double, decimal value switches. For now use if-then-else return(false); } // Gather up the (value, label) pairs, starting with the first one var cases = ArrayBuilder <(ConstantValue value, LabelSymbol label)> .GetInstance(); cases.Add((value: firstTest.Value, label: GetDagNodeLabel(firstTestNode.WhenTrue))); BoundTestDecisionDagNode previous = firstTestNode; while (previous.WhenFalse is BoundTestDecisionDagNode p && p.Test is BoundDagValueTest vd && vd.Input == firstTest.Input && !this._dagNodeLabels.ContainsKey(p) && !loweredNodes.Contains(p)) { cases.Add((value: vd.Value, label: GetDagNodeLabel(p.WhenTrue))); loweredNodes.Add(p); previous = p; } // If we are emitting a hash table based string switch, // we need to generate a helper method for computing // string hash value in <PrivateImplementationDetails> class. MethodSymbol?stringEquality = null; if (firstTest.Input.Type.SpecialType == SpecialType.System_String) { EnsureStringHashFunction(cases.Count, node.Syntax); stringEquality = _localRewriter.UnsafeGetSpecialTypeMethod(node.Syntax, SpecialMember.System_String__op_Equality); } LabelSymbol defaultLabel = GetDagNodeLabel(previous.WhenFalse); var dispatch = new BoundSwitchDispatch( node.Syntax, _tempAllocator.GetTemp(firstTest.Input), cases.ToImmutableAndFree(), defaultLabel, stringEquality); _loweredDecisionDag.Add(dispatch); return(true); }
public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) { VisitRvalue(node.Expression); var state = this.State.Clone(); PendingBranches.Add(new PendingBranch(node, state, node.DefaultLabel)); foreach ((_, LabelSymbol label) in node.Cases) { PendingBranches.Add(new PendingBranch(node, state, label)); } SetUnreachable(); return(null); }