public void SimpleTest()
        {
            RegisterNode[] firstUsed = {};
            RegisterNode[] firstDef  = { x };
            Instruction    firstIns  = new Instruction(instructionBuilder,
                                                       firstUsed, firstDef);

            RegisterNode[] secondUsed = {};
            RegisterNode[] secondDef  = { y };
            Instruction    secondIns  = new Instruction(instructionBuilder,
                                                        secondUsed, secondDef);

            RegisterNode[] thirdUsed = { x, y };
            RegisterNode[] thirdDef  = {};
            Instruction    thirdIns  = new Instruction(instructionBuilder,
                                                       thirdUsed, thirdDef);
            LivenessAnalysis aL = new LivenessAnalysis();

            Instruction[] instructions = { firstIns, secondIns, thirdIns };
            var           result       = aL.AnalyzeLiveness(instructions);

            Assert.AreEqual(2, result.Vertices.Count);
            Assert.AreEqual(1, result.Vertices [0].NonCopyNeighbors.Count);

            ICollection <string> temp = new HashSet <string>();

            if (result.Vertices [0].Register.Id.CompareTo("x") == 0)
            {
                temp.Add("y");
            }
            else
            {
                temp.Add("x");
            }
            foreach (var v in result.Vertices[0].NonCopyNeighbors)
            {
                Assert.IsTrue(temp.Contains(v.Register.Id));
            }

            temp.Clear();

            if (result.Vertices [1].Register.Id.CompareTo("x") == 0)
            {
                temp.Add("y");
            }
            else
            {
                temp.Add("x");
            }
            foreach (var v in result.Vertices[1].NonCopyNeighbors)
            {
                Assert.IsTrue(temp.Contains(v.Register.Id));
            }
        }
Exemplo n.º 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 LabelJumpTest()
        {
            RegisterNode[] used     = {};
            RegisterNode[] def      = {};
            Instruction    firstIns = Instruction.JumpInstruction(instructionBuilder, used, def,
                                                                  "third");
            Instruction secondIns = new Instruction(instructionBuilder,
                                                    used, def);
            Instruction thirdIns = Instruction.LabelInstruction(instructionBuilder,
                                                                "third");
            LivenessAnalysis aL = new LivenessAnalysis();

            Instruction[] instructions = { firstIns, secondIns, thirdIns };
            aL.AnalyzeLiveness(instructions);

            Assert.AreEqual(0, firstIns.PrevInstructions.Count);
            Assert.AreEqual(1, secondIns.PrevInstructions.Count);
            Assert.AreEqual(2, thirdIns.PrevInstructions.Count);
        }
        public void SimpleTest2()
        {
            RegisterNode[] firstUsed = {};
            RegisterNode[] firstDef  = { x, y };
            Instruction    firstIns  = new Instruction(instructionBuilder,
                                                       firstUsed, firstDef);

            RegisterNode[] secondUsed = { x };
            RegisterNode[] secondDef  = {};
            Instruction    secondIns  = new Instruction(instructionBuilder,
                                                        secondUsed, secondDef);
            LivenessAnalysis aL = new LivenessAnalysis();

            Instruction[] instructions = { firstIns, secondIns };
            var           result       = aL.AnalyzeLiveness(instructions);

            Assert.AreEqual(2, result.Vertices.Count);
            Assert.AreEqual(0, result.Vertices [0].NonCopyNeighbors.Count);
            Assert.AreEqual(0, result.Vertices [0].CopyNeighbors.Count);
            Assert.AreEqual(0, result.Vertices [1].NonCopyNeighbors.Count);
            Assert.AreEqual(0, result.Vertices [1].CopyNeighbors.Count);
        }