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])); } }