Exemplo n.º 1
0
        public void Optimize_RightOptimized2()
        {
            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 expectedResult = new ThreeAddressCode();

            Utils.AddAssignmentNode(expectedResult, null, "t3", "4", "*", "i");
            Utils.AddAssignmentNode(expectedResult, null, "t1", "t3");
            Utils.AddAssignmentNode(expectedResult, null, "a1", "t1");
            Utils.AddAssignmentNode(expectedResult, null, "t2", "b");
            Utils.AddAssignmentNode(expectedResult, null, "i", "1");
            Utils.AddIfGotoNode(expectedResult, null, "L1", "t2");
            Utils.AddGotoNode(expectedResult, null, "L2");
            Utils.AddAssignmentNode(expectedResult, "L1", "t3", "4", "*", "i");
            Utils.AddAssignmentNode(expectedResult, "L2", "a3", "t3");
            Utils.AddAssignmentNode(expectedResult, null, "t3", "4", "*", "i");
            Utils.AddAssignmentNode(expectedResult, null, "t4", "t3");
            Utils.AddAssignmentNode(expectedResult, null, "a2", "t4");

            var cfg = new ControlFlowGraph(tacContainer);
            var expectedResultcfg = new ControlFlowGraph(expectedResult);

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

            var availableExpressionsITA = new AvailableExpressionsITA(cfg, availExprContainers);

            var  availableExprOptimization = new AvailableExprOptimization();
            bool isOptimized     = availableExprOptimization.Optimize(availableExpressionsITA);
            var  basicBlockItems = cfg.SourceBasicBlocks.BasicBlockItems;
            var  codeText        = cfg.SourceBasicBlocks.BasicBlockItems
                                   .Select(bl => bl.ToString()).Aggregate((b1, b2) => b1 + b2);

            Assert.IsTrue(isOptimized);
            Assert.AreEqual(cfg.ToString(), expectedResultcfg.ToString());
        }
Exemplo n.º 2
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_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 = с
             * 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);

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

            var ita = new AvailableExpressionsITA(cfg, availExprContainers);

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

            var expectedIn0 = new TacAssignmentNode();

            var expectedIn1 = new TacAssignmentNode();

            expectedIn1.LeftPartIdentifier = "t1";
            expectedIn1.FirstOperand       = "b";

            var expectedOut0 = new TacAssignmentNode();

            expectedOut0.LeftPartIdentifier = "t1";
            expectedOut0.FirstOperand       = "b";

            Assert.AreEqual(expectedIn1.ToString(), inData[cfg[1]].First().ToString());
            Assert.AreEqual(expectedIn1.ToString(), inData[cfg[2]].First().ToString());
            Assert.AreEqual(expectedIn1.ToString(), inData[cfg[3]].First().ToString());

            Assert.AreEqual(expectedOut0.ToString(), outData[cfg[1]].First().ToString());
            Assert.AreEqual(expectedOut0.ToString(), outData[cfg[2]].First().ToString());
            Assert.AreEqual(expectedOut0.ToString(), outData[cfg[3]].First().ToString());
        }