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); }
/// <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(); }
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]; }
/// <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(); } }
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; } }
public void Initialize(IRTransformer tr) { allocator = new RegisterAllocator(tr); allocator.Initialize(); tr.Annotations[RegAllocatorKey] = allocator; }