public static MethodInterpreter CreateLinkerFromEntryPoint(this MethodInfo definition, ProgramClosure programClosure) { var methodInterpreter = definition.Register(); MetaLinker.Interpret(methodInterpreter, programClosure.Runtime); OptimizeMethods(LinkerInterpretersTable.Methods); var foundMethodCount = 1; var canContinue = true; while (canContinue) { var dependencies = methodInterpreter.GetMethodClosure(programClosure.Runtime); canContinue = foundMethodCount != dependencies.Count; foundMethodCount = dependencies.Count; foreach (var interpreter in dependencies) { MetaLinker.Interpret(interpreter, programClosure.Runtime); } OptimizeMethods(LinkerInterpretersTable.Methods); } return(methodInterpreter); }
public static HashSet <Type> GetTypesClosure(List <MethodInterpreter> methodList, out bool foundNewMethods, ProgramClosure programClosure, CrRuntimeLibrary crRuntime) { var typesSet = ScanMethodParameters(methodList, crRuntime); foundNewMethods = false; var resultTypes = BuildScannedDictionaryFromTypesAndInstructions(typesSet, crRuntime); var methodDict = methodList.ToDictionary(method => method.Method.Register(crRuntime).ToKey()); var virtMethods = methodList.Where(m => m.Method.IsVirtual).ToArray(); foreach (var virt in virtMethods) { var baseClass = virt.Method.DeclaringType; var methodName = virt.Method.Name; var methodArgs = virt.Method.GetParameters().Select(par => par.ParameterType).ToArray(); foreach (var type in resultTypes) { if (!type.IsSubclassOf(baseClass)) { continue; } var implMethod = type.GetMethod(methodName, methodArgs); if (methodDict.ContainsKey(implMethod.Register(crRuntime).ToKey())) { continue; } var implInterpreter = implMethod.Register(); MetaLinker.Interpret(implInterpreter, crRuntime); methodList.Add(implInterpreter); foundNewMethods = true; } } return(resultTypes); }
public bool Optimize(ProgramClosure program) { var result = false; foreach (var optimization in Optimizations) { result |= optimization.Optimize(program); } return(result); }
protected override void DoOptimize(ProgramClosure closure) { var methodInterpreters = closure.MethodClosure.Values .Where(m => m.Kind == MethodKind.Default) .ToList(); foreach (var interpreter in methodInterpreters) { HandleInterpreterInstructions(interpreter, methodInterpreters, closure.UsedTypes); } }
public static MethodInterpreterKey ToKey(this MethodBase methodbase, ProgramClosure closure) { foreach (var m in closure.MethodClosure) { if (m.Value.Method == methodbase) { return(m.Key); } } return(null); }
public override bool Optimize(ProgramClosure closure) { try { DoOptimize(closure); } catch { return(false); } return(Result); }
public static ClosureResult BuildClosureForEntry(MethodInterpreter entryInterpreter, ProgramClosure programClosure) { var result = new ClosureResult(); var methodInterpreters = new Dictionary <MethodInterpreterKey, MethodInterpreter>(); methodInterpreters.Clear(); methodInterpreters[entryInterpreter.ToKey()] = entryInterpreter; MetaLinker.Interpret(entryInterpreter, programClosure.Runtime); var canContinue = true; var dependencies = entryInterpreter.GetMethodClosure(programClosure.Runtime); while (canContinue) { foreach (var interpreter in dependencies) { MetaLinker.Interpret(interpreter, programClosure.Runtime); } foreach (var dependency in dependencies) { methodInterpreters[dependency.ToKey()] = dependency; } result.MethodInterpreters = methodInterpreters; var foundMethodCount = methodInterpreters.Count; dependencies = methodInterpreters.Values.ToList(); bool foundNewMethods; result.UsedTypes = new HashSet <Type>(GetTypesClosure(dependencies, out foundNewMethods, programClosure, programClosure.Runtime)); foreach (var dependency in dependencies) { methodInterpreters[dependency.ToKey()] = dependency; } foreach (var interpreter in methodInterpreters.Values) { interpreter.Process(programClosure.Runtime); } dependencies = methodInterpreters.Values.ToList().GetMultiMethodsClosure(programClosure.Runtime); canContinue = foundMethodCount != dependencies.Count; } return(result); }
protected override void DoOptimize(ProgramClosure closure) { var methodInterpreters = closure.MethodClosure.Values .Where(m => m.Kind == MethodKind.Default) .ToList(); var updateHappen = false; foreach (var interpreter in methodInterpreters) { updateHappen |= HandleInterpreterInstructions(interpreter); } if (!updateHappen) { return; } var parametersDatas = methodInterpreters .Select(ConstantParametersData.GetInterpreterData) .ToList(); for (var index = 0; index < methodInterpreters.Count; index++) { var interpreter = methodInterpreters[index]; var parametersData = parametersDatas[index]; if (!parametersData.ConstKinds.ContainsValue(ConstantParametersData.ConstValueKind.AssignedConstant)) { continue; } foreach (var constKind in parametersData.ConstKinds) { if (constKind.Value != ConstantParametersData.ConstValueKind.AssignedConstant) { continue; } var assignedConstant = parametersData.ConstValues[constKind.Key]; interpreter.SwitchAllUsagesWithDefinition(constKind.Key, assignedConstant); interpreter.AnalyzeProperties.SetVariableData(constKind.Key, EscapingMode.Unused); Result = true; } } }
public static void CallCompiler(string inputAssemblyName, string outputExeName) { var commandLineParse = CommandLineParse.Instance; if (!String.IsNullOrEmpty(inputAssemblyName)) { commandLineParse.ApplicationInputAssembly = inputAssemblyName; } if (!String.IsNullOrEmpty(outputExeName)) { commandLineParse.ApplicationNativeExe = outputExeName; commandLineParse.OutputCpp = Path.ChangeExtension(commandLineParse.ApplicationNativeExe, ".cpp"); } var dir = Directory.GetCurrentDirectory(); inputAssemblyName = Path.Combine(dir, commandLineParse.ApplicationInputAssembly); var asm = Assembly.LoadFile(inputAssemblyName); var definition = asm.EntryPoint; var start = Environment.TickCount; var optimizationsTable = new ProgramOptimizationsTable(); optimizationsTable.Add(new DevirtualizerIfOneImplemetor()); optimizationsTable.Add(new CallToFunctionsWithSameConstant()); var crRuntime = new CrRuntimeLibrary(); crRuntime.ScanAssembly(typeof(CrString).Assembly); var programClosure = new ProgramClosure(definition, crRuntime); var sb = programClosure.BuildFullSourceCode(programClosure.Runtime); var end = Environment.TickCount - start; Console.WriteLine("Compilation time: {0} ms", end); sb.ToFile(commandLineParse.OutputCpp); NativeCompilationUtils.CompileAppToNativeExe(commandLineParse.OutputCpp, commandLineParse.ApplicationNativeExe); }
public abstract bool Optimize(ProgramClosure closure);
protected abstract void DoOptimize(ProgramClosure closure);
public static HashSet <Type> GetTypesClosure(List <MethodInterpreter> methodList, out bool foundNewMethods, ProgramClosure programClosure, CrRuntimeLibrary crRuntime) { var typesSet = ScanMethodParameters(methodList, crRuntime); //For struct types we need to add them separately foreach (var methodInterpreter in methodList) { foreach (var operation in methodInterpreter.MidRepresentation.LocalOperations) { if (operation is Assignment) { var type = (operation as Assignment).AssignedTo.FixedType.ClrType; if (!typesSet.Contains(type) && !type.IsByRef) { typesSet.Add(type); } } if (operation is RefAssignment) { var type = (operation as RefAssignment).Left.FixedType.ClrType; if (!typesSet.Contains(type) && !type.IsByRef) { typesSet.Add(type); } } } } foundNewMethods = false; var resultTypes = BuildScannedDictionaryFromTypesAndInstructions(typesSet, crRuntime); var methodDict = methodList.ToDictionary(method => method.Method.Register(crRuntime).ToKey()); var virtMethods = methodList.Where(m => m.Method.IsVirtual).ToArray(); foreach (var virt in virtMethods) { var baseClass = virt.Method.DeclaringType; var methodName = virt.Method.Name; var methodArgs = virt.Method.GetParameters().Select(par => par.ParameterType).ToArray(); foreach (var type in resultTypes) { var hasinterface = false;//TODO: for some reason I cannot use .Contains / Linq here ? foreach (var @interface in type.GetInterfaces()) { if (@interface == baseClass) { hasinterface = true; // methodName = baseClass.Name +"."+methodName; break; } } if ((!(type.IsSubclassOf(baseClass) || hasinterface))) { continue; } MethodInfo implMethod; if (!hasinterface) { implMethod = type.GetMethod(methodName, methodArgs); } else { implMethod = type.GetInterfaceMap(baseClass) .InterfaceMethods.Where(m => m.Name == methodName && (!m.GetParameters().Select(j => j.ParameterType).Except(methodArgs).Any())).FirstOrDefault(); } if (methodDict.ContainsKey(implMethod.Register(crRuntime).ToKey())) { continue; } var implInterpreter = implMethod.Register(); MetaLinker.Interpret(implInterpreter, crRuntime); methodList.Add(implInterpreter); foundNewMethods = true; } } return(resultTypes); }