public void DefUse_Test1()
        {
            var tacContainer = new ThreeAddressCode();

            Utils.AddAssignmentNode(tacContainer, null, "a", "b", "+", "c");
            Utils.AddAssignmentNode(tacContainer, null, "b", "a", "-", "d");
            Utils.AddAssignmentNode(tacContainer, null, "v", "l", "+", "c");
            Utils.AddAssignmentNode(tacContainer, null, "d", "a", "-", "d");
            var cfg = new ControlFlowGraph(tacContainer);
            var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
            var container        = defUseContainers.First().Value;

            Assert.IsTrue(
                container.GetSecondSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "a"
                },
                new TacNodeVarDecorator {
                    VarName = "v"
                }
            })
                );
            Assert.IsTrue(
                container.GetFirstSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "b"
                },
                new TacNodeVarDecorator {
                    VarName = "c"
                },
                new TacNodeVarDecorator {
                    VarName = "d"
                },
                new TacNodeVarDecorator {
                    VarName = "l"
                }
            })
                );
        }
예제 #2
0
        public void Optimize_CombinationOfBlocks()
        {
            /*
             * x = b;
             * x = a; --> Should be deleted despite of it's latest operation in block
             * if (1==1)
             * {
             * x = b;
             * y = x;
             * }
             * x = 1;
             * v = x;
             */
            TmpNameManager.Instance.Drop();
            var tacVisitor = new ThreeAddressCodeVisitor();

            var expectedResult = "t1 = 1 == 1\nif t1 goto L1\n";
            var source         = "x = b;\nx = a;\nif (1==1){\nx = b;\n y = x;\n}\n x = 1;\n v = x;\n";

            var scanner = new Scanner();

            scanner.SetSource(source, 0);
            var parser = new Parser(scanner);

            parser.Parse();
            var root = parser.root;

            root.Visit(tacVisitor);
            tacVisitor.Postprocess();

            var cfg = new ControlFlowGraph(tacVisitor.TACodeContainer);
            var defUseContainers   = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
            var activeVariablesITA = new ActiveVariablesITA(cfg, defUseContainers);
            DeadCodeOptimizationWithITA optimization = new DeadCodeOptimizationWithITA();
            var isOptimized = optimization.Optimize(activeVariablesITA);

            Assert.AreEqual(expectedResult, activeVariablesITA.controlFlowGraph.SourceBasicBlocks.BasicBlockItems[0].ToString());
        }
        public void DefUse_Test2()
        {
            var tacContainer = new ThreeAddressCode();

            Utils.AddAssignmentNode(tacContainer, null, "t1", "4", "*", "i");
            Utils.AddAssignmentNode(tacContainer, null, "a1", "t1");
            Utils.AddAssignmentNode(tacContainer, null, "t2", "b");
            Utils.AddAssignmentNode(tacContainer, null, "i", "1");
            Utils.AddIfGotoNode(tacContainer, null, "L1", "t2");
            Utils.AddGotoNode(tacContainer, null, "L2");
            Utils.AddAssignmentNode(tacContainer, "L1", "t3", "4", "*", "i");
            Utils.AddAssignmentNode(tacContainer, "L2", "a3", "t3");
            Utils.AddAssignmentNode(tacContainer, null, "t4", "4", "*", "i");
            Utils.AddAssignmentNode(tacContainer, null, "a2", "t4");
            var cfg = new ControlFlowGraph(tacContainer);
            var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
            var containers       = defUseContainers.Select(e => e.Value).ToList();

            Assert.IsTrue(
                containers[0].GetSecondSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "a1"
                },
                new TacNodeVarDecorator {
                    VarName = "t1"
                },
                new TacNodeVarDecorator {
                    VarName = "t2"
                }
            })
                );
            Assert.IsTrue(
                containers[0].GetFirstSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "b"
                },
                new TacNodeVarDecorator {
                    VarName = "i"
                }
            })
                );
            Assert.IsTrue(containers[1].GetSecondSet().Count == 0);
            Assert.IsTrue(containers[1].GetFirstSet().Count == 0);
            Assert.IsTrue(
                containers[2].GetSecondSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "t3"
                }
            })
                );
            Assert.IsTrue(
                containers[2].GetFirstSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "i"
                }
            })
                );
            Assert.IsTrue(
                containers[3].GetSecondSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "a2"
                },
                new TacNodeVarDecorator {
                    VarName = "a3"
                },
                new TacNodeVarDecorator {
                    VarName = "t4"
                }
            })
                );
            Assert.IsTrue(
                containers[3].GetFirstSet().SetEquals(new HashSet <TacNode>()
            {
                new TacNodeVarDecorator {
                    VarName = "i"
                },
                new TacNodeVarDecorator {
                    VarName = "t3"
                }
            })
                );
        }
예제 #4
0
        public static void Main()
        {
            var    DirectoryPath = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
            string FileName      = Path.Combine(DirectoryPath, "a.txt");

            try
            {
                string Text = File.ReadAllText(FileName);
                Text = Text.Replace('\t', ' ');

                Scanner scanner = new Scanner();
                scanner.SetSource(Text, 0);

                Parser parser = new Parser(scanner);

                var b = parser.Parse();
                var r = parser.root;
                // Console.WriteLine(r);
                Console.WriteLine("Исходный текст программы");
                var printv = new PrettyPrintVisitor(true);
                r.Visit(printv);
                Console.WriteLine(printv.Text);
                Console.WriteLine("-------------------------------");

                if (!b)
                {
                    Console.WriteLine("Ошибка");
                }
                else
                {
                    Console.WriteLine("Синтаксическое дерево построено");

                    // TODO: add loop through all tree optimizations

                    var avis = new AssignCountVisitor();
                    parser.root.Visit(avis);
                    Console.WriteLine("Количество присваиваний = {0}", avis.Count);
                    Console.WriteLine("-------------------------------");

                    var operv = new OperatorCountVisitor();
                    parser.root.Visit(operv);
                    Console.WriteLine(operv.Result);

                    var maxcv = new MaxOpExprVisitor();
                    parser.root.Visit(maxcv);
                    Console.WriteLine(maxcv.Result);

                    var inncycv = new IsInnerCycleVisitor();
                    parser.root.Visit(inncycv);
                    Console.WriteLine(inncycv.Result);

                    var innifv = new IsInnerIfCycleVisitor();
                    parser.root.Visit(innifv);
                    Console.WriteLine(innifv.Result);

                    var maxdeepv = new MaxDeepCycleVistor();
                    parser.root.Visit(maxdeepv);
                    Console.WriteLine(maxdeepv.Result);

                    var parentv = new FillParentVisitor();
                    parser.root.Visit(parentv);

                    var sameminusv = new SameMinusOptVisitor();
                    parser.root.Visit(sameminusv);

                    var zeroMulVisitor = new ZeroMulOptVisitor();
                    parser.root.Visit(zeroMulVisitor);

                    var compareFalseVisitor = new CompareToItselfFalseOptVisitor();
                    parser.root.Visit(compareFalseVisitor);

                    Console.WriteLine("-------------------------------");

                    var ifNodeWithBoolExpr = new IfNodeWithBoolExprVisitor();
                    parser.root.Visit(ifNodeWithBoolExpr);

                    //var plusZeroExpr = new PlusZeroExprVisitor();
                    //parser.root.Visit(plusZeroExpr);

                    //var alwaysElse = new AlwaysElseVisitor();
                    //parser.root.Visit(alwaysElse);

                    //var checkTruth = new CheckTruthVisitor();
                    //parser.root.Visit(checkTruth);

                    //Console.WriteLine("Оптимизированная программа");
                    //printv = new PrettyPrintVisitor(true);
                    //r.Visit(printv);
                    //Console.WriteLine(printv.Text);
                    //Console.WriteLine("-------------------------------");

                    Console.WriteLine("Оптимизированная программа");
                    printv = new PrettyPrintVisitor(true);
                    r.Visit(printv);
                    Console.WriteLine(printv.Text);
                    Console.WriteLine("-------------------------------");

                    var threeAddressCodeVisitor = new ThreeAddressCodeVisitor();
                    r.Visit(threeAddressCodeVisitor);

                    var cfg = new ControlFlowGraph(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine(cfg);
                    cfg.SaveToFile(@"cfg.txt");

                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);
                    var availExprOpt = new AvailableExprOptimization();
                    availExprOpt.Optimize(cfg);
                    Console.WriteLine("======= After algebraic identity =======");
                    Console.WriteLine(cfg);

                    Console.WriteLine("======= DV =======");
                    Console.WriteLine(threeAddressCodeVisitor);
                    var detector = new DefUseDetector();
                    detector.DetectAndFillDefUse(threeAddressCodeVisitor.TACodeContainer);
                    //Console.WriteLine("======= Detector 1 =======");
                    //Console.WriteLine(detector);
                    //Console.WriteLine("======= Detector 2 =======");
                    //Console.WriteLine(detector.ToString2());
                    var constPropagationOptimizer = new DefUseConstPropagation(detector);
                    var result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);

                    Console.WriteLine("======= After const propagation =======");
                    Console.WriteLine(threeAddressCodeVisitor);

                    result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("======= After const propagation =======");
                    Console.WriteLine(threeAddressCodeVisitor);

                    var copyPropagationOptimizer = new DefUseCopyPropagation(detector);
                    result = copyPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);

                    Console.WriteLine("======= After copy propagation =======");
                    Console.WriteLine(threeAddressCodeVisitor);

                    //var bblocks = new BasicBlocks();
                    //bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer);
                    //Console.WriteLine("Разбиение на базовые блоки завершилось");
                    var emptyopt = new EmptyNodeOptimization();
                    emptyopt.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Empty node optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    var gotoOpt = new GotoOptimization();
                    gotoOpt.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Goto optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    //var elimintaion = new EliminateTranToTranOpt();
                    //elimintaion.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    //Console.WriteLine("Удаление переходов к переходам завершилось");

                    var unreachableCode = new UnreachableCodeOpt();
                    var res             = unreachableCode.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Оптимизация для недостижимых блоков");

                    var algOpt = new AlgebraicIdentityOptimization();
                    algOpt.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("algebraic identity optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    var bblocks = new BasicBlocks();
                    bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Разбиение на базовые блоки завершилось");
                    Console.WriteLine();

                    GenKillVisitor genKillVisitor    = new GenKillVisitor();
                    var            genKillContainers = genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks);
                    InOutContainer inOutContainers   = new InOutContainer(cfg.SourceBasicBlocks, genKillContainers);
                    Console.WriteLine("=== InOut для базовых блоков ===");
                    Console.WriteLine(inOutContainers.ToString());

                    var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
                    DefUseForBlocksPrinter.Execute(defUseContainers);

                    var reachingDefenitionsITA = new ReachingDefinitionsITA(cfg, genKillContainers);
                    Console.WriteLine("=== InOut после итерационного алгоритма для достигающих определения ===");
                    Console.WriteLine(reachingDefenitionsITA);

                    var activeVariablesITA = new ActiveVariablesITA(cfg, defUseContainers);
                    Console.WriteLine("=== InOut после итерационного алгоритма для активных переменных ===");
                    Console.WriteLine(activeVariablesITA);
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Файл {0} не найден", FileName);
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e);
            }

            Console.ReadLine();
        }
        public void Compute_CheckFirstBlockActiveVariables()
        {
            var source = "c = 123;\nm = 1 + c + y;\nif (m > 2) {\n    c = 3;\n} else {\n    c = 456;\n}\na = 11;";

            /*
             * c = 123;
             * m = 1 + c + y;
             * if (m > 2) {
             *   c = 3;
             * } else {
             *   c = 456;
             * }
             * a = 11;
             */

            var scanner = new Scanner();

            scanner.SetSource(source, 0);
            var parser = new Parser(scanner);

            parser.Parse();

            var parentv = new FillParentVisitor();

            parser.root.Visit(parentv);

            var threeAddressCodeVisitor = new ThreeAddressCodeVisitor();

            parser.root.Visit(threeAddressCodeVisitor);
            threeAddressCodeVisitor.Postprocess();

            var cfg = new ControlFlowGraph(threeAddressCodeVisitor.TACodeContainer);

            var basicBlocks = new BasicBlocks();

            basicBlocks.SplitTACode(cfg.SourceCode);

            var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);

            DefUseForBlocksPrinter.Execute(defUseContainers);

            var tfFunction = new TFByComposition(defUseContainers);

            var collectionOperator = new UnionCollectionOperator <TacNode>();

            var mop = new MeetOverPaths(cfg, tfFunction, collectionOperator, new HashSet <TacNode>(), false);

            mop.Compute();

            var expectedIn = new List <string> {
                "y"
            };
            var outputIn = mop.InOut.In[cfg.SourceBasicBlocks.BasicBlockItems[0]]
                           .Select(x => x.ToString()).ToList();

            Assert.IsTrue(expectedIn.SequenceEqual(outputIn));

            var outputOut = mop.InOut.Out[cfg.SourceBasicBlocks.BasicBlockItems[0]]
                            .Select(x => x.ToString()).ToList();

            Assert.AreEqual(0, outputOut.Count);
        }
예제 #6
0
        public static void Main()
        {
            var    DirectoryPath = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
            string FileName      = Path.Combine(DirectoryPath, "a.txt");

            try
            {
                string Text = File.ReadAllText(FileName);
                Text = Text.Replace('\t', ' ');

                Scanner scanner = new Scanner();
                scanner.SetSource(Text, 0);

                Parser parser = new Parser(scanner);

                var b = parser.Parse();
                var r = parser.root;
                // Console.WriteLine(r);
                Console.WriteLine("Исходный текст программы");
                var printv = new PrettyPrintVisitor(true);
                r.Visit(printv);
                Console.WriteLine(printv.Text);
                Console.WriteLine("-------------------------------");

                if (!b)
                {
                    Console.WriteLine("Ошибка");
                }
                else
                {
                    Console.WriteLine("Синтаксическое дерево построено");

                    // TODO: add loop through all tree optimizations

                    var avis = new AssignCountVisitor();
                    parser.root.Visit(avis);
                    Console.WriteLine("Количество присваиваний = {0}", avis.Count);
                    Console.WriteLine("-------------------------------");

//                    var operv = new OperatorCountVisitor();
//                    parser.root.Visit(operv);
//                    Console.WriteLine(operv.Result);
//
//                    var maxcv = new MaxOpExprVisitor();
//                    parser.root.Visit(maxcv);
//                    Console.WriteLine(maxcv.Result);
//
//                    var inncycv = new IsInnerCycleVisitor();
//                    parser.root.Visit(inncycv);
//                    Console.WriteLine(inncycv.Result);
//
//                    var innifv = new IsInnerIfCycleVisitor();
//                    parser.root.Visit(innifv);
//                    Console.WriteLine(innifv.Result);
//
//                    var maxdeepv = new MaxDeepCycleVistor();
//                    parser.root.Visit(maxdeepv);
//                    Console.WriteLine(maxdeepv.Result);
//
//                    var parentv = new FillParentVisitor();
//                    parser.root.Visit(parentv);
//
//                    var sameminusv = new SameMinusOptVisitor();
//                    parser.root.Visit(sameminusv);
//
//                    var zeroMulVisitor = new ZeroMulOptVisitor();
//                    parser.root.Visit(zeroMulVisitor);
//
//                    var compareFalseVisitor = new CompareToItselfFalseOptVisitor();
//                    parser.root.Visit(compareFalseVisitor);
                    var operv = new OperatorCountVisitor();
                    parser.root.Visit(operv);
                    Console.WriteLine(operv.Result);

                    var maxcv = new MaxOpExprVisitor();
                    parser.root.Visit(maxcv);
                    Console.WriteLine(maxcv.Result);

                    var inncycv = new IsInnerCycleVisitor();
                    parser.root.Visit(inncycv);
                    Console.WriteLine(inncycv.Result);

                    var innifv = new IsInnerIfCycleVisitor();
                    parser.root.Visit(innifv);
                    Console.WriteLine(innifv.Result);

                    var maxdeepv = new MaxDeepCycleVistor();
                    parser.root.Visit(maxdeepv);
                    Console.WriteLine(maxdeepv.Result);

                    var parentv = new FillParentVisitor();
                    parser.root.Visit(parentv);

                    var sameminusv = new SameMinusOptVisitor();
                    parser.root.Visit(sameminusv);

                    var whilefalsev = new WhileFalseOptVisitor();
                    parser.root.Visit(whilefalsev);

                    var zeroMulVisitor = new ZeroMulOptVisitor();
                    parser.root.Visit(zeroMulVisitor);

                    var compareFalseVisitor = new CompareToItselfFalseOptVisitor();
                    parser.root.Visit(compareFalseVisitor);

                    Console.WriteLine("-------------------------------");
                    //
                    //                    var ifNodeWithBoolExpr = new IfNodeWithBoolExprVisitor();
                    //                    parser.root.Visit(ifNodeWithBoolExpr);

                    //var plusZeroExpr = new PlusZeroExprVisitor();
                    //parser.root.Visit(plusZeroExpr);

                    var alwaysElse = new AlwaysElseVisitor();
                    parser.root.Visit(alwaysElse);

                    //var checkTruth = new CheckTruthVisitor();
                    //parser.root.Visit(checkTruth);

                    //Console.WriteLine("Оптимизированная программа");
                    //printv = new PrettyPrintVisitor(true);
                    //r.Visit(printv);
                    //Console.WriteLine(printv.Text);
                    //Console.WriteLine("-------------------------------");

                    Console.WriteLine("Оптимизированная программа");
                    printv = new PrettyPrintVisitor(true);
                    r.Visit(printv);
                    Console.WriteLine(printv.Text);
                    Console.WriteLine("-------------------------------");

                    var threeAddressCodeVisitor = new ThreeAddressCodeVisitor();
                    r.Visit(threeAddressCodeVisitor);
                    threeAddressCodeVisitor.Postprocess();

                    Console.WriteLine("========== TAC ==============");
                    Console.WriteLine(threeAddressCodeVisitor);

                    var cfg = new ControlFlowGraph(threeAddressCodeVisitor.TACodeContainer);

//                    Console.WriteLine(cfg);
//                    cfg.SaveToFile(@"cfg.txt");

//                    var dstClassifier = new DstEdgeClassifier(cfg);
//                    dstClassifier.ClassificateEdges(cfg);
//                    Console.WriteLine(dstClassifier);

                    Console.WriteLine(cfg);
                    cfg.SaveToFile(@"cfg.txt");
                    var dstClassifier = new DstEdgeClassifier(cfg);
                    dstClassifier.ClassificateEdges(cfg);
                    Console.WriteLine(dstClassifier);

                    var depth = cfg.GetDepth(dstClassifier.EdgeTypes);
                    Console.WriteLine($"Depth CFG = {depth}");


                    /* -----------------------CFG TASKS START---------------------------------*/
                    Console.WriteLine("\nCFG TASKS START");
                    Console.WriteLine(cfg);
                    var edgeClassifierService = new EdgeClassifierService(cfg);
                    Console.WriteLine("EdgeClassifierService: \n" + edgeClassifierService);
                    bool isReducibility = DSTReducibility.IsReducibility(cfg);
                    Console.WriteLine("IsReducibility: " + isReducibility);
                    var naturalCycles = new CFGNaturalCycles(cfg);
                    Console.WriteLine("\nNaturalCycles: \n" + naturalCycles);
                    //Console.WriteLine("\nNestedCycles: \n" + naturalCycles.NestedLoopsText());
                    Console.WriteLine("\nCFG TASKS END");
                    /* -----------------------CFG TASKS END---------------------------------*/

                    //Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);
                    //var availExprOpt = new AvailableExprOptimization();
                    //availExprOpt.Optimize(cfg);
                    //Console.WriteLine("======= After algebraic identity =======");
                    //Console.WriteLine(cfg);


                    //                    Console.WriteLine("======= DV =======");
                    //                    Console.WriteLine(threeAddressCodeVisitor);
                    //                    var detector = new DefUseDetector();
                    //                    detector.DetectAndFillDefUse(threeAddressCodeVisitor.TACodeContainer);

                    Console.WriteLine();
                    Console.WriteLine("Before optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    /*Console.WriteLine("======= DV =======");
                     * Console.WriteLine(threeAddressCodeVisitor);
                     * var detector = new DefUseDetector();
                     * detector.DetectAndFillDefUse(threeAddressCodeVisitor.TACodeContainer);
                     *
                     * //Console.WriteLine("======= Detector 1 =======");
                     * //Console.WriteLine(detector);
                     * //Console.WriteLine("======= Detector 2 =======");
                     * //Console.WriteLine(detector.ToString2());
                     *
                     * //                    var constPropagationOptimizer = new DefUseConstPropagation(detector);
                     * //                    var result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     * //
                     * //                    Console.WriteLine("======= After const propagation =======");
                     * //                    Console.WriteLine(threeAddressCodeVisitor);
                     * //
                     * //                    result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     * //                    Console.WriteLine("======= After const propagation =======");
                     * //                    Console.WriteLine(threeAddressCodeVisitor);
                     * //
                     * //                    var copyPropagationOptimizer = new DefUseCopyPropagation(detector);
                     * //                    result = copyPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     * //
                     * //                    Console.WriteLine("======= After copy propagation =======");
                     * //                    Console.WriteLine(threeAddressCodeVisitor);
                     * =======
                     * var constPropagationOptimizer = new DefUseConstPropagation(detector);
                     * var result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     *
                     * Console.WriteLine("======= After const propagation =======");
                     * Console.WriteLine(threeAddressCodeVisitor);
                     *
                     * result = constPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     * Console.WriteLine("======= After const propagation =======");
                     * Console.WriteLine(threeAddressCodeVisitor);
                     *
                     * var copyPropagationOptimizer = new DefUseCopyPropagation(detector);
                     * result = copyPropagationOptimizer.Optimize(threeAddressCodeVisitor.TACodeContainer);
                     *
                     * Console.WriteLine("======= After copy propagation =======");
                     * Console.WriteLine(threeAddressCodeVisitor);
                     */

                    //var bblocks = new BasicBlocks();
                    //bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer);
                    //Console.WriteLine("Разбиение на базовые блоки завершилось");
                    var emptyopt = new EmptyNodeOptimization();
                    emptyopt.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Empty node optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

//                    var gotoOpt = new GotoOptimization();
//                    gotoOpt.Optimize(threeAddressCodeVisitor.TACodeContainer);
//                    Console.WriteLine("Goto optimization");
//                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    //var elimintaion = new EliminateTranToTranOpt();
                    //elimintaion.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    //Console.WriteLine("Удаление переходов к переходам завершилось");

//                   var unreachableCode = new UnreachableCodeOpt();
//                   var res = unreachableCode.Optimize(threeAddressCodeVisitor.TACodeContainer);
//                   Console.WriteLine("Оптимизация для недостижимых блоков");

                    var algOpt = new AlgebraicIdentityOptimization();
                    algOpt.Optimize(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("algebraic identity optimization");
                    Console.WriteLine(threeAddressCodeVisitor.TACodeContainer);

                    var bblocks = new BasicBlocks();
                    bblocks.SplitTACode(threeAddressCodeVisitor.TACodeContainer);
                    Console.WriteLine("Разбиение на базовые блоки завершилось");
                    Console.WriteLine();

                    GenKillVisitor genKillVisitor    = new GenKillVisitor();
                    var            genKillContainers = genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks);

                    //start
                    var commonTf = new TFByCommonWay(genKillContainers);
                    var composTf = new TFByComposition(genKillContainers);

                    Console.WriteLine("=== Compos ===");
                    Console.WriteLine(composTf.Calculate(new HashSet <TacNode>(), cfg.SourceBasicBlocks.BasicBlockItems.First()));

                    Console.WriteLine("=== Common ===");
                    Console.WriteLine(commonTf.Calculate(new HashSet <TacNode>(), cfg.SourceBasicBlocks.BasicBlockItems.First()));

                    //end
//                    InOutContainerWithFilling inOutContainers =
//                        new InOutContainerWithFilling(cfg.SourceBasicBlocks, genKillContainers);
//                    Console.WriteLine("=== InOut для базовых блоков ===");
//                    Console.WriteLine(inOutContainers.ToString());

                    var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
                    DefUseForBlocksPrinter.Execute(defUseContainers);

                    var reachingDefenitionsITA = new ReachingDefinitionsITA(cfg, genKillContainers);
                    Console.WriteLine("=== InOut после итерационного алгоритма для достигающих определения ===");
                    Console.WriteLine(reachingDefenitionsITA.InOut);
                    Console.WriteLine("=======================================================================");
                    var reachingDefConstPropagation = new ReachingDefinitionsConstPropagation();
                    Console.WriteLine(threeAddressCodeVisitor);

                    reachingDefConstPropagation.Optimize(reachingDefenitionsITA);
                    reachingDefConstPropagation.Optimize(reachingDefenitionsITA);


                    foreach (var bblock in bblocks)
                    {
                        Console.Write(bblock);
                    }

                    Console.WriteLine("============ Dominators ============");
                    var dominators = new DominatorsFinder(cfg);
                    for (var i = 0; i < dominators.Dominators.Count; ++i)
                    {
                        Console.WriteLine(i + ": ");
                        foreach (var tacNode in dominators.Dominators.ElementAt(i).Value)
                        {
                            Console.WriteLine(tacNode);
                        }
                    }
                    Console.WriteLine("============ Immediate Dominators ============");
                    for (var i = 0; i < dominators.ImmediateDominators.Count; ++i)
                    {
                        Console.WriteLine(i + ": ");
                        if (dominators.ImmediateDominators.ElementAt(i).Value == null)
                        {
                            Console.WriteLine("null");
                        }
                        else
                        {
                            foreach (var tacNode in dominators.ImmediateDominators.ElementAt(i).Value)
                            {
                                Console.WriteLine(tacNode);
                            }
                        }
                        Console.WriteLine();
                    }


//                    var activeVariablesITA = new ActiveVariablesITA(cfg, defUseContainers);
//                    Console.WriteLine("=== InOut после итерационного алгоритма для активных переменных ===");
//                    Console.WriteLine(activeVariablesITA.InOut);
                    var activeVariablesITA = new ActiveVariablesITA(cfg, defUseContainers);
                    Console.WriteLine("=== InOut после итерационного алгоритма для активных переменных ===");
                    Console.WriteLine(activeVariablesITA.InOut);

                    /* -----------------------AvailableExpressions START---------------------------------*/
                    Console.WriteLine("AvailableExpressions Optimization");

                    Console.WriteLine("Before AvailableExprOptimization");
                    Console.WriteLine(cfg.SourceBasicBlocks
                                      .BasicBlockItems.Select((bl, ind) => $"BLOCK{ind}:\n" + bl.ToString()).Aggregate((b1, b2) => b1 + b2));

                    E_GenKillVisitor availExprVisitor = new E_GenKillVisitor();
                    var availExprContainers           = availExprVisitor.GenerateAvailableExpressionForBlocks(cfg.SourceBasicBlocks);

                    var availableExpressionsITA = new AvailableExpressionsITA(cfg, availExprContainers);
                    Console.WriteLine("=== InOut после итерационного алгоритма для доступных выражений ===");
                    Console.WriteLine(availableExpressionsITA.InOut);
                    var inData = availableExpressionsITA.InOut.In;

                    var  availableExprOptimization = new AvailableExprOptimization();
                    bool isUsed = availableExprOptimization.Optimize(availableExpressionsITA);
                    Console.WriteLine("AvailableExprOptimization isUsed: " + isUsed);
                    isUsed = availableExprOptimization.Optimize(availableExpressionsITA);
                    Console.WriteLine("AvailableExprOptimization isUsed: " + isUsed);
                    Console.WriteLine(cfg.SourceBasicBlocks
                                      .BasicBlockItems.Select((bl, ind) => $"BLOCK{ind}:\n" + bl.ToString()).Aggregate((b1, b2) => b1 + b2));
                    /* -----------------------AvailableExpressions END---------------------------------*/

                    /* -----------------------ConstDistribOptimization START---------------------------------*/
                    Console.WriteLine("ConstDistributionOptimization: Before");
                    Console.WriteLine(cfg.SourceBasicBlocks
                                      .BasicBlockItems.Select((bl, ind) => $"BLOCK{ind}:\n" + bl.ToString()).Aggregate((b1, b2) => b1 + b2));

                    var constDistITA       = new ConstDistributionITA(cfg);
                    var constDistOpt       = new ConstDistributionOptimization();
                    var isConstDistApplied = constDistOpt.Optimize(constDistITA);
                    Console.WriteLine("ConstDistributionOptimization isUsed: " + isConstDistApplied);
                    Console.WriteLine(cfg.SourceBasicBlocks
                                      .BasicBlockItems.Select((bl, ind) => $"BLOCK{ind}:\n" + bl.ToString()).Aggregate((b1, b2) => b1 + b2));
                    /* -----------------------ConstDistrib END---------------------------------*/
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("Файл {0} не найден", FileName);
            }
            catch (Exception e)
            {
                Console.WriteLine("{0}", e);
            }

            Console.ReadLine();
        }
        public void Constructor_IfWithNestedLoopAndNestedIf()
        {
            /*
             * if (a < 5)
             *     for (j = 1 to 10)
             *         a = a + 1;
             * else
             *     if (a > 10)
             *         a = a - 10;
             * p = 2;
             */

            var tacContainer = new ThreeAddressCode();

            // basic block #0
            Utils.AddAssignmentNode(tacContainer, null, "t1", "a", "<", "5");
            Utils.AddIfGotoNode(tacContainer, null, "L1", "t1");
            // basic block #1
            Utils.AddAssignmentNode(tacContainer, null, "t2", "a", ">", "10");
            Utils.AddIfGotoNode(tacContainer, null, "L3", "t2");
            // basic block #2
            Utils.AddGotoNode(tacContainer, null, "L4");
            // basic block #3
            Utils.AddAssignmentNode(tacContainer, "L3", "t3", "a", "-", "10");
            Utils.AddAssignmentNode(tacContainer, null, "a", "t3");
            // basic block #4
            Utils.AddGotoNode(tacContainer, "L4", "L2");
            // basic block #5
            Utils.AddAssignmentNode(tacContainer, "L1", "j", "1");
            // basic block #6
            Utils.AddAssignmentNode(tacContainer, "L5", "t4", "a", "+", "1");
            Utils.AddAssignmentNode(tacContainer, null, "a", "t4");
            Utils.AddAssignmentNode(tacContainer, null, "j", "j", "+", "1");
            Utils.AddAssignmentNode(tacContainer, null, "t5", "j", "<", "10");
            Utils.AddIfGotoNode(tacContainer, null, "L5", "t5");
            // basic block #7
            Utils.AddAssignmentNode(tacContainer, "L2", "p", "2");

            var cfg = new ControlFlowGraph(tacContainer);

            var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
            var ita = new ActiveVariablesITA(cfg, defUseContainers);

            var inData  = ita.InOut.In;
            var outData = ita.InOut.Out;

            var expectedIn0 = generateTacNodes();
            var expectedIn1 = generateTacNodes("a");
            var expectedIn2 = generateTacNodes("a");
            var expectedIn3 = generateTacNodes();
            var expectedIn4 = generateTacNodes("a");
            var expectedIn5 = generateTacNodes();
            var expectedIn6 = generateTacNodes("a");
            var expectedIn7 = generateTacNodes("a");

            var expectedOut0 = generateTacNodes();
            var expectedOut1 = generateTacNodes("a");
            var expectedOut2 = generateTacNodes("a");
            var expectedOut3 = generateTacNodes();
            var expectedOut4 = generateTacNodes();
            var expectedOut5 = generateTacNodes();
            var expectedOut6 = generateTacNodes("a");
            var expectedOut7 = generateTacNodes("a");

            Assert.IsTrue(expectedIn7.All(e => inData[cfg[0]].Contains(e)));
            Assert.IsTrue(expectedIn6.All(e => inData[cfg[1]].Contains(e)));
            Assert.IsTrue(expectedIn5.All(e => inData[cfg[2]].Contains(e)));
            Assert.IsTrue(expectedIn4.All(e => inData[cfg[3]].Contains(e)));
            Assert.IsTrue(expectedIn3.All(e => inData[cfg[4]].Contains(e)));
            Assert.IsTrue(expectedIn2.All(e => inData[cfg[5]].Contains(e)));
            Assert.IsTrue(expectedIn1.All(e => inData[cfg[6]].Contains(e)));
            Assert.IsTrue(expectedIn0.All(e => inData[cfg[7]].Contains(e)));

            Assert.IsTrue(expectedOut7.All(e => outData[cfg[0]].Contains(e)));
            Assert.IsTrue(expectedOut6.All(e => outData[cfg[1]].Contains(e)));
            Assert.IsTrue(expectedOut5.All(e => outData[cfg[2]].Contains(e)));
            Assert.IsTrue(expectedOut4.All(e => outData[cfg[3]].Contains(e)));
            Assert.IsTrue(expectedOut3.All(e => outData[cfg[4]].Contains(e)));
            Assert.IsTrue(expectedOut2.All(e => outData[cfg[5]].Contains(e)));
            Assert.IsTrue(expectedOut1.All(e => outData[cfg[6]].Contains(e)));
            Assert.IsTrue(expectedOut0.All(e => outData[cfg[7]].Contains(e)));
        }
        public void Constructor_IfElse()
        {
            /*
             * Code:
             * a = 1;
             * if(b)
             * {
             *      a = 4;
             * } else
             * {
             *      c = 5;
             * }
             * a = c;
             * c = 1;
             *
             * Tac:
             * a = 1
             * t1 = b
             * if t1 goto L1
             * c = 5
             * goto L2
             * L1: a = 4
             * L2: a = 5
             * c = 1
             */

            var tacContainer = new ThreeAddressCode();

            //1
            Utils.AddAssignmentNode(tacContainer, null, "a", "1");
            Utils.AddAssignmentNode(tacContainer, null, "t1", "b");
            Utils.AddIfGotoNode(tacContainer, null, "L1", "t1");
            //2
            Utils.AddAssignmentNode(tacContainer, null, "c", "5");
            Utils.AddGotoNode(tacContainer, null, "L2");
            //3
            Utils.AddAssignmentNode(tacContainer, "L1", "a", "4");
            //4
            Utils.AddAssignmentNode(tacContainer, "L2", "a", "c");
            Utils.AddAssignmentNode(tacContainer, null, "c", "1");

            var cfg = new ControlFlowGraph(tacContainer);

            var defUseContainers = DefUseForBlocksGenerator.Execute(cfg.SourceBasicBlocks);
            var ita = new ActiveVariablesITA(cfg, defUseContainers);

            var inData  = ita.InOut.In;
            var outData = ita.InOut.Out;

            var expectedIn0 = generateTacNodes("c");
            var expectedIn1 = generateTacNodes("c");
            var expectedIn2 = generateTacNodes();
            var expectedIn3 = generateTacNodes("c", "b");

            var expectedOut0 = generateTacNodes();
            var expectedOut1 = generateTacNodes("c");
            var expectedOut2 = generateTacNodes("c");
            var expectedOut3 = generateTacNodes("c");

            Assert.IsTrue(expectedIn3.All(e => inData[cfg[0]].Contains(e)));
            Assert.IsTrue(expectedIn2.All(e => inData[cfg[1]].Contains(e)));
            Assert.IsTrue(expectedIn1.All(e => inData[cfg[2]].Contains(e)));
            Assert.IsTrue(expectedIn0.All(e => inData[cfg[3]].Contains(e)));

            Assert.IsTrue(expectedOut3.All(e => outData[cfg[0]].Contains(e)));
            Assert.IsTrue(expectedOut2.All(e => outData[cfg[1]].Contains(e)));
            Assert.IsTrue(expectedOut1.All(e => outData[cfg[2]].Contains(e)));
            Assert.IsTrue(expectedOut0.All(e => outData[cfg[3]].Contains(e)));
        }