public override void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; List <int> newOperations; var newObjOperations = FindAllNewOperators(useDef, out newOperations); if (newObjOperations.Length == 0) { return; } var getAllUsages = useDef.GetAllUsedVariables(); var unusedNewObj = new List <int>(); foreach (var newOperation in newOperations) { var definition = useDef.GetDefinition(newOperation); if (getAllUsages.Contains(definition)) { continue; } unusedNewObj.Add(newOperation); } if (unusedNewObj.Count == 0) { return; } Result = true; interpreter.DeleteInstructions(unusedNewObj); }
private static bool HandleInterpreterInstructions(CilMethodInterpreter interpreter, List <Type> usedTypes) { var useDef = interpreter.MidRepresentation.UseDef; var calls = useDef.GetOperationsOfKind(OperationKind.CallVirtual).ToList(); var allOps = useDef.GetLocalOperations(); var result = false; foreach (var callOp in calls) { var op = allOps[callOp]; var methodData = (CallMethodStatic)op; var callingInterpreterKey = methodData.Interpreter.ToKey(); var methodBase = callingInterpreterKey.Interpreter.Method; if (!methodBase.IsFinal) { continue; } interpreter.MidRepresentation.LocalOperations[callOp] = new CallMethodStatic(methodData.Interpreter) { Result = methodData.Result, Parameters = methodData.Parameters }; result = true; } if (result) { interpreter.MidRepresentation.UpdateUseDef(); } return(result); }
public override bool ApplyOptimization(CilMethodInterpreter interpreter, ClosureEntities closure) { var midRepresentation = interpreter.MidRepresentation; var useDef = midRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var callIndices = useDef.GetOperationsOfKind(OperationKind.Call); foreach (var index in callIndices) { var op = operations[index]; var methodData = (CallMethodStatic)op; var info = methodData.Info; if (!info.IsConstructor) { continue; } if (info.DeclaringType != typeof(object) && info.DeclaringType != interpreter.Method.DeclaringType) { continue; } midRepresentation.LocalOperations.RemoveAt(index); return(true); } return(false); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var labelIndices = useDef.GetOperationsOfKind(OperationKind.Label); var found = labelIndices.Length == 0; if (!found) { return; } foreach (var i in labelIndices) { var operation2 = operations[i + 1]; if (operation2.Kind != OperationKind.Label) { continue; } var operation = operations[i]; var jumpId = ((Label)operation).JumpTo; var jumpId2 = ((Label)operation2).JumpTo;; OptimizeConsecutiveLabels(operations, jumpId, jumpId2); interpreter.DeleteInstructions(new[] { i + 1 }); Result = true; } }
public override bool ApplyOptimization(CilMethodInterpreter interpreter, ClosureEntities closure) { var useDef = interpreter.MidRepresentation.UseDef; List <int> newOperations; var newObjOperations = FindAllNewOperators(useDef, out newOperations); if (newObjOperations.Length == 0) { return(false); } var getAllUsages = useDef.GetAllUsedVariables(); var unusedNewObj = new List <int>(); foreach (var newOperation in newOperations) { var definition = useDef.GetDefinition(newOperation); if (getAllUsages.Contains(definition)) { continue; } unusedNewObj.Add(newOperation); } if (unusedNewObj.Count == 0) { return(false); } interpreter.DeleteInstructions(unusedNewObj); return(true); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var labelTable = useDef.GetLabelTable(true); var reached = new SortedSet <int>(); Interpret(0, operations, labelTable, reached); if (reached.Count == operations.Length) { return; } Result = true; var toDelete = new List <int>(); for (var i = 0; i < operations.Length; i++) { if (!reached.Contains(i)) { toDelete.Add(i); } } interpreter.DeleteInstructions(toDelete); }
private static bool HandleInterpreterInstructions(CilMethodInterpreter interpreter, List <Type> usedTypes) { var useDef = interpreter.MidRepresentation.UseDef; var calls = useDef.GetOperationsOfKind(OperationKind.CallVirtual).ToList(); var allOps = useDef.GetLocalOperations(); var result = false; foreach (var callOp in calls) { var op = allOps[callOp]; var methodData = (CallMethodStatic)op; var callingInterpreterKey = methodData.Interpreter.ToKey(); var declaringType = callingInterpreterKey.Interpreter.Method.DeclaringType; var implementors = declaringType.ImplementorsOfT(usedTypes); implementors.Remove(declaringType); if (implementors.Count > 0) { continue; } //TODO: map correct method interpreter.MidRepresentation.LocalOperations[callOp] = new CallMethodStatic(methodData.Interpreter) { Result = methodData.Result, Parameters = methodData.Parameters }; result = true; } if (result) { interpreter.MidRepresentation.UpdateUseDef(); } return(result); }
public override bool OptimizeBlock(CilMethodInterpreter midRepresentation, int startRange, int endRange, LocalOperation[] operations) { var localOperations = midRepresentation.MidRepresentation.UseDef.GetLocalOperations(); var calls = FindBinaryOperators(localOperations, startRange, endRange); if (calls.Count < 2) { return(false); } for (var i = 0; i < calls.Count - 1; i++) { var firstOperator = localOperations.GetBinaryOperator(calls, i); for (var j = i + 1; j < calls.Count; j++) { var secondOperator = localOperations.GetBinaryOperator(calls, j); if (AreDifferentOperators(firstOperator, secondOperator, calls, i, j, localOperations)) { continue; } ApplyOptimization(midRepresentation, calls[i], calls[j]); return(true); } } return(false); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var midRepresentation = interpreter.MidRepresentation; var useDef = midRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var callIndices = useDef.GetOperationsOfKind(OperationKind.Call); foreach (var index in callIndices) { var op = operations[index]; var methodData = (CallMethodStatic)op; var info = methodData.Info; if (!info.IsConstructor) { continue; } if (info.DeclaringType != typeof(object) && info.DeclaringType != interpreter.Method.DeclaringType) { continue; } midRepresentation.LocalOperations.RemoveAt(index); Result = true; return; } }
public override bool ApplyOptimization(CilMethodInterpreter interpreter, ClosureEntities closure) { var useDef = interpreter.MidRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var labelTable = useDef.GetLabelTable(true); var reached = new SortedSet <int>(); Interpret(0, operations, labelTable, reached); if (reached.Count == operations.Length) { return(false); } var toDelete = new List <int>(); for (var i = 0; i < operations.Length; i++) { if (!reached.Contains(i)) { toDelete.Add(i); } } interpreter.DeleteInstructions(toDelete); return(true); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var candidateVariables = SetAllCandidateVariables(interpreter); var useDef = interpreter.MidRepresentation.UseDef; var localOp = useDef.GetLocalOperations(); if (RemoveAllEscaping(candidateVariables, localOp, useDef)) { return; } if (candidateVariables.Count == 0) { return; } foreach (var variable in candidateVariables) { var getVariableData = interpreter.AnalyzeProperties.GetVariableData(variable); if (getVariableData != EscapingMode.Unused) { interpreter.AnalyzeProperties.SetVariableData(variable, EscapingMode.Pointer); } } AllocateVariablesOnStack(localOp, candidateVariables, interpreter); }
public static HashSet <LocalVariable> GetAllUsedVariables(CilMethodInterpreter interpreter, bool includeDefinitions = false) { var useDef = interpreter.MidRepresentation.UseDef; return(GetAllUsedVariables(useDef, includeDefinitions)); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; var operations = useDef.GetLocalOperations(); var callIndices = useDef.GetOperationsOfKind(OperationKind.Call); foreach (var i in callIndices) { var operation = operations[i]; var operationData = ComputeAndEvaluatePurityOfCall(operation); if (!operationData.Interpreter.AnalyzeProperties.IsPure || !operationData.Info.IsStatic) { continue; } var methodInfo = operationData.Info; var constParams = new List <object>(); var paramsAreConst = CheckIfParamAreConst(operationData, constParams); if (!paramsAreConst) { continue; } var result = methodInfo.Invoke(null, constParams.ToArray()); interpreter.MidRepresentation.LocalOperations[i] = new Assignment { AssignedTo = operationData.Result, Right = new ConstValue(result) }; Result = true; } }
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 void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; var localOperations = useDef.GetLocalOperations(); var constValues = GetAssignToConstOperations(localOperations, useDef); if (constValues.Count == 0) { return; } localOperations = useDef.GetLocalOperations(); for (var index = 0; index < localOperations.Length; index++) { var op = localOperations[index]; var variableUsages = useDef.GetUsages(index); if (variableUsages.Length == 0) { continue; } foreach (var variable in variableUsages) { ConstValue constMappedValue; if (constValues.TryGetValue(variable, out constMappedValue)) { op.SwitchUsageWithDefinition(variable, constMappedValue); Result = true; } } } }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var operations = interpreter.MidRepresentation.LocalOperations .Where(op => op.Kind == OperationKind.BranchOperator) .Select(operation => (BranchOperator)operation) .ToArray(); foreach (var operation in operations) { var leftVal = (operation.CompareValue as ConstValue); var rightVal = (operation.SecondValue as ConstValue); if (leftVal == null || rightVal == null) { continue; } switch (operation.Name) { case OpcodeBranchNames.Beq: FoldEvaluation(operation, EvaluateBeq(leftVal, rightVal)); break; default: throw new InvalidDataException( "ConstantVariableEvaluation optimization. Case not handled, report a bug with reduced code"); } } }
private static bool ComputeFunctionPurity(CilMethodInterpreter intermediateCode) { if (intermediateCode == null) { return(false); } var operations = intermediateCode.MidRepresentation.UseDef.GetLocalOperations(); foreach (var localOperation in operations) { switch (localOperation.Kind) { case OperationKind.SetField: case OperationKind.Assignment: case OperationKind.AlwaysBranch: case OperationKind.Label: case OperationKind.Return: break; default: return(false); } } return(true); }
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); }
public override bool ApplyOptimization(CilMethodInterpreter interpreter, ClosureEntities closure) { var candidateVariables = SetAllCandidateVariables(interpreter, closure); var useDef = interpreter.MidRepresentation.UseDef; var localOp = useDef.GetLocalOperations(); if (RemoveAllEscaping(candidateVariables, localOp, useDef)) { return(false); } if (candidateVariables.Count == 0) { return(false); } var result = false; foreach (var variable in candidateVariables) { var getVariableData = interpreter.AnalyzeProperties.GetVariableData(variable); if (getVariableData != EscapingMode.Unused && getVariableData != EscapingMode.Stack) { result |= interpreter.AnalyzeProperties.SetVariableData(variable, EscapingMode.Pointer); } } AllocateVariablesOnStack(localOp, candidateVariables, interpreter); return(result); }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var operations = interpreter.MidRepresentation.LocalOperations.ToArray(); for (var i = 0; i < operations.Length - 1; i++) { Assignment srcVariableDefinition; var constValue = GetConstantFromOperation(operations[i], out srcVariableDefinition); if (constValue == null) { continue; } for (var j = i + 1; j < operations.Length; j++) { var destOperation = operations[j]; if (destOperation.Kind == OperationKind.Label) { break; } if (destOperation.Kind == OperationKind.BranchOperator) { break; } if (destOperation.Kind != OperationKind.BinaryOperator && destOperation.Kind != OperationKind.UnaryOperator) { continue; } var destAssignment = (OperatorBase)destOperation; if (SameVariable(destAssignment.AssignedTo, srcVariableDefinition.AssignedTo)) { break; } var rightBinaryAssignment = destAssignment as BinaryOperator; var unaryAssignment = destAssignment as UnaryOperator; if (unaryAssignment != null) { continue; } if (rightBinaryAssignment == null) { continue; } if (SameVariable(rightBinaryAssignment.Left as LocalVariable, srcVariableDefinition.AssignedTo)) { rightBinaryAssignment.Left = constValue; Result = true; continue; } if (SameVariable(rightBinaryAssignment.Right as LocalVariable, srcVariableDefinition.AssignedTo)) { rightBinaryAssignment.Right = constValue; Result = true; } } } }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var localOperations = interpreter.MidRepresentation.UseDef.GetLocalOperations(); for (var index = 0; index < localOperations.Length; index++) { var localOperation = localOperations[index]; if (localOperation.Kind != OperationKind.Call) { continue; } var methodData = (CallMethodStatic)localOperation; var cilMethodInterpreter = methodData.GetInterpreter(Closure) as CilMethodInterpreter; if (cilMethodInterpreter == null) { continue; } if (AnalyzeFunctionIsGetter.ReadProperty(cilMethodInterpreter) || AnalyzeFunctionIsSetter.ReadProperty(cilMethodInterpreter) || AnalyzeFunctionIsEmpty.ReadProperty(cilMethodInterpreter) ) { SmallFunctionsInliner.InlineMethod(interpreter.MidRepresentation, methodData, index); Result = true; return; } } }
public void NewObject(MethodBase constructorInfo) { if (constructorInfo.DeclaringType == typeof(object)) { return; } constructorInfo.Register(); var result = SetNewVReg(); result.FixedType = new TypeDescription(constructorInfo.DeclaringType); var constructedObject = new NewConstructedObject { AssignedTo = result, Info = constructorInfo }; AddOperation(constructedObject); var interpreter = new CilMethodInterpreter(constructedObject.Info); var methodData = new CallMethodStatic(interpreter); CallMethodData(constructedObject.Info, methodData); var vreg = SetNewVReg(); vreg.FixedType = new TypeDescription(methodData.Info.DeclaringType); var assign = new Assignment { AssignedTo = vreg, Right = methodData.Parameters.First() }; AddOperation(assign); }
public override void OptimizeOperations(CilMethodInterpreter methodInterpreter) { var useDef = methodInterpreter.MidRepresentation.UseDef; var localOperations = useDef.GetLocalOperations(); var toRemove = new List <int>(); var callIndices = useDef.GetOperationsOfKind(OperationKind.Call); foreach (var index in callIndices) { var operation = localOperations[index]; var methodData = operation.Get <CallMethodStatic>(); var interpreter = methodData.GetInterpreter(Closure); if (interpreter == null) { continue; } if (methodData.Result != null) { continue; } var properties = interpreter.AnalyzeProperties; if (properties.IsReadOnly || properties.IsPure) { toRemove.Add(index); } } if (toRemove.Count == 0) { return; } methodInterpreter.DeleteInstructions(toRemove); Result = true; }
public override void OptimizeOperations(CilMethodInterpreter interpreter) { var useDef = interpreter.MidRepresentation.UseDef; var operations = useDef.GetLocalOperations(); for (var i = 0; i < operations.Length - 1; i++) { Assignment srcVariableDefinition; var constValue = GetConstantFromOperation(operations[i], out srcVariableDefinition); if (constValue == null) { continue; } for (var j = i + 1; j < operations.Length; j++) { var destOperation = operations[j]; if (destOperation.Kind == OperationKind.Label) { break; } if (destOperation.Kind == OperationKind.BranchOperator) { break; } if (destOperation.Kind != OperationKind.Call) { continue; } var callData = (CallMethodStatic)destOperation; if (SameVariable(callData.Result, srcVariableDefinition.AssignedTo)) { break; } var pos = -1; bool found; do { found = false; foreach (var identifierValue in callData.Parameters) { pos++; if (!SameVariable(srcVariableDefinition.AssignedTo, identifierValue as LocalVariable)) { continue; } found = true; break; } if (!found) { continue; } callData.Parameters[pos] = constValue; Result = true; } while (found); } } }
public override bool OptimizeBlock(CilMethodInterpreter midRepresentation, int startRange, int endRange, LocalOperation[] operations) { var instructionRange = GetInstructionRange(operations, startRange, endRange); var useDef = midRepresentation.MidRepresentation.UseDef; return(ProcessOptimizations(startRange, instructionRange, useDef)); }
private bool TryOptimizeBlock(CilMethodInterpreter localOperations, int startRange, int endRange, LocalOperation[] operations) { if (startRange >= endRange) { return(false); } return(OptimizeBlock(localOperations, startRange, endRange, operations)); }
private static void MergeVRegs(MetaMidRepresentation intermediateCode, CilMethodInterpreter methodToInlineInterpreter, Dictionary <int, int> mappedVregs) { var virtRegs = methodToInlineInterpreter.MidRepresentation.Vars.VirtRegs; var vregsToAdd = mappedVregs.Select(id => GetVRegMapped(virtRegs, id)).ToList(); intermediateCode.Vars.VirtRegs.AddRange(vregsToAdd); }
public void CallVirtual(MethodBase operand) { var methodInfo = operand; var interpreter = new CilMethodInterpreter(methodInfo); var methodData = new CallMethodVirtual(interpreter); CallMethodDataVirtual(methodInfo, methodData); }
private static List <int> BuildBlockOperations(CilMethodInterpreter methodInterpreter) { var useDef = methodInterpreter.MidRepresentation.UseDef; var result = new List <int>(); result.AddRange(useDef.GetOperationsOfKind(OperationKind.Label)); result.AddRange(useDef.GetOperationsOfKind(OperationKind.BranchOperator)); result.AddRange(useDef.GetOperationsOfKind(OperationKind.AlwaysBranch)); result.Sort(); return(result); }
public override bool ApplyOptimization(CilMethodInterpreter interpreter, ClosureEntities closure) { var localOperations = interpreter.MidRepresentation.UseDef.GetLocalOperations(); var toPatch = Analyze(localOperations); if (toPatch.Count == 0) { return(false); } return(ApplyOptimization(interpreter, toPatch, localOperations)); }