public void Constructor_CompareNestedLoopWithCounter()
        {
            var tacContainer = Utils.GetNestedLoopWithCounterInTAC();
            var cfg          = new ControlFlowGraph(tacContainer);

            var genKillVisitor = new GenKillVisitor();
            var itaOriginal    = new ReachingDefinitionsITA(cfg.GetCFGWithSortedVertices(),
                                                            genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));
            var itaSorted = new ReachingDefinitionsITA(cfg,
                                                       genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));

            Assert.AreEqual(itaOriginal.ToString(), itaSorted.ToString());
        }
        public void Constructor_CompareIfWithNestedLoopAndNestedIf()
        {
            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 genKillVisitor = new GenKillVisitor();
            var itaOriginal    = new ReachingDefinitionsITA(cfg.GetCFGWithSortedVertices(),
                                                            genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));
            var itaSorted = new ReachingDefinitionsITA(cfg,
                                                       genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));

            Assert.AreEqual(itaOriginal.ToString(), itaSorted.ToString());
        }
예제 #3
0
        public void Constructor_GotoWithUnreachableCode()
        {
            /*
             * goto l 1:
             * a = 7;
             * l 1: a = 15;
             */

            var tacContainer = new ThreeAddressCode();

            // basic block #0
            Utils.AddGotoNode(tacContainer, null, "l1");
            // basic block #1
            Utils.AddAssignmentNode(tacContainer, null, "a", "7");
            // basic block #2
            Utils.AddAssignmentNode(tacContainer, "l1", "a", "15");

            var cfg = new ControlFlowGraph(tacContainer);

            var genKillVisitor = new GenKillVisitor();
            var ita            = new ReachingDefinitionsITA(cfg,
                                                            genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));
            var inData  = ita.InOut.In;
            var outData = ita.InOut.Out;

            Assert.AreEqual(inData[cfg[0]].Count, 0);
            Assert.AreEqual(outData[cfg[0]].Count, 0);
            Assert.AreEqual(inData[cfg[1]].Count, 0);
            Assert.AreEqual(outData[cfg[1]].Count, 1);
            Assert.AreEqual(inData[cfg[2]].Count, 1);
            Assert.AreEqual(outData[cfg[2]].Count, 1);

            Assert.IsTrue(outData[cfg[1]].Contains(cfg[1, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[2, 0]));
        }
예제 #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();
        }
예제 #5
0
        public void Execute_IfWithLoopAndNestedIf()
        {
            /*
             * 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 genKillVisitor = new GenKillVisitor();
            var ita            = new ReachingDefinitionsITA(cfg,
                                                            genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));
            var inData  = ita.InOut.In;
            var outData = ita.InOut.Out;

            Assert.AreEqual(inData[cfg[0]].Count, 0);
            Assert.AreEqual(outData[cfg[0]].Count, 1);
            Assert.AreEqual(inData[cfg[1]].Count, 1);
            Assert.AreEqual(outData[cfg[1]].Count, 2);
            Assert.AreEqual(inData[cfg[2]].Count, 2);
            Assert.AreEqual(outData[cfg[2]].Count, 2);
            Assert.AreEqual(inData[cfg[3]].Count, 2);
            Assert.AreEqual(outData[cfg[3]].Count, 4);
            Assert.AreEqual(inData[cfg[4]].Count, 4);
            Assert.AreEqual(outData[cfg[4]].Count, 4);
            Assert.AreEqual(inData[cfg[5]].Count, 1);
            Assert.AreEqual(outData[cfg[5]].Count, 2);
            Assert.AreEqual(inData[cfg[6]].Count, 6);
            Assert.AreEqual(outData[cfg[6]].Count, 5);
            Assert.AreEqual(inData[cfg[7]].Count, 8);
            Assert.AreEqual(outData[cfg[7]].Count, 9);

            Assert.IsTrue(outData[cfg[0]].Contains(cfg[0, 0]));

            Assert.IsTrue(inData[cfg[1]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[1, 0]));

            Assert.IsTrue(inData[cfg[2]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[1, 0]));

            Assert.IsTrue(inData[cfg[3]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[3, 1]));

            Assert.IsTrue(inData[cfg[4]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[4]].Contains(cfg[1, 0]));
            Assert.IsTrue(inData[cfg[4]].Contains(cfg[3, 0]));
            Assert.IsTrue(inData[cfg[4]].Contains(cfg[3, 1]));
            Assert.IsTrue(outData[cfg[4]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[4]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[4]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[4]].Contains(cfg[3, 1]));

            Assert.IsTrue(inData[cfg[5]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[5]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[5]].Contains(cfg[5, 0]));

            Assert.IsTrue(inData[cfg[6]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[6]].Contains(cfg[5, 0]));
            Assert.IsTrue(inData[cfg[6]].Contains(cfg[6, 0]));
            Assert.IsTrue(inData[cfg[6]].Contains(cfg[6, 1]));
            Assert.IsTrue(inData[cfg[6]].Contains(cfg[6, 2]));
            Assert.IsTrue(inData[cfg[6]].Contains(cfg[6, 3]));
            Assert.IsTrue(outData[cfg[6]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[6]].Contains(cfg[6, 0]));
            Assert.IsTrue(outData[cfg[6]].Contains(cfg[6, 1]));
            Assert.IsTrue(outData[cfg[6]].Contains(cfg[6, 2]));
            Assert.IsTrue(outData[cfg[6]].Contains(cfg[6, 3]));

            Assert.IsTrue(inData[cfg[7]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[1, 0]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[3, 0]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[3, 1]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[6, 0]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[6, 1]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[6, 2]));
            Assert.IsTrue(inData[cfg[7]].Contains(cfg[6, 3]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[3, 1]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[6, 0]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[6, 1]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[6, 2]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[6, 3]));
            Assert.IsTrue(outData[cfg[7]].Contains(cfg[7, 0]));
        }
예제 #6
0
        public void Execute_NestedLoopWithCounter()
        {
            /*
             * a = 1;
             * for (i = 1 to 10)
             *     for (j = 1 to 10)
             *         a = a + 1;
             */

            var tacContainer = Utils.GetNestedLoopWithCounterInTAC();
            var cfg          = new ControlFlowGraph(tacContainer);

            var genKillVisitor = new GenKillVisitor();
            var ita            = new ReachingDefinitionsITA(cfg,
                                                            genKillVisitor.GenerateReachingDefinitionForBlocks(cfg.SourceBasicBlocks));
            var inData  = ita.InOut.In;
            var outData = ita.InOut.Out;

            Assert.AreEqual(inData[cfg[0]].Count, 0);
            Assert.AreEqual(outData[cfg[0]].Count, 2);
            Assert.AreEqual(inData[cfg[1]].Count, 8);
            Assert.AreEqual(outData[cfg[1]].Count, 8);
            Assert.AreEqual(inData[cfg[2]].Count, 9);
            Assert.AreEqual(outData[cfg[2]].Count, 7);
            Assert.AreEqual(inData[cfg[3]].Count, 7);
            Assert.AreEqual(outData[cfg[3]].Count, 6);

            Assert.IsTrue(outData[cfg[0]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[0]].Contains(cfg[0, 1]));

            Assert.IsTrue(inData[cfg[1]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[0, 1]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[2, 0]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[2, 1]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[2, 2]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[2, 3]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[3, 0]));
            Assert.IsTrue(inData[cfg[1]].Contains(cfg[3, 1]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[0, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[0, 1]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[1, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[2, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[2, 1]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[2, 3]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[1]].Contains(cfg[3, 1]));

            Assert.IsTrue(inData[cfg[2]].Contains(cfg[0, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[0, 1]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[1, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[2, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[2, 1]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[2, 2]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[2, 3]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[3, 0]));
            Assert.IsTrue(inData[cfg[2]].Contains(cfg[3, 1]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[0, 1]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[2, 0]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[2, 1]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[2, 2]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[2, 3]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[2]].Contains(cfg[3, 1]));

            Assert.IsTrue(inData[cfg[3]].Contains(cfg[0, 1]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[2, 0]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[2, 1]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[2, 2]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[2, 3]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[3, 0]));
            Assert.IsTrue(inData[cfg[3]].Contains(cfg[3, 1]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[2, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[2, 1]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[2, 2]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[2, 3]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[3, 0]));
            Assert.IsTrue(outData[cfg[3]].Contains(cfg[3, 1]));
        }
예제 #7
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();
        }