private static void ApplyOptimization(CilMethodInterpreter midRepresentation, int i, int j) { var localOps = midRepresentation.MidRepresentation.LocalOperations; var srcMethod = PrecomputeRepeatedUtils.GetMethodData(localOps, i); var destMethod = PrecomputeRepeatedUtils.GetMethodData(localOps, j); if (srcMethod.Result == null) { return; } var computedType = srcMethod.Result.ComputedType(); var newVreg = midRepresentation.CreateCacheVariable(computedType); var assignedTo = srcMethod.Result; var localOperation = PrecomputeRepeatedUtils.CreateAssignLocalOperation(assignedTo, newVreg); localOps.Insert(i + 1, localOperation); srcMethod.Result = newVreg; var destAssignment = PrecomputeRepeatedUtils.CreateAssignLocalOperation(destMethod.Result, newVreg); localOps.RemoveAt(j + 1); localOps.Insert(j + 1, destAssignment); }
public override bool OptimizeBlock(CilMethodInterpreter midRepresentation, int startRange, int endRange, LocalOperation[] operations) { var localOperations = midRepresentation.MidRepresentation.LocalOperations; var calls = FindCallsToPureFunctions(midRepresentation.MidRepresentation.UseDef, startRange, endRange); if (calls.Count < 2) { return(false); } for (var i = 0; i < calls.Count - 1; i++) { var firstMethodData = PrecomputeRepeatedUtils.GetMethodData(localOperations, calls, i); for (var j = i + 1; j < calls.Count; j++) { var secondMethodData = PrecomputeRepeatedUtils.GetMethodData(localOperations, calls, j); if (firstMethodData.Info != secondMethodData.Info) { continue; } var resultMerge = TryMergeCalls(i, j, firstMethodData, secondMethodData, localOperations); if (!resultMerge) { continue; } ApplyOptimization(midRepresentation, calls[i], calls[j]); return(true); } } return(false); }