/// <summary> /// Создает команду - IfGoto (переход по условию) /// </summary> /// <param name="Condition"></param> /// <returns></returns> private IfGoto IfGotoC(Expr Condition) { var C = new IfGoto(); C.Condition = Condition; C.TargetLabel = new Guid(); C.IsLabeled = true; return(C); }
public MIPS Visitor(IfGoto instance, IFunctionCil function, GenerateToCil cil) { var lines = new List <string>(Utils.AcomodarVariables(instance.VarCil, function)) { $"beq $t1, 1, {instance.LabelCil.Name}" //salta condicionalmente }; return(new MIPS() { Functions = lines }); }
public void ReachingExpressionsTest1() { var taCode = new TACode(); //TAC выглядит следующим образом /** * 0) t0 = 3 | * 1) t1 = 5 + t0 | B1 * 2) t2 = t1 + t0 | * * * 3) t3 = 4 + t2 | * 4) t1 = 10 | B2 * 5) if (1) goto 3) | * * * 6) t4 = t1 + 5 | * 7) t5 = t3 + t0 | * 8) t0 = 100 | B3 * 9) if (2) goto 6) | * * * 10) t6 = t5 + 10 | * 11) t7 = t6 + 10 | * 12) t8 = t6 + t7 | B4 * 13) t6 = 3 | * 14) t5 = 100 | * **/ var ass1 = new Assign { Operation = OpCode.Plus, Right = new IntConst(3), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(5), Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass3 = new Assign { Left = ass2.Result, Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass4 = new Assign { Left = new IntConst(4), Operation = OpCode.Plus, Right = ass3.Result, Result = new Var() }; var ass5 = new Assign { Operation = OpCode.Plus, Right = new IntConst(10), Result = ass2.Result }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass4.Label }; ass4.IsLabeled = true; var ass6 = new Assign { Left = ass2.Result, Operation = OpCode.Plus, Right = new IntConst(5), Result = new Var() }; var ass7 = new Assign { Left = ass4.Result, Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass8 = new Assign { Operation = OpCode.Plus, Right = new IntConst(100), Result = ass1.Result }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass6.Label }; ass6.IsLabeled = true; var ass9 = new Assign { Left = ass7.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var() }; var ass10 = new Assign { Left = ass9.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var() }; var ass11 = new Assign { Left = ass9.Result, Operation = OpCode.Plus, Right = ass10.Result, Result = new Var() }; var ass12 = new Assign { Operation = OpCode.Plus, Right = new IntConst(3), Result = ass9.Result }; var ass13 = new Assign { Operation = OpCode.Plus, Right = new IntConst(100), Result = ass7.Result }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ass4); taCode.AddNode(ass5); taCode.AddNode(ifgt1); taCode.AddNode(ass6); taCode.AddNode(ass7); taCode.AddNode(ass8); taCode.AddNode(ifgt2); taCode.AddNode(ass9); taCode.AddNode(ass10); taCode.AddNode(ass11); taCode.AddNode(ass12); taCode.AddNode(ass13); /** CFG имеет следующий вид * * B1 * | * | ____ * v / \ * B2-v______| * | * | ____ * v / \ * B3-v______| * | * | * V * B4 * */ var cfg = new ControlFlowGraph(taCode); /**************************Reaching definition test*************************/ var op = new Operations(taCode); var algo = new IterativeAlgorithm(); var transFunc = new TransferFunction(taCode); var inout = algo.Analyze(cfg, op, transFunc); //Тестирование множест e_gen и e_kill для каждого базового блока var(e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(0)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass2.Label, ass3.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass4.Label, ass6.Label, ass7.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(1)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass4.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass3.Label, ass6.Label, ass7.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(2)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass6.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass2.Label, ass3.Label, ass7.Label, ass9.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(3)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass9.Label, ass10.Label, ass11.Label })); //Текстирование IN/OUT множеств для каждого ББл var trueInOut = new DFA.InOutData <HashSet <System.Guid> >(); trueInOut.Add(cfg.CFGNodes.ElementAt(0), (new HashSet <Guid>(), new HashSet <Guid> { ass2.Label, ass3.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(1), (new HashSet <Guid> { ass2.Label, ass3.Label }, new HashSet <Guid> { ass2.Label, ass4.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(2), (new HashSet <Guid> { ass2.Label, ass4.Label }, new HashSet <Guid> { ass4.Label, ass6.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(3), (new HashSet <Guid> { ass4.Label, ass6.Label }, new HashSet <Guid> { ass4.Label, ass6.Label }) ); foreach (var x in cfg.CFGNodes) { HashSet <Guid> toutItem1 = trueInOut[x].Item1; HashSet <Guid> outItem1 = inout[x].Item1; HashSet <Guid> toutItem2 = trueInOut[x].Item2; HashSet <Guid> outItem2 = inout[x].Item2; var inEq = toutItem1.SetEquals(outItem1); var outEq = toutItem2.SetEquals(outItem2); Assert.True(inEq && outEq); } }
private TACode GetTestGraph1() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(2), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Minus, Right = new IntConst(1), Result = new Var() }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass3.Label }; ass3.IsLabeled = true; var ass4 = new Assign { Left = ass3.Result, Operation = OpCode.Plus, Right = new IntConst(1999), Result = new Var() }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass2.Label }; ass2.IsLabeled = true; var ass5 = new Assign { Left = new IntConst(7), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass6 = new Assign { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(25), Result = new Var() }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ifgt1); taCode.AddNode(ass4); taCode.AddNode(ifgt2); taCode.AddNode(ass5); taCode.AddNode(ass6); return(taCode); }
public void ReachingDefenitionTest0() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(1000), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(2000), Operation = OpCode.Copy, Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Copy, Right = new IntConst(3000), Result = new Var() }; var ass4 = new Assign { Left = ass1.Result, Operation = OpCode.Plus, Right = new IntConst(1), Result = ass1.Result }; ass4.IsLabeled = true; var ass5 = new Assign { Left = ass2.Result, Operation = OpCode.Minus, Right = new IntConst(4), Result = ass2.Result }; var ass6 = new Assign { Operation = OpCode.Copy, Right = new IntConst(4000), Result = ass3.Result }; var ass7 = new Assign { Operation = OpCode.Copy, Right = new IntConst(5000), Result = ass1.Result }; ass7.IsLabeled = true; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass7.Label }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass4.Label }; var empty = new Empty { }; { taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ass4); taCode.AddNode(ass5); taCode.AddNode(ifgt1); taCode.AddNode(ass6); taCode.AddNode(ass7); taCode.AddNode(ifgt2); taCode.AddNode(empty); } var cfg = new ControlFlowGraph(taCode); taCode.CreateBasicBlockList(); var op = new Operations(taCode); var tf = new TransferFunction(taCode); var tmp = taCode.ToString(); var(gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(0), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass1.Label, ass2.Label, ass3.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass4.Label, ass5.Label, ass6.Label, ass7.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(1), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass4.Label, ass5.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass1.Label, ass2.Label, ass7.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(2), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass6.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass3.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(3), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass7.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass1.Label, ass4.Label })); var inout = new GenericIterativeAlgorithm <HashSet <Guid> >() { Finish = (a, b) => { var(a1, a2) = a; var(b1, b2) = b; return(!a2.Except(b2).Any()); }, Comparer = (x, y) => !x.Except(y).Any(), Fill = () => (op.Lower, op.Lower), DebugToString = (x) => x.Aggregate("", (s, y) => s + ", " + TACodeNameManager.Instance[y]) }.Analyze(cfg, op, tf);
private static void TaCodeTest() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), //Left = new IntConst(5), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(2), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Minus, Right = new IntConst(1), Result = new Var() }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass3.Label }; ass3.IsLabeled = true; //На этот оперетор мы переходим по условию var ass4 = new Assign { Left = ass3.Result, Operation = OpCode.Plus, Right = new IntConst(1999), Result = new Var() }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass2.Label }; ass2.IsLabeled = true; //На этот оперетор мы переходим по условию var ass5 = new Assign { Left = new IntConst(7), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass6 = new Assign { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(25), Result = new Var() }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ifgt1); taCode.AddNode(ass4); taCode.AddNode(ifgt2); taCode.AddNode(ass5); taCode.AddNode(ass6); var algOpt = new AlgebraicOptimization(); algOpt.Optimize(taCode.CodeList.ToList(), out var applied); Console.WriteLine($"TA Code\n: {taCode}"); var bBlocks = taCode.CreateBasicBlockList(); foreach (var bbl in bBlocks) { Console.WriteLine($"Block[{bbl.BlockId}]:"); var bblCodeStr = bbl.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); } Console.WriteLine($"Algebraic Optimization was{(applied ? "" : "n't")} applied"); Console.WriteLine("========================CFG test========================"); var cfg = new ControlFlowGraph(taCode); foreach (var cfgn in cfg.CFGNodes) { Console.WriteLine($"Block[{cfgn.BlockId}]"); var bblCodeStr = cfgn.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); Console.WriteLine("Children:\n"); foreach (var ch in cfgn.Children) { Console.WriteLine($"Block[{ch.BlockId}]"); var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("Parents:\n"); foreach (var ch in cfgn.Parents) { Console.WriteLine($"Block[{ch.BlockId}]"); var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("-----------------------------------------"); } //Copy Propagation Test var taCodeCopyProp = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var assgn2 = new Assign() { Left = assgn1.Right, Operation = OpCode.Minus, Right = assgn1.Result, Result = new Var() }; var assgn3 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assgn4 = new Assign() { Left = assgn3.Result, Operation = OpCode.Mul, Right = assgn1.Result, Result = new Var() }; var assgn5 = new Assign() { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(20), Result = assgn1.Result }; var assgn6 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = assgn5.Result, Result = new Var() }; taCodeCopyProp.AddNode(assgn1); taCodeCopyProp.AddNode(assgn2); taCodeCopyProp.AddNode(assgn3); taCodeCopyProp.AddNode(assgn4); taCodeCopyProp.AddNode(assgn5); taCodeCopyProp.AddNode(assgn6); /* * a = b * c = b - a -----> c = b - b * d = c + 1 * e = d * a -----> e = d * b * a = 30 - 20 * k = c + a -----> k = c + a */ Console.WriteLine($"Testing Copy Propagation Optimisation.\n Three Adress Code:\n {taCodeCopyProp}"); var optCopyProp = new CopyPropagation(); optCopyProp.Optimize(taCodeCopyProp.CodeList.ToList(), out var applCopProp); Console.WriteLine($"Optimisation Copy Propagation was{(applCopProp ? "" : "n't")} applied"); Console.WriteLine($"Three Adress Code Code\n: {taCodeCopyProp}"); Console.WriteLine("-----------------------------------------"); //Constant Folding Test var taCodeConstantFolding = new TACode(); var assign1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var assign2 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var assign3 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assign4 = new Assign() { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(50), Result = new Var() }; var assign5 = new Assign() { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(20), Result = assign1.Result }; var assign6 = new Assign() { Left = assign2.Result, Operation = OpCode.Plus, Right = assign5.Result, Result = new Var() }; taCodeConstantFolding.AddNode(assign1); taCodeConstantFolding.AddNode(assign2); taCodeConstantFolding.AddNode(assign3); taCodeConstantFolding.AddNode(assign4); taCodeConstantFolding.AddNode(assign5); taCodeConstantFolding.AddNode(assign6); /* * a = b * c = 20 * 3 -----> c = 60 * d = 10 + 1 -----> d = 11 * e = 100 / 50 -----> e = 2 * a = 30 - 20 -----> a = 10 * k = c + a */ Console.WriteLine($"Testing Constant Folding Optimisation.\n Three Adress Code:\n {taCodeConstantFolding}"); var optConstFold = new ConstantFolding(); optConstFold.Optimize(taCodeConstantFolding.CodeList.ToList(), out var applConstFold); Console.WriteLine($"Optimisation Constant Folding was{(applConstFold ? "" : "n't")} applied"); Console.WriteLine($"Three Adress Code Code\n: {taCodeConstantFolding}"); Console.WriteLine("-----------------------------------------"); //All Optimizations Together Test var taCodeAllOptimizations = new TACode(); var a1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var a2 = new Assign() { Left = a1.Right, Operation = OpCode.Minus, Right = a1.Result, Result = new Var() }; var a3 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(20), Result = new Var() }; var a4 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var a5 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = a3.Result, Result = new Var() }; taCodeAllOptimizations.AddNode(a1); taCodeAllOptimizations.AddNode(a2); taCodeAllOptimizations.AddNode(a3); taCodeAllOptimizations.AddNode(a4); taCodeAllOptimizations.AddNode(a5); /* * a = b * c = b - a -----> c = 0 * n = 20 * c = 20 * 3 -----> c = 60 * d = 10 + n -----> d = 30 */ Console.WriteLine($"Testing All Optimizations Together.\n Three Adress Code:\n {taCodeAllOptimizations}"); var allOptimizations = new AllOptimizations(); allOptimizations.ApplyAllOptimizations(taCodeAllOptimizations); Console.WriteLine($"Three Adress Code Code\n: {taCodeAllOptimizations}"); Console.WriteLine("-----------------------------------------"); }
public void Test1() { var taCode = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(91), Result = new Var("b") }; var assgn2 = new Assign() { Left = null, Operation = OpCode.Copy, Right = assgn1.Result, Result = new Var("c") }; var assgn3 = new Assign() { Left = assgn1.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var("d") }; var ifgtH = new IfGoto { Condition = new IntConst(1), TargetLabel = assgn3.Label }; assgn3.IsLabeled = true; var assgn4 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(2), Result = new Var("j") }; var assgn5 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(0), Result = assgn3.Result }; var assgn6 = new Assign() { Left = null, Operation = OpCode.Copy, Right = assgn2.Result, Result = assgn3.Result }; var ifgtX = new IfGoto { Condition = new IntConst(1), TargetLabel = assgn6.Label }; assgn6.IsLabeled = true; taCode.AddNode(assgn1); taCode.AddNode(assgn2); taCode.AddNode(ifgtH); taCode.AddNode(assgn3); taCode.AddNode(assgn4); taCode.AddNode(assgn5); taCode.AddNode(ifgtX); taCode.AddNode(assgn6); var cfg = new ControlFlowGraph(taCode); IterativeAlgorithmAV ItAV = new IterativeAlgorithmAV(cfg); Assert.AreEqual(ItAV.IN.ElementAt(0).Value.Count, 0); Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(0), assgn1.Result); Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(1), assgn2.Result); Assert.AreEqual(ItAV.IN.ElementAt(2).Value.ElementAt(0), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(0), assgn1.Result); Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(1), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(1).Value.ElementAt(0), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(2).Value.Count, 0); }
public void DeclarationOptimizationTest() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; ass1.IsLabeled = true; var ass2 = new Assign { Left = new IntConst(3), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Plus, Left = ass2.Result, Right = new IntConst(5), Result = new Var() }; var ass4 = new Assign { Operation = OpCode.Plus, Left = ass1.Result, Right = new IntConst(1), Result = new Var() }; var ass5 = new Assign { Operation = OpCode.Mul, Left = new IntConst(4), Right = new IntConst(7), Result = new Var() }; var ass6 = new Assign { Operation = OpCode.Mul, Left = new IntConst(8), Right = new IntConst(9), Result = new Var() }; var ass7 = new Assign { Operation = OpCode.Mul, Left = ass3.Result, Right = new IntConst(3), Result = new Var() }; var ifgt1 = new IfGoto { Condition = ass1.Result, TargetLabel = ass1.Label }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ass4); taCode.AddNode(ass5); taCode.AddNode(ass6); taCode.AddNode(ass7); taCode.AddNode(ifgt1); Console.WriteLine($"TA Code\n: {taCode}"); var algOpt = new DeclarationOptimization(); Console.WriteLine($"TA Code\n"); foreach (var node in algOpt.Optimize(taCode.CodeList.ToList(), out var applied)) { Console.WriteLine($"{node}"); } Console.ReadKey(); //var bBlocks = taCode.CreateBasicBlockList(); //foreach (var bbl in bBlocks) //{ // Console.WriteLine($"Block[{bbl.BlockId}]:"); // var bblCodeStr = bbl.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); // Console.WriteLine($"{bblCodeStr}\n"); //} //Console.WriteLine($"Algebraic Optimization was{(applied ? "" : "n't")} applied"); //Console.WriteLine("========================CFG test========================"); //var cfg = new ControlFlowGraph(taCode); //foreach (var cfgn in cfg.CFGNodes) //{ // Console.WriteLine($"Block[{cfgn.Block.BlockId}]"); // var bblCodeStr = cfgn.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); // Console.WriteLine($"{bblCodeStr}\n"); // Console.WriteLine("Children:\n"); // foreach (var ch in cfgn.Children) // { // Console.WriteLine($"Block[{ch.Block.BlockId}]"); // var bblCodeCh = ch.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); // Console.WriteLine($"{bblCodeCh}\n"); // } // Console.WriteLine("Parents:\n"); // foreach (var ch in cfgn.Parents) // { // Console.WriteLine($"Block[{ch.Block.BlockId}]"); // var bblCodeCh = ch.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); // Console.WriteLine($"{bblCodeCh}\n"); // } // Console.WriteLine("-----------------------------------------"); //} }
private static void TaCodeTest() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(2), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Minus, Right = new IntConst(1), Result = new Var() }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass3.Label }; ass3.IsLabeled = true; //На этот оперетор мы переходим по условию var ass4 = new Assign { Left = ass3.Result, Operation = OpCode.Plus, Right = new IntConst(1999), Result = new Var() }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass2.Label }; ass2.IsLabeled = true; //На этот оперетор мы переходим по условию var ass5 = new Assign { Left = new IntConst(7), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass6 = new Assign { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(25), Result = new Var() }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ifgt1); taCode.AddNode(ass4); taCode.AddNode(ifgt2); taCode.AddNode(ass5); taCode.AddNode(ass6); Console.WriteLine($"TA Code\n: {taCode}"); var bBlocks = taCode.CreateBasicBlockList(); foreach (var bbl in bBlocks) { Console.WriteLine($"Block[{bbl.BlockId}]:"); var bblCodeStr = bbl.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); } Console.WriteLine("========================CFG test========================"); var cfg = new ControlFlowGraph(taCode); foreach (var cfgn in cfg.CFGNodes) { Console.WriteLine($"Block[{cfgn.Block.BlockId}]"); var bblCodeStr = cfgn.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); Console.WriteLine("Children:\n"); foreach (var ch in cfgn.Children) { Console.WriteLine($"Block[{ch.Block.BlockId}]"); var bblCodeCh = ch.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("Parents:\n"); foreach (var ch in cfgn.Parents) { Console.WriteLine($"Block[{ch.Block.BlockId}]"); var bblCodeCh = ch.Block.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("-----------------------------------------"); } }
public void Test1() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(2), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Minus, Right = new IntConst(1), Result = new Var() }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass3.Label }; ass3.IsLabeled = true; var ass4 = new Assign { Left = ass3.Result, Operation = OpCode.Plus, Right = new IntConst(1999), Result = new Var() }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass2.Label }; ass2.IsLabeled = true; var ass5 = new Assign { Left = new IntConst(7), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass6 = new Assign { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(25), Result = new Var() }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ifgt1); taCode.AddNode(ass4); taCode.AddNode(ifgt2); taCode.AddNode(ass5); taCode.AddNode(ass6); var cfg = new ControlFlowGraph(taCode); var fst = cfg.CFGNodes.First(); /** * 1) t1 = 3 - 5 -- 1-й блок-узел * * 2) t2 = 10 + 2 -- 2-й блок-узел * * 3) t3 = -1 -- 3-й блок-узел * 4) if 1 goto 3) * * 5) t4 = t3 + 1999 -- 4-й блок-узел * 6) if 2 goto 2) * * 7) t5 = 7 * 4 -- 5-й блок-узел * 8) t6 = 100 / 2 * */ //Тест 1-го узла Assert.AreEqual(fst.CodeList.ElementAt(0), taCode.CodeList.ElementAt(0)); Assert.IsTrue(fst.CodeList.Count() == 1, "Number of TAC at first node is not 1"); Assert.IsTrue(fst.Children.Count() == 1, "Number of children for first node is not 1"); Assert.IsTrue(fst.Parents.Count() == 0, "Number of parents for first node is not 0"); Assert.AreEqual(cfg.CFGNodes.ElementAt(1), fst.Children.ElementAt(0)); //Тест 2-го узла Assert.IsTrue(cfg.CFGNodes.ElementAt(1).CodeList.Count() == 1, "Number of TAC at second node is not 1"); Assert.IsTrue(cfg.CFGNodes.ElementAt(1).Children.Count() == 1, "Number of children for second node is not 1"); Assert.IsTrue(cfg.CFGNodes.ElementAt(1).Parents.Count() == 2, "Number of parents for second node is not 1"); Assert.AreEqual(cfg.CFGNodes.ElementAt(2), cfg.CFGNodes.ElementAt(1).Children.ElementAt(0)); //потомок для 2-го узла : 3-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(0), cfg.CFGNodes.ElementAt(1).Parents.ElementAt(1)); //предок для 2-го узла : 4-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(3), cfg.CFGNodes.ElementAt(1).Parents.ElementAt(0)); //предок для 2-го узла : 1-й узел //Тест 3-го узла Assert.IsTrue(cfg.CFGNodes.ElementAt(2).CodeList.Count() == 2, "Number of TAC at third node is not equals 2"); Assert.IsTrue(cfg.CFGNodes.ElementAt(2).Children.Count() == 2, "Number of children for third node is not equals 2"); Assert.IsTrue(cfg.CFGNodes.ElementAt(1).Parents.Count() == 2, "Number of parents for third node is not equals 2"); Assert.AreEqual(cfg.CFGNodes.ElementAt(2), cfg.CFGNodes.ElementAt(2).Children.ElementAt(0)); //потомок для 3-го узла : 3-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(3), cfg.CFGNodes.ElementAt(2).Children.ElementAt(1)); //потомок для 3-го узла : 4-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(2), cfg.CFGNodes.ElementAt(2).Parents.ElementAt(0)); //предок для 3-го узла : 3-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(1), cfg.CFGNodes.ElementAt(2).Parents.ElementAt(1)); //предок для 3-го узла : 2-й узел //Тест 4-го узла Assert.IsTrue(cfg.CFGNodes.ElementAt(3).CodeList.Count() == 2, "Number of TAC at fourth node is not equals 2"); Assert.IsTrue(cfg.CFGNodes.ElementAt(3).Children.Count() == 2, "Number of children for fourth node is not equals 2"); Assert.IsTrue(cfg.CFGNodes.ElementAt(3).Parents.Count() == 1, "Number of parents for fourth node is not equals 1"); Assert.AreEqual(cfg.CFGNodes.ElementAt(1), cfg.CFGNodes.ElementAt(3).Children.ElementAt(0)); //потомок для 4-го узла : 1-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(4), cfg.CFGNodes.ElementAt(3).Children.ElementAt(1)); //потомок для 4-го узла : 5-й узел Assert.AreEqual(cfg.CFGNodes.ElementAt(2), cfg.CFGNodes.ElementAt(3).Parents.ElementAt(0)); //предок для 4-го узла : 3-й узел //Тест 5-го узла Assert.IsTrue(cfg.CFGNodes.ElementAt(4).CodeList.Count() == 2, "Number of TAC at fifth node is not equals 2"); Assert.IsTrue(cfg.CFGNodes.ElementAt(4).Children.Count() == 0, "Number of children for fifth node is not equals 0"); Assert.IsTrue(cfg.CFGNodes.ElementAt(4).Parents.Count() == 1, "Number of parents for fifth node is not equals 1"); Assert.AreEqual(cfg.CFGNodes.ElementAt(3), cfg.CFGNodes.ElementAt(4).Parents.ElementAt(0)); //предок для 5-го узла : 4-й узел }