public void SmallColorableGraph() { var registers = new List <HardwareRegisterNode> (); registers.Add(new HardwareRegisterNode("a")); registers.Add(new HardwareRegisterNode("b")); var v1 = new Vertex(registers [1]); var v2 = new Vertex(new TemporaryNode()); var v3 = new Vertex(new TemporaryNode()); var v4 = new Vertex(registers [0]); v1.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v4, v2 })); v2.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v1, v3 })); v3.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v2, v4 })); v4.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v3, v1 })); var graph = new InterferenceGraph(new List <Vertex> (new Vertex[4] { v1, v2, v3, v4 })); var allocator = new RegisterAllocator(registers); allocator.AllocateRegisters(graph); Assert.AreEqual(IsValid(graph, allocator.RegistersColoring), true); Assert.IsEmpty(allocator.SpilledRegisters); }
/// <summary> /// Construct trace for each function and then in a loop: /// - generate the whole body of the function /// - select instructions /// - analyze liveness /// - allocate registers. /// Loop untill success or MAX_ALLOC_TRY. After success - generate nasm. /// </summary> /// <returns>sequence of nasm instructions</returns> /// <param name="funcList">List of backend functions created by frontend.</param> public IEnumerable <string> FromFunctionsToNasm(IEnumerable <Function> funcList) { foreach (var f in funcList) { f.Body = TraceBuilder.BuildTrace(f.Body.First()); } var livenessAnalyzer = new LivenessAnalysis(); var regAllocator = new RegisterAllocator(Target.AllHardwareRegisters); var output = new List <string>(); foreach (var f in funcList) { int tryCount = 0; IEnumerable <Instruction> fInstr; while (true) { if (tryCount == MAX_ALLOC_TRY) { throw new ArgumentException("Your input is stupid... (or our compiler)."); } var fBody = f.GenerateTheWholeBody(); fInstr = InstructionSelection.SelectInstructions(fBody); var inGraph = livenessAnalyzer.AnalyzeLiveness(fInstr); regAllocator.AllocateRegisters(inGraph); var toCorrect = regAllocator.SpilledRegisters; if (toCorrect.Any()) { // apply changes f.MoveRegistersToMemory(toCorrect); } else { // success break; } tryCount++; } // use regAllocator.RegistersColoring to produce nasm var regMapping = regAllocator.RegistersColoring; foreach (var instr in fInstr) { output.Add(instr.ToString(regMapping)); } output.Add("\n"); } return(output); }
public void SpillNeeded() { var registers = new List <HardwareRegisterNode> (); registers.Add(new HardwareRegisterNode("a")); registers.Add(new HardwareRegisterNode("b")); var v1 = new Vertex(new TemporaryNode()); var v2 = new Vertex(new TemporaryNode()); var v3 = new Vertex(new TemporaryNode()); v1.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v3, v2 })); v2.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v1, v3 })); v3.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v2, v1 })); var graph = new InterferenceGraph(new List <Vertex> (new Vertex[3] { v1, v2, v3 })); var allocator = new RegisterAllocator(registers); allocator.AllocateRegisters(graph); Assert.AreEqual(allocator.SpilledRegisters.Count, 1); }
public void NonTrivialThreeColorableGraph() { var registers = new List <HardwareRegisterNode> (); registers.Add(new HardwareRegisterNode("a")); registers.Add(new HardwareRegisterNode("b")); registers.Add(new HardwareRegisterNode("c")); var v1 = new Vertex(new TemporaryNode()); var v2 = new Vertex(new TemporaryNode()); var v3 = new Vertex(new TemporaryNode()); var v4 = new Vertex(new TemporaryNode()); var v5 = new Vertex(new TemporaryNode()); var v6 = new Vertex(new TemporaryNode()); var v7 = new Vertex(registers[1]); var v8 = new Vertex(new TemporaryNode()); var v9 = new Vertex(new TemporaryNode()); v1.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v2, v3 })); v2.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v1, v3 })); v3.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v1, v2 })); v4.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v5, v6 })); v5.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v4, v6 })); v6.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v4, v5 })); v7.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v3, v4 })); v8.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v7, v9 })); v9.NonCopyNeighbors.UnionWith(new HashSet <Vertex> (new Vertex[] { v7, v8 })); var graph = new InterferenceGraph(new List <Vertex> (new Vertex[9] { v1, v2, v3, v4, v5, v6, v7, v8, v9 })); var allocator = new RegisterAllocator(registers); allocator.AllocateRegisters(graph); Assert.AreEqual(IsValid(graph, allocator.RegistersColoring), true); Assert.IsEmpty(allocator.SpilledRegisters); }
public void Parse(string input, string[] compilerOptions) { string fileName = Path.GetFileNameWithoutExtension(compilerOptions[0]); ParseCompilerOptions(compilerOptions); AntlrInputStream inputStream = new AntlrInputStream(input); MiniJavaLexer miniJavaLexer = new MiniJavaLexer(inputStream); CommonTokenStream commonTokenStream = new CommonTokenStream(miniJavaLexer); MiniJavaParser miniJavaParser = new MiniJavaParser(commonTokenStream); miniJavaParser.AddErrorListener(ErrorListener.INSTANCE); var cst = miniJavaParser.prg(); if (ErrorListener.INSTANCE.errorCounter > 0) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Sorry this is all my fault :("); } else { // Generate AST // var ast = cst.ToAst(); // Type Checking // TypeChecker typeChecker = new TypeChecker(); typeChecker.InitTypeChecking(ast); typeChecker.StartTypeChecking(ast); // Convert to intermediate // IntermediateAstBuilder intermediate = new IntermediateAstBuilder(); var interTree = intermediate.BuildIntermediateAst(ast); var canonizedTree = new Canonizer().CanonPrg((TreePrg)interTree); // assembly // I386CodeGenerator codeGenerator = new I386CodeGenerator(); var i386Prg = (I386Prg)codeGenerator.CodeGen(canonizedTree); if (WithoutAlloc) { File.WriteAllText(fileName + "_noallocs.s", i386Prg.RenderAssembly()); } // Liveness analysis // RegisterAllocator registerAllocator = new RegisterAllocator(); registerAllocator.AllocateRegisters(i386Prg, codeGenerator.GetGeneralPurposeRegisters()); Afterburner afterburner = new Afterburner(); afterburner.RemoveRedundancies(i386Prg); if (Intermediate) { File.WriteAllText(fileName + ".tree", canonizedTree.ToString()); } File.WriteAllText(fileName + ".s", i386Prg.RenderAssembly()); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("You did great!"); Console.ForegroundColor = ConsoleColor.White; } }