public bool Repeat(DILOperationSet operations, int offset) { int delta = Scalar, totalOperationsCovered = 1; for (int j = offset + 1; j < operations.Count; j++) // - i ? { var instruction = operations[j] as AdditionMemoryOp; if (instruction == null) { break; } if (instruction.Offset != Offset) { break; } totalOperationsCovered++; delta += instruction.Scalar; } if (totalOperationsCovered > 1) { operations.RemoveRange(offset, totalOperationsCovered); operations.Insert(offset, new AdditionMemoryOp(Offset, delta)); return true; } return false; }
public bool Repeat(DILOperationSet operations, int offset) { int ptrDelta = Delta, totalPtrsCovered = 1; for (int j = offset + 1; j < operations.Count; j++) { var instruction = operations[j] as PtrOp; if (instruction == null) { break; } ptrDelta += instruction.Delta; totalPtrsCovered++; } if (totalPtrsCovered > 1) { operations.RemoveRange(offset, totalPtrsCovered); operations.Insert(offset, new PtrOp(ptrDelta)); return true; } return false; }
public void Run(DILOperationSet operations) { int ptr = Ptr; // since you can't pass a Property by reference... foreach (var instruction in operations) { var interpretableInstruction = instruction as IInterpretable; if (interpretableInstruction != null) { interpretableInstruction.Interpret(Domain, ref ptr); Ptr = ptr; } else { throw new Exception("Why isn't this instruction interpretable?"); } } }
/// <summary> /// TODO: https://github.com/dreasgrech/yabfcompiler/issues/11 /// Do not emit the array and the pointer variables if they're not needed. /// </summary> private string CompileToExecutable(DILOperationSet operations, string filename) { var assembly = CreateAssemblyAndEntryPoint(filename); ILGenerator ilg = assembly.MainMethod.GetILGenerator(); LocalBuilder array = ilg.CreateArray<byte>(DomainSize); LocalBuilder ptr = null; // Do not emit the pointer variable if it's not needed. if (operations.ContainsPointerOperations()) { ptr = ilg.DeclareIntegerVariable(); } foreach (var dilInstruction in operations) { dilInstruction.Emit(ilg, array, ptr); } ilg.Emit(OpCodes.Ret); Type t = assembly.MainClass.CreateType(); assembly.DynamicAssembly.SetEntryPoint(assembly.MainMethod, PEFileKinds.ConsoleApplication); var compiledAssemblyFile = String.Format("{0}.exe", Path.GetFileNameWithoutExtension(filename)); assembly.DynamicAssembly.Save(compiledAssemblyFile); return compiledAssemblyFile; }
/// <summary> /// Returns the location of the compiled assembly /// </summary> /// <returns></returns> public string Compile(string filename) { var instructions = Parser.GenerateDIL(File.ReadAllText(filename)).ToArray(); LanguageInstruction? areLoopOperationsBalanced; if ((areLoopOperationsBalanced = AreLoopOperationsBalanced(instructions)) != null) { throw new InstructionNotFoundException(String.Format("Expected to find an {0} instruction but didn't.", (~areLoopOperationsBalanced.Value).ToString())); } var dilInstructions = new DILOperationSet(instructions); // If we're not in debug mode, optimize the shit out of it! if (!OptionEnabled(CompilationOptions.DebugMode)) { while (dilInstructions.Optimize(ref dilInstructions)) { } } //var interpreter = new Interpreter(30000); //interpreter.Run(dilInstructions); return CompileToExecutable(dilInstructions, filename); }
/// <summary> /// A simple loop is a loop which, when ignoring nested loops, the pointer returns to the initial position of the loop after execution /// /// A nested loop also doesn't contain any IO. /// /// This method needs to be changed to an instance method /// </summary> /// <param name="operations"></param> /// <returns></returns> public static bool IsSimple(DILOperationSet operations) { return new CodeWalker().Walk(operations).EndPtrPosition == 0 && !ContainsIO(operations); }
/// <summary> /// This method needs to be changed to an instance method /// </summary> /// <param name="operations"></param> /// <returns></returns> public static bool ContainsIO(DILOperationSet operations) { return operations.Any(o => o is WriteOp || o is ReadOp); }
public LoopOp(DILOperationSet instructions) { Instructions = instructions; NestedLoops = Instructions.OfType<LoopOp>().ToList(); }
public LoopUnrollingResults Unroll() { var unrolled = new DILOperationSet(); //if (IsClearanceLoop()) //{ // unrolled.Add(new AssignOp(0, 0)); // return new LoopUnrollingResults(unrolled, true); //} var withUnrolledNestLoops = new DILOperationSet(); foreach (var instruction in Instructions) { if (instruction is LoopOp) { var nestedLoop = instruction as LoopOp; var ur = nestedLoop.Unroll(); if (ur.WasLoopUnrolled) { withUnrolledNestLoops.AddRange(ur.UnrolledInstructions); } else { withUnrolledNestLoops.Add(new LoopOp(ur.UnrolledInstructions)); } } else { withUnrolledNestLoops.Add(instruction); } } if (IsSimple(withUnrolledNestLoops)) { var walk = new CodeWalker().Walk(withUnrolledNestLoops); if (walk.Domain.ContainsKey(0) && walk.Domain[0] == -1) { foreach (var cell in walk.Domain) { if (cell.Key == 0) { continue; } //// If the scalar value of the multiplication operation is 0, //// then simply assign 0 to the cell because n * 0 = 0. //if (cell.Value == 0) //{ // unrolled.Add(new AssignOp(cell.Key, 0)); //} //else //{ unrolled.Add(new MultiplicationMemoryOp(cell.Key, cell.Value)); //} } // If it's a simple loop, then the cell position of the loop should always be assigned a 0 since that's when the loop stops. if (walk.Domain.ContainsKey(0)) { unrolled.Add(new AssignOp(0, 0)); } return new LoopUnrollingResults(unrolled, true); } else { return new LoopUnrollingResults(withUnrolledNestLoops, false); } } return new LoopUnrollingResults(withUnrolledNestLoops, false); }
public bool Repeat(DILOperationSet operations, int offset) { int repeated = Repeated, totalOperationsCovered = 1; for (int i = offset + 1; i < operations.Count; i++) { var instruction = operations[i] as WriteOp; if (instruction == null) { break; } if (instruction.Offset != Offset) { break; } repeated += instruction.Repeated; totalOperationsCovered++; } if (totalOperationsCovered > 1) { operations.RemoveRange(offset, totalOperationsCovered); operations.Insert(offset, new WriteOp(Offset, repeated)); return true; } return false; }
public LoopUnrollingResults(DILOperationSet operations, bool wasLoopUnrolled) { UnrolledInstructions = operations; WasLoopUnrolled = wasLoopUnrolled; }
public bool Repeat(DILOperationSet operations, int offset) { var totalOperationsCovered = 1; for (int j = offset + 1; j < operations.Count; j++) { var instruction = operations[j] as AssignOp; if (instruction == null) { break; } if (instruction.Offset != Offset) { break; } if (instruction.Value != Value) { break; } totalOperationsCovered++; } if (totalOperationsCovered > 1) { operations.RemoveRange(offset, totalOperationsCovered); operations.Insert(offset, new AssignOp(Offset, Value)); return true; } return false; }