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);
        }
Example #2
0
        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);
        }
Example #4
0
        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);
        }
Example #6
0
        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);
        }
Example #9
0
        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;
            }
        }
Example #10
0
        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);
        }
Example #12
0
        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;
                    }
                }
            }
        }
Example #16
0
        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");
                }
            }
        }
Example #17
0
        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);
        }
Example #20
0
        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;
                    }
                }
            }
        }
Example #21
0
        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;
                }
            }
        }
Example #22
0
        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);
        }
Example #23
0
        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;
        }
Example #24
0
        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);
                }
            }
        }
Example #25
0
        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));
        }
Example #26
0
 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);
        }
Example #28
0
        public void CallVirtual(MethodBase operand)
        {
            var methodInfo = operand;

            var interpreter = new CilMethodInterpreter(methodInfo);

            var methodData = new CallMethodVirtual(interpreter);

            CallMethodDataVirtual(methodInfo, methodData);
        }
Example #29
0
        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);
        }
Example #30
0
        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));
        }