Beispiel #1
0
        /// <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);
            }
        }
Beispiel #4
0
        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);
Beispiel #6
0
        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-й узел
        }