private RelationalDispatch( SyntaxNode syntax, ConstantValue value, BinaryOperatorKind op, ValueDispatchNode left, ValueDispatchNode right ) : base(syntax) { Debug.Assert(op.OperandTypes() != 0); this.Value = value; this.Operator = op; WithLeftAndRight(left, right); }
/// <summary> /// Push the set of equality tests down to the level of the leaves in the value dispatch tree. /// </summary> private ValueDispatchNode PushEqualityTestsIntoTree( SyntaxNode syntax, ValueDispatchNode otherwise, ImmutableArray <(ConstantValue value, LabelSymbol label)> cases,
/// <summary> /// Generate a switch dispatch for a contiguous sequence of dag nodes if applicable. /// Returns true if it was applicable. /// </summary> private bool GenerateSwitchDispatch(BoundDecisionDagNode node, HashSet <BoundDecisionDagNode> loweredNodes) { Debug.Assert(!loweredNodes.Contains(node)); if (!canGenerateSwitchDispatch(node)) { return(false); } var input = ((BoundTestDecisionDagNode)node).Test.Input; ValueDispatchNode n = GatherValueDispatchNodes(node, loweredNodes, input); LowerValueDispatchNode(n, _tempAllocator.GetTemp(input)); return(true); bool canGenerateSwitchDispatch(BoundDecisionDagNode node) { switch (node) { // These are the forms worth optimizing. case BoundTestDecisionDagNode { WhenFalse: BoundTestDecisionDagNode test2 } test1: return(canDispatch(test1, test2)); case BoundTestDecisionDagNode { WhenTrue: BoundTestDecisionDagNode test2 } test1: return(canDispatch(test1, test2)); default: // Other cases are just as well done with a single test. return(false); } bool canDispatch(BoundTestDecisionDagNode test1, BoundTestDecisionDagNode test2) { if (this._dagNodeLabels.ContainsKey(test2)) { return(false); } Debug.Assert(!loweredNodes.Contains(test2)); var t1 = test1.Test; var t2 = test2.Test; if (!(t1 is BoundDagValueTest || t1 is BoundDagRelationalTest)) { return(false); } if (!(t2 is BoundDagValueTest || t2 is BoundDagRelationalTest)) { return(false); } if (!t1.Input.Equals(t2.Input)) { return(false); } return(true); } } }