private void HandleDiv(ConstValue constLeft, ConstValue constRight, LocalOperation destOperation, LocalOperation[] localOperations, int pos) { var binaryOperator = (BinaryOperator)destOperation.Value; if (constRight != null && constRight.Value is int && (int)constRight.Value == 1) { throw new NotImplementedException(); Result = true; return; } if (constLeft != null && constLeft.Value is int && (int)constLeft.Value == 0) { FoldAssign(binaryOperator.Left, localOperations, pos); Result = true; return; } if (constLeft != null && constLeft.Value is double && (double)constLeft.Value == 0.0) { FoldAssign(binaryOperator.Left, localOperations, pos); Result = true; return; } if (constLeft != null && constLeft.Value is float && (float)constLeft.Value == 0.0) { FoldAssign(binaryOperator.Left, localOperations, pos); Result = true; return; } }
static bool UpdateKnownUsages(LocalOperation op, Dictionary <LocalVariable, ConstValue> constValues, Dictionary <LocalVariable, LocalVariable> mappedValues, UseDefDescription useDef, int i) { if (mappedValues.Count == 0 && constValues.Count == 0) { return(false); } var usagesOp = useDef.GetUsages(i); if (usagesOp.Length == 0) { return(false); } var result = false; foreach (var usage in usagesOp) { LocalVariable mappedVar; if (mappedValues.TryGetValue(usage, out mappedVar)) { op.SwitchUsageWithDefinition(usage, mappedVar); result = true; } ConstValue constValue; if (constValues.TryGetValue(usage, out constValue)) { op.SwitchUsageWithDefinition(usage, constValue); result = true; } } return(result); }
private static void HandleNewObject(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter) { var value = (Assignment)operation.Value; var rightValue = (NewConstructedObject)value.Right; var localValue = rightValue.Info; var declaringType = localValue.DeclaringType; var cppName = declaringType.ToDeclaredVariableType(true, EscapingMode.Stack); var assignedData = interpreter.AnalyzeProperties.GetVariableData(value.AssignedTo); var isStack = assignedData == EscapingMode.Stack; if (isStack) { bodySb .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName); } else { bodySb.AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName); } bodySb.AppendLine(); typeTable.SetIdOfInstance(bodySb, value.AssignedTo, declaringType, isStack); }
private static void AddUsagesOfNewArray(LocalOperation operation, List <LocalVariable> result) { var assignment = (Assignment)operation.Value; var arrayVar = (NewArrayObject)assignment.Right; result.AddUsage(arrayVar.ArrayLength); }
private static void AddUsagesOfDerefAssignment(LocalOperation operation, List <LocalVariable> result) { var refData = (DerefAssignment)operation; result.Add(refData.Left); result.Add(refData.Right); }
private static void HandleReadArrayItem(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars) { var value = (Assignment)operation.Value; var valueSrc = (ArrayVariable)value.Right; var parentType = valueSrc.Parent.ComputedType(); var variableData = vars.GetVariableData(value.AssignedTo); switch (variableData.Escaping) { case EscapingMode.Smart: bodySb.AppendFormat(parentType.ClrType.IsClass ? "{0} = (*{1})[{2}];" : "{0} = {1}[{2}];", value.AssignedTo.Name, valueSrc.Parent.Name, valueSrc.Index.Name); return; case EscapingMode.Pointer: bodySb.AppendFormat(parentType.ClrType.IsClass ? "{0} = ((*{1})[{2}]).get();" : "{0} = ({1}[{2}]).get();", value.AssignedTo.Name, valueSrc.Parent.Name, valueSrc.Index.Name); return; } }
public static void HandleReturn(LocalOperation operation, StringBuilder bodySb, MethodInterpreter interpreter) { var returnValue = (Return)operation; if (returnValue.Returning == null) { bodySb.Append("return;"); } else { //Need to expand this for more cases if (returnValue.Returning is ConstValue) { var retType = interpreter.Method.GetReturnType(); if (retType == typeof(string)) { bodySb.AppendFormat("return {0};", returnValue.Returning.ComputedValue()); } else { bodySb.AppendFormat("return {0};", returnValue.Returning.Name); } } else { bodySb.AppendFormat("return {0};", returnValue.Returning.Name); } } }
private static void HandleAssign(StringBuilder sb, LocalOperation operation, MidRepresentationVariables vars, TypeDescriptionTable typeTable, MethodInterpreter interpreter) { var assignment = (Assignment)operation.Value; if (assignment.Right is NewConstructedObject) { HandleNewObject(operation, sb, vars, typeTable, interpreter); return; } var assignedTo = assignment.AssignedTo; var localVariable = assignment.Right as LocalVariable; if (localVariable != null) { var leftVarType = assignment.AssignedTo.ComputedType(); var rightVarType = assignment.Right.ComputedType(); if (leftVarType != rightVarType) { if (rightVarType.ClrType.IsPointer) { sb.AppendFormat("{0} = *{1};", assignedTo, localVariable.Name); return; } } var assignedToData = interpreter.AnalyzeProperties.GetVariableData(assignedTo); var localVariableData = interpreter.AnalyzeProperties.GetVariableData(localVariable); var rightVar = localVariable; var description = assignedTo.ComputedType(); if (description.ClrTypeCode != TypeCode.Object || assignedToData == localVariableData) { sb.AppendFormat("{0} = {1};", assignedTo.Name, rightVar.Name); return; } switch (assignedToData) { case EscapingMode.Pointer: switch (localVariableData) { case EscapingMode.Stack: sb.AppendFormat("{0} = &{1};", assignedTo.Name, rightVar.Name); return; case EscapingMode.Smart: sb.AppendFormat("{0} = ({1}).get();", assignedTo.Name, rightVar.Name); return; } break; case EscapingMode.Smart: throw new InvalidDataException("Case not possible!"); } throw new InvalidDataException("Case not handled"); } else { sb.AppendFormat("{0} = {1};", assignedTo.Name, assignment.Right.ComputedValue()); } }
static void HandleCall(HashSet <LocalVariable> candidateVariables, LocalOperation op) { var methodData = (CallMethodStatic)op; if (methodData.Result != null) { candidateVariables.Remove(methodData.Result); } var escapeFullData = methodData.Interpreter.BuildEscapeModes(); for (var index = 0; index < methodData.Parameters.Count; index++) { var parameter = methodData.Parameters[index]; var variable = parameter as LocalVariable; if (variable == null) { continue; } if (escapeFullData[index] == EscapingMode.Smart) { candidateVariables.Remove(variable); } } }
private static void AddUsagesOfGetArrayItem(LocalOperation operation, List <LocalVariable> result) { var assignment = (GetArrayElement)operation; result.AddUsage(assignment.Instance); result.AddUsage(assignment.Index); }
private static void HandleNewObject(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars) { var value = (Assignment)operation.Value; var rightValue = (NewConstructedObject)value.Right; var localValue = rightValue.Info; var declaringType = localValue.DeclaringType; var cppName = declaringType.ToDeclaredVariableType(true, EscapingMode.Stack); var assignedData = vars.GetVariableData(value.AssignedTo); switch (assignedData.Escaping) { case EscapingMode.Stack: bodySb .AppendFormat("{1} {0};", value.AssignedTo.Name, cppName) .AppendLine(); break; default: bodySb .AppendFormat("{0} = std::make_shared<{1}>();", value.AssignedTo.Name, cppName) .AppendLine();; break; } }
private void HandleMul(ConstValue constLeft, ConstValue constRight, LocalOperation destOperation, LocalOperation[] localOperations, int pos) { var binaryOperator = (BinaryOperator)destOperation.Value; if (constRight != null && (int)constRight.Value == 1) { FoldAssign(binaryOperator.Left, localOperations, pos); Result = true; return; } var constValue = constLeft ?? constRight; if (constValue != null && constValue.Value is int && (int)constValue.Value == 0) { FoldAssign(constValue, localOperations, pos); destOperation.Kind = OperationKind.Assignment; Result = true; } if (constLeft != null && constLeft.Value is double && (double)constValue.Value == 0.0) { FoldAssign(constValue, localOperations, pos); Result = true; return; } if (constLeft != null && constValue.Value is float && (float)constValue.Value == 0.0) { FoldAssign(constValue, localOperations, pos); Result = true; return; } }
public static CallMethodStatic ComputeAndEvaluatePurityOfCall(LocalOperation operation) { var operationData = (CallMethodStatic)operation; var methodInterpreter = operationData.Info.GetInterpreter(Closure); if (AnalyzeFunctionPurity.ReadPurity(methodInterpreter as CilMethodInterpreter)) { operationData.Interpreter.AnalyzeProperties.IsPure = true; } else { if (methodInterpreter == null) { return(operationData); } if (methodInterpreter.Kind != MethodKind.CilInstructions) { operationData.Interpreter.AnalyzeProperties.IsPure = false; return(operationData); } var computeIsPure = AnalyzeFunctionPurity.ComputeFunctionPurity(methodInterpreter as CilMethodInterpreter); if (computeIsPure) { operationData.Interpreter.AnalyzeProperties.IsPure = true; } } return(operationData); }
public static void HandleCallRuntime(LocalOperation operation, StringBuilder sb) { var operationData = (MethodData)operation.Value; var methodInfo = operationData.Info; if (methodInfo.IsConstructor) { return; //don't call constructor for now } var isVoidMethod = methodInfo.GetReturnType().IsVoid(); if (isVoidMethod) { sb.AppendFormat("{0}", methodInfo.ClangMethodSignature()); } else { sb.AppendFormat("{1} = {0}", methodInfo.ClangMethodSignature(), operationData.Result.Name); } var identifierValues = operationData.Parameters; var argumentsCall = String.Join(", ", identifierValues.Select(p => p.Name)); sb.AppendFormat("({0});", argumentsCall); }
static bool HandleCallOperations(MidRepresentationVariables vars, MethodInterpreter interpreter, ClosureEntities crRuntime, LocalOperation operation, CodeOutput bodySb) { switch (operation.Kind) { case OperationKind.Call: CppHandleCalls.HandleCall(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallInterface: CppHandleCalls.HandleCallInterface(operation, bodySb, vars, interpreter, crRuntime); break; case OperationKind.CallVirtual: CppHandleCalls.HandleCallVirtual(operation, bodySb, interpreter, crRuntime); break; case OperationKind.CallRuntime: CppHandleCalls.HandleCallRuntime(operation, bodySb, crRuntime); break; default: return(false); } return(true); }
public static MethodData ComputeAndEvaluatePurityOfCall(LocalOperation operation) { var operationData = (MethodData)operation.Value; var methodInterpreter = operationData.Info.GetInterpreter(Runtime); if (AnalyzeFunctionPurity.ReadPurity(methodInterpreter)) { operationData.Interpreter.AnalyzeProperties.IsPure = true; } else { if (methodInterpreter == null) { return(operationData); } if (methodInterpreter.Kind != MethodKind.Default) { operationData.Interpreter.AnalyzeProperties.IsPure = false; return(operationData); } var computeIsPure = AnalyzeFunctionPurity.ComputeFunctionPurity(methodInterpreter); if (computeIsPure) { operationData.Interpreter.AnalyzeProperties.IsPure = true; } } return(operationData); }
private static void HandleNewArray(LocalOperation operation, StringBuilder bodySb, MidRepresentationVariables vars) { var assignment = (Assignment)operation.Value; var arrayData = (NewArrayObject)assignment.Right; var assignedData = vars.GetVariableData(assignment.AssignedTo); switch (assignedData.Escaping) { case EscapingMode.Stack: bodySb.AppendFormat("Array <{1}> {0} ({2}); ", assignment.AssignedTo.Name, arrayData.TypeArray.ToCppName(), arrayData.ArrayLength.Name); break; default: bodySb.AppendFormat("{0} = std::make_shared< Array <{1}> >({2}); ", assignment.AssignedTo.Name, arrayData.TypeArray.ToCppName(), arrayData.ArrayLength.Name); break; } }
private static void AddUsagesOfRefArrayItemAssignment(LocalOperation operation, List <LocalVariable> result) { var refData = (RefArrayItemAssignment)operation; result.Add(refData.Left); result.Add(refData.ArrayVar); }
private static void HandleCall(LocalVariable localVariable, HashSet <LocalVariable> candidateVariables, LocalOperation op, CrRuntimeLibrary crRuntime) { var methodData = (MethodData)op.Value; var escapeData = AnalyzeParametersAreEscaping.GetEscapingParameterData(methodData); if (escapeData == null) { candidateVariables.Remove(localVariable); return; } var escapingBools = LinkerUtils.BuildEscapingBools(methodData.Info, crRuntime); for (var index = 0; index < methodData.Parameters.Count; index++) { var parameter = methodData.Parameters[index]; var variable = parameter as LocalVariable; if (variable == null) { continue; } if (escapingBools[index]) { candidateVariables.Remove(variable); } } }
private static void AddUsagesOfSetField(LocalOperation operation, List <LocalVariable> result) { var assignment = (SetField)operation; result.AddUsage(assignment.Instance); result.AddUsage(assignment.Right); }
static void HandleReadArrayItem(LocalOperation operation, CodeOutput bodySb, MethodInterpreter interpreter, ClosureEntities closureEntities) { var valueSrc = (GetArrayElement)operation; var parentType = valueSrc.Instance.ComputedType(); var variableData = interpreter.AnalyzeProperties.GetVariableData(valueSrc.AssignedTo); switch (variableData) { case EscapingMode.Smart: bodySb.AppendFormat( (parentType.GetClrType(closureEntities).IsClass || parentType.GetClrType(closureEntities).IsInterface) ? "{0} = (*{1})[{2}];" : "{0} = {1}[{2}];", valueSrc.AssignedTo.Name, valueSrc.Instance.Name, valueSrc.Index.Name); return; case EscapingMode.Pointer: bodySb.AppendFormat( (parentType.GetClrType(closureEntities).IsClass || parentType.GetClrType(closureEntities).IsInterface) ? "{0} = ((*{1})[{2}]).get();" : "{0} = ({1}[{2}]).get();", valueSrc.AssignedTo.Name, valueSrc.Instance.Name, valueSrc.Index.Name); return; } }
protected static ConstValue GetConstantFromOperation(LocalOperation srcOperation, out Assignment srcVariableDefinition) { srcVariableDefinition = null; return(srcOperation.Kind != OperationKind.Assignment ? null : ConstantFromOperation(out srcVariableDefinition, srcOperation)); }
private static void SwitchUsageClones(Dictionary <LocalVariable, IdentifierValue> mappedNames, LocalOperation clone) { foreach (var localVariable in mappedNames) { clone.SwitchUsageWithDefinition(localVariable.Key, localVariable.Value); } }
private static void HandleDerefAssignment(LocalOperation operation, StringBuilder bodySb) { var assign = (DerefAssignment)operation; var leftData = (IdentifierValue)assign.Left; var rightData = (IdentifierValue)assign.Right; bodySb.AppendFormat("{0} = *{1};", leftData.Name, rightData.Name); }
private static void HandleSizeOf(LocalOperation operation, StringBuilder bodySb) { var assign = (SizeOfAssignment)operation; var leftData = (IdentifierValue)assign.AssignedTo; var rightData = assign.Right.ToCppName(); bodySb.AppendFormat("{0} = sizeof({1});", leftData.Name, rightData); }
static void HandleRefAssignment(LocalOperation operation, CodeOutput bodySb) { var assign = (RefAssignment)operation; var leftData = (IdentifierValue)assign.Left; var rightData = (IdentifierValue)assign.Right; bodySb.AppendFormat("{0} = &{1};", leftData.Name, rightData.Name); }
private static void HandleRefAssignment(LocalVariable localVariable, HashSet <LocalVariable> candidateVariables, LocalOperation op) { var value = (RefAssignment)op.Value; candidateVariables.Remove(localVariable); candidateVariables.Remove(value.Right); }
private static void HandleSetField(LocalOperation operation, StringBuilder bodySb) { var assign = (Assignment)operation.Value; var fieldSetter = (FieldSetter)assign.AssignedTo; bodySb.AppendFormat("{0}->{1} = {2};", fieldSetter.Instance.Name, fieldSetter.FieldName.ValidName(), assign.Right.Name); }
private void FoldAssign(IdentifierValue constResult, LocalOperation[] localOperations, int pos) { localOperations[pos] = new LocalOperation() { Kind = OperationKind.Assignment, Value = constResult }; }
private static void AddUsagesOfGetArrayItem(LocalOperation operation, List <LocalVariable> result) { var assignment = (Assignment)operation.Value; var arrayVar = (ArrayVariable)assignment.Right; result.AddUsage(arrayVar.Parent); result.AddUsage(arrayVar.Index); }
public void AddOperation(LocalOperation operation) { _localSequence.Add(operation); }