public MultiplexerGenerator(RegisterAllocator allocator)
        {
            RegisterAllocator = allocator;

            FunctionalUnitMultiplexers = allocator.Functional.Units
                                         .Where(unit => unit.Operations.Length > 1)
                                         .Select((unit, index) => new FunctionalUnitMultiplexer
            {
                SelectionBitSize = Convert.ToInt32(Math.Ceiling(Math.Log(unit.Operations.Length, 2))),
                Op   = unit.Operations,
                Unit = unit
            })
                                         .ToArray();

            foreach (var multiplexor in FunctionalUnitMultiplexers.OrderBy(mx => mx.Name))
            {
                Log.Info(multiplexor);
            }

            RegisterUnitMultiplexers = allocator.Units
                                       .Where(unit => unit.Registers.Length > 1)
                                       .Select((unit, index) => new RegisterUnitMultiplexer
            {
                SelectionBitSize = Convert.ToInt32(Math.Ceiling(Math.Log(unit.Registers.Length, 2))),
                Registers        = unit.Registers,
                Unit             = unit
            })
                                       .ToArray();

            foreach (var multiplexor in RegisterUnitMultiplexers.OrderBy(mx => mx.Name))
            {
                Log.Info(multiplexor);
            }
        }
        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);
        }
        private void test(Func <AifFile> getFile)
        {
            TestLogger.Setup();

            var file = getFile();

            var schedule = new IlpScheduler(file, file.MinCycles.Values.Max());

            schedule.BuildSchedule();

            var registerAllocator = new RegisterAllocator(new FunctionalUnitAllocator(schedule));

            Assert.IsNotNull(registerAllocator.Units);

            var registers = registerAllocator.Units.SelectMany(unit => unit.Registers).ToArray();

            Assert.AreEqual(registers.Length, schedule.AifFile.Registers.Count);
            Assert.IsTrue(registers.All(reg => schedule.AifFile.Registers.ContainsValue(reg)));

            Assert.IsTrue(registerAllocator.Units
                          .All(unit => unit.Registers
                               .All(reg1 => unit.Registers
                                    .Where(reg2 => reg1 != reg2)
                                    .All(reg1.IsCompatible))));
        }
    public override Register GenCode()
    {
        Register targetRegister = RegisterAllocator.GetNextRegister();

        Console.WriteLine("const/16 v{0}, #int {1}", targetRegister.GetIndex(), val);
        return(targetRegister);
    }
    public override Register GenCode()
    {
        Register firstRegister  = left.GenCode();
        Register secondRegister = right.GenCode();
        Register targetRegister = RegisterAllocator.GetNextRegister();

        Console.WriteLine("add-int v{0}, v{1}, v{2}", targetRegister.GetIndex(), firstRegister.GetIndex(), secondRegister.GetIndex());
        return(targetRegister);
    }
Esempio n. 6
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);
        }
        internal void generate()
        {
            ast.translate(directTranslation);
            directTranslation.ResolveLabel();
            // directTranslation.ConstructFlowGraph();
            // directTranslation.CalculateLiveSpan();
            List <FunctionTranslation> list = new List <FunctionTranslation>();
            Dictionary <string, (SortedSet <int> s, SortedSet <int> v)> rlist =
                new Dictionary <string, (SortedSet <int> s, SortedSet <int> v)>();

            for (int i = 0; i < directTranslation.ListOfList.Count; i++)
            {
                var item = directTranslation.ListOfList[i];
                var f    = new FunctionTranslation(item, directTranslation.LabelReferences,
                                                   directTranslation.Functions[i]);
                list.Add(f);
                rlist.Add(item[0].Label, RegisterAllocator.fk(f));
            }
            foreach (var item in list)
            {
                item.CalculateLiveSpan2();
                item.ResolveCallerSave(rlist);
            }
            foreach (var item in directTranslation.FunctionStackWaiting)
            {
                int size = item.Key.StackSize;
                if (size % 4 != 0)
                {
                    size = size - (size % 4) + 4;
                }
                item.Value.Operands[2] = size.ToString();
            }
            list[0].List.AddFirst(new Assembly("s_mov", new List <string> {
                "RS2", "RS28"
            }));
            list[0].List.AddFirst(new Assembly("s_mov", new List <string> {
                "RS28", "RS29"
            }));
            foreach (var item in list)
            {
                item.ResolvePhysicalRegister();
                item.Output(Console.Out);
            }
            // directTranslation.Print();
        }
Esempio n. 8
0
        public IFunctionToAsmGenerator Generate()
        {
            var livenessAnalyzer             = new LivenessAnalyzer();
            var registerAllocator            = new RegisterAllocator();
            var instructionsTemplatesFactory = new Templates.InstructionsTemplatesFactory();
            var instructionTemplates         = instructionsTemplatesFactory.CreateInstructionTemplates();
            var instructionSelector          = new InstructionSelector.InstructionSelector(instructionTemplates);
            var cfgLinearizer      = new CfgLinearizer.CfgLinearizer();
            var labelFactory       = new LabelFactory(new LabelIdGuidGenerator());
            var readWriteGenerator = new ReadWriteGenerator();

            return(new FunctionToAsmGenerator(
                       livenessAnalyzer,
                       registerAllocator,
                       instructionSelector,
                       cfgLinearizer,
                       labelFactory,
                       readWriteGenerator));
        }
        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 Initialize(IRTransformer tr)
 {
     allocator = (RegisterAllocator)tr.Annotations[RegisterAllocationTransform.RegAllocatorKey];
 }
Esempio n. 12
0
 /// <summary>
 /// Frees the allocated predicate register.
 /// </summary>
 public void Dispose() =>
 // Release the predicate register
 RegisterAllocator?.FreeRegister(PredicateRegister);
        public static void Main(string[] args)
        {
            StreamWriter controller = null, dataPath = null, design = null, testBench = null;

            try
            {
                string fileName;
                var    file = GetAifFile(out fileName);
                if (file == null)
                {
                    return;
                }

                //1. Operation Scheduling:
                var schedule = GetSchedule(file);
                if (schedule == null)
                {
                    return;
                }

                //2. Functional Unit Allocation and Binding:
                var functionalUnits = new FunctionalUnitAllocator(schedule);

                //3. Register Allocation and Binding
                var registers = new RegisterAllocator(functionalUnits);

                //4. Multiplexer Generation:
                var multiplexorGenerator = new MultiplexerGenerator(registers);

                //5. Datapath Generation in VHDL:
                var dataPathGenerator = new DataPathGenerator(multiplexorGenerator);

                //6. Get test cases
                Console.ForegroundColor = ConsoleColor.Green;
                foreach (var expression in file.AsExpressions)
                {
                    Console.WriteLine(expression);
                }
                var testCases = GetTestCases(dataPathGenerator).ToArray();

                var saveFolder = GetSaveTo();
                if (saveFolder == null)
                {
                    return;
                }

                //save generation
                dataPath = GetSaveStream(Path.Combine(saveFolder, fileName + "_dp.vhd"));
                if (dataPath == null)
                {
                    return;
                }
                controller = GetSaveStream(Path.Combine(saveFolder, fileName + "_con.vhd"));
                if (controller == null)
                {
                    return;
                }
                design = GetSaveStream(Path.Combine(saveFolder, fileName + "_des.vhd"));
                if (design == null)
                {
                    return;
                }
                if (testCases.Length > 0)
                {
                    testBench = GetSaveStream(Path.Combine(saveFolder, fileName + "_tb.vhd"));
                    if (testBench == null)
                    {
                        return;
                    }
                }

                using (controller)
                {
                    dataPathGenerator.SaveController(controller);
                }

                foreach (var codeFile in functionalUnits.Units
                         .Select(unit => unit.VhdlCodeFile)
                         .Concat(new []
                {
                    "c_multiplexer",
                    "c_register"
                })
                         .Distinct(StringComparer.OrdinalIgnoreCase))
                {
                    var savePath = Path.Combine(saveFolder, codeFile + ".vhd");
                    if (!File.Exists(savePath))
                    {
                        using (var stream = File.CreateText(savePath))
                        {
                            stream.WriteVhdlFile(codeFile);
                        }
                    }
                }
                using (dataPath)
                {
                    dataPathGenerator.SaveDataPath(dataPath);
                }
                using (design)
                {
                    dataPathGenerator.SaveDesign(design);
                }
                if (testCases.Length > 0)
                {
                    using (testBench)
                    {
                        dataPathGenerator.SaveTestBench(testBench, testCases);
                    }
                }

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Press enter to exit.");
                Console.ReadLine();
            }
            catch (Exception error)
            {
                Log.Error(error);

                dataPath?.Dispose();
                design?.Dispose();
                controller?.Dispose();
                testBench?.Dispose();
            }
        }
Esempio n. 14
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;
            }
        }
Esempio n. 15
0
 public void Initialize(IRTransformer tr)
 {
     allocator = new RegisterAllocator(tr);
     allocator.Initialize();
     tr.Annotations[RegAllocatorKey] = allocator;
 }