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);
        }
示例#2
0
        /// <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);
        }
示例#5
0
        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;
            }
        }