public override void OptimizeOperations(MethodInterpreter interpreter)
        {
            _operations       = interpreter.MidRepresentation.LocalOperations.ToArray();
            _labelTable       = interpreter.MidRepresentation.UseDef.GetLabelTable();
            _pointsOfAnalysis = new DfaPointOfAnalysis[_operations.Length + 1];

            var startingConclusions = new DfaPointOfAnalysis();

            Interpret(0, startingConclusions);

            ApplyResult();
        }
 public bool Equals(DfaPointOfAnalysis other)
 {
     if (ReferenceEquals(null, other))
     {
         return(false);
     }
     if (ReferenceEquals(this, other))
     {
         return(true);
     }
     return(Compare(other));
 }
 private bool Compare(DfaPointOfAnalysis other)
 {
     if (States.Count != other.States.Count)
     {
         return(false);
     }
     foreach (var variableState in States)
     {
         VariableState result;
         if (!other.States.TryGetValue(variableState.Key, out result))
         {
             return(false);
         }
         if (!result.Compare(variableState.Value))
         {
             return(false);
         }
     }
     return(true);
 }
        public DfaPointOfAnalysis Merge(DfaPointOfAnalysis pointsOfAnalysis)
        {
            var result       = new DfaPointOfAnalysis();
            var combinedList = new List <Tuple <LocalVariable, VariableState> >();

            foreach (var variableState in States)
            {
                combinedList.Add(new Tuple <LocalVariable, VariableState>(variableState.Key, variableState.Value));
            }
            if (pointsOfAnalysis != null)
            {
                foreach (var variableState in pointsOfAnalysis.States)
                {
                    combinedList.Add(new Tuple <LocalVariable, VariableState>(variableState.Key, variableState.Value));
                }
            }
            foreach (var tuple in combinedList)
            {
                VariableState variableState;
                if (result.States.TryGetValue(tuple.Item1, out variableState))
                {
                    if (!tuple.Item2.Equals(variableState))
                    {
                        result.States[tuple.Item1] = new VariableState
                        {
                            State = VariableState.ConstantState.NotConstant
                        };
                    }
                }
                else
                {
                    result.States[tuple.Item1] = tuple.Item2;
                }
            }
            return(result);
        }
        private void Interpret(int cursor, DfaPointOfAnalysis startingConclusions)
        {
            var canUpdate = true;

            if (startingConclusions.Equals(_pointsOfAnalysis[cursor]))
            {
                return;
            }
            while (canUpdate)
            {
                _pointsOfAnalysis[cursor] = startingConclusions.Merge(_pointsOfAnalysis[cursor]);

                var        operation = GetOperation(cursor);
                var        analysis  = _pointsOfAnalysis[cursor];
                Assignment assignment;
                switch (operation.Kind)
                {
                case OperationKind.Assignment:
                    assignment = operation.GetAssignment();
                    var constant = assignment.Right as ConstValue;
                    if (constant != null)
                    {
                        analysis.States[assignment.AssignedTo] = new VariableState
                        {
                            Constant = constant,
                            State    = VariableState.ConstantState.Constant
                        };
                    }
                    else
                    {
                        analysis.States[assignment.AssignedTo] = new VariableState
                        {
                            State = VariableState.ConstantState.NotConstant
                        };
                    }
                    startingConclusions = analysis;
                    break;

                case OperationKind.BinaryOperator:
                    assignment = (Assignment)operation.Value;
                    analysis.States[assignment.AssignedTo] = new VariableState
                    {
                        State = VariableState.ConstantState.NotConstant
                    };
                    break;

                case OperationKind.BranchOperator:
                    var branchOperator = (BranchOperator)operation.Value;
                    Interpret(JumpTo(branchOperator.JumpTo), analysis);
                    break;

                case OperationKind.Label:
                    break;

                case OperationKind.Call:
                    break;

                case OperationKind.Return:
                    return;

                case OperationKind.AlwaysBranch:
                    var jumpTo = (int)operation.Value;
                    Interpret(JumpTo(jumpTo), analysis);
                    return;

                default:
                    throw new InvalidOperationException(String.Format("Unhandled: {0}", operation));
                }
                cursor++;
                canUpdate = !(startingConclusions.Equals(_pointsOfAnalysis[cursor]));
            }
        }