Beispiel #1
0
        /// <summary>
        ///     Конструктор
        /// </summary>
        /// <param name="code">экземпляр программы в формате трехадресного кода</param>
        public ControlFlowGraph(TACode code)
        {
            Code = code;
            _cfgNodes = new List<BasicBlock>();

            CreateCFGNodes();
        }
Beispiel #2
0
        public static NumeratedGraph StraightOrder(this TACode code)
        {
            var graph = new NumeratedGraph(code, null);

            graph.Numerator = GraphNumerator.BackOrder(graph).Reverse(graph);
            return(graph);
        }
        public TACode ApplyAllOptimizations(TACode code)
        {
            List <IOptimization> o1Optimizations = BasicBlockOptimizationList();
            var canApplyAny = true;

            while (canApplyAny)
            {
                canApplyAny = false;
                var blocks   = code.CreateBasicBlockList().ToList();
                var codeList = new List <Node>();

                foreach (var b in blocks)
                {
                    var block = b.CodeList.ToList();
                    for (int i = 0; i < o1Optimizations.Count; i++)
                    {
                        block       = o1Optimizations[i].Optimize(block, out var applied);
                        canApplyAny = canApplyAny || applied;
                    }
                    codeList.AddRange(block);
                }

                code          = new TACode();
                code.CodeList = codeList;


                foreach (var line in code.CodeList)
                {
                    code.LabeledCode[line.Label] = line;
                }
            }

            return(code);
        }
Beispiel #4
0
        public void GenerateCFG(TACode code)
        {
            try
            {
                var cfg = new ControlFlowGraph(code);

                string graph = BuildDotGraph(cfg);
                File.WriteAllText(@"cfg_graph.txt", graph);

                var processQuery          = new GetStartProcessQuery();
                var processStartInfoQuery = new GetProcessStartInfoQuery();
                var registerLayout        = new RegisterLayoutPluginCommand(processStartInfoQuery, processQuery);
                var wrapper = new GraphGeneration(processQuery, processStartInfoQuery, registerLayout)
                {
                    RenderingEngine = Enums.RenderingEngine.Dot
                };
                byte[] output = wrapper.GenerateGraph(graph, Enums.GraphReturnType.Png);

                using (var stream = new MemoryStream(output))
                {
                    var image = Image.FromStream(stream);
                    GenerationCompleted(null, image);
                }

                CfgGenerated(null, cfg);
            }
            catch (Exception ex)
            {
                GenerationErrored(null, ex);
            }
        }
Beispiel #5
0
        public ControlFlowGraph(TACode code)
        {
            _code      = code;
            _blockList = _code.CreateBasicBlockList().ToList();

            CFGNodes = new SortedSet <CFGNode>();
            CreateCFGNodes();
        }
        public static TACode LabelCode(TACode code)
        {
            foreach (var l in code.CodeList.ToList())
            {
                code.LabeledCode[l.Label] = l;
            }

            return(code);
        }
Beispiel #7
0
        public InOutData <Dictionary <Guid, VarValue> > TempFunc(TACode taCode, ControlFlowGraph cfg)
        {
            Operations       ops = new Operations(taCode);
            TransferFunction f   = new TransferFunction();

            IterativeAlgorithm itAlg = new IterativeAlgorithm();
            var result = itAlg.Analyze(cfg, ops, f);

            return(result);
        }
        public VarInfoTable(TACode code)
        {
            foreach (var line in code.CodeList.OfType <Assign>())
            {
                var v = line.Result;
                base[v.Id] = new VarInfo();
            }

            this.code = code;
        }
Beispiel #9
0
 /// <summary>
 /// Конструктор для TransferFunction
 /// </summary>
 /// <param name="code">Необходим для списка выражений-присвоений</param>
 public TransferFunction(TACode code)
 {
     AssignNodes = new List <Assign>();
     foreach (var node in code.CodeList)
     {
         if ((node is Assign ass) &&
             (!(ass.Left is null) && !(ass.Right is null)) &&
             (ass.Left is Var || ass.Right is Var))
         {
             AssignNodes.Add(ass);
         }
     }
 }
 public void GenerateIlCode(TACode code)
 {
     try
     {
         var trans = new TAcode2ILcodeTranslator();
         trans.Translate(code);
         _ilProgram = trans;
         GenerationCompleted(null, trans);
     }
     catch (Exception ex)
     {
         GenerationErrored(null, ex);
     }
 }
        private TACode ApplyOptimizations(TACode code)
        {
            var optList = BlockOptimizationList();

            bool canApplyAny = true;

            TACode newCode = code;

            while (canApplyAny)
            {
                canApplyAny = false;
                var codeList = newCode.CreateBasicBlockList();
                newCode = new TACode();
                foreach (var b in codeList)
                {
                    List <Node> block = b.CodeList.ToList();

                    foreach (var opt in optList)
                    {
                        block       = opt.Optimize(block, out var applied);
                        canApplyAny = canApplyAny || applied;
                    }

                    foreach (var node in block)
                    {
                        newCode.AddNode(node);
                    }
                }
                foreach (var line in newCode.CodeList)
                {
                    newCode.LabeledCode[line.Label] = line;
                }
            }

            if (OptimizationList[Optimizations.GlobalConstProp])
            {
                var opt = new GlobalConstantPropogationAlt(newCode);
                newCode = opt.Optimize();
                AllOptimizations.LabelCode(newCode);
            }

            if (RemoveDeadVariables)
            {
                var rmOpt = new RemoveDeadVariablesCFG(newCode);
                newCode = rmOpt.CodeNew;
            }


            return(newCode);
        }
Beispiel #12
0
 public Operations(TACode code)
 {
     upper = new HashSet <Guid>();
     foreach (var node in code.CodeList)
     {
         //Если узел - присваивание и хотя бы один операнд - это переменная, то добавляем его в верхнюю границу
         if (node is Assign ass && (!(ass.Left is null) && !(ass.Right is null)))
         {
             if (ass.Left is Var || ass.Right is Var)
             {
                 upper.Add(ass.Label);
             }
         }
     }
 }
        public Operations(TACode code)
        {
            Lower = new VarInfoTable(code);
            var keys = Lower.Keys.ToArray();

            foreach (var k in keys)
            {
                Lower[k] = new VarInfo(VarInfo.Flag.NAC);
            }

            Upper = new VarInfoTable(code);
            foreach (var k in keys)
            {
                Upper[k] = new VarInfo(VarInfo.Flag.UNDEF);
            }
        }
        public void GenerateThreeAddrCode(object sender, Parser.AST.BlockNode root)
        {
            try
            {
                var visitor = new TACodeVisitor();
                root.Visit(visitor);

                TACode code = ApplyOptimizations(visitor.Code);
                GenerationCompleted(null, code);
                PostProcess(code);
            }
            catch (Exception ex)
            {
                GenerationErrored(null, ex);
            }
        }
 public Operations(TACode code)
 {
     upper = new Dictionary <Guid, VarValue>();
     foreach (var node in code.CodeList)
     {
         if (node is Assign)
         {
             var asNode = node as Assign;
             // т.к. node as Assign всегда Var верхние значения инициализированы как NAC
             if (!upper.ContainsKey((asNode.Result as Var).Id))
             {
                 upper.Add((asNode.Result as Var).Id, new VarValue(asNode.Result));
             }
             if (asNode.Left is Var && !upper.ContainsKey((asNode.Left as Var).Id))
             {
                 upper.Add((asNode.Left as Var).Id, new VarValue(asNode.Left as Var));
             }
             if (asNode.Right is Var && !upper.ContainsKey((asNode.Right as Var).Id))
             {
                 upper.Add((asNode.Right as Var).Id, new VarValue(asNode.Right as Var));
             }
         }
     }
     lower = new Dictionary <Guid, VarValue>();
     foreach (var node in code.CodeList)
     {
         if (node is Assign)
         {
             var asNode = node as Assign;
             // UNDEF
             if (!lower.ContainsKey((asNode.Result as Var).Id))
             {
                 lower.Add((asNode.Result as Var).Id, new VarValue());
             }
             if (asNode.Left is Var && !lower.ContainsKey((asNode.Left as Var).Id))
             {
                 lower.Add((asNode.Left as Var).Id, new VarValue());
             }
             if (asNode.Right is Var && !lower.ContainsKey((asNode.Right as Var).Id))
             {
                 lower.Add((asNode.Right as Var).Id, new VarValue());
             }
         }
     }
 }
Beispiel #16
0
        public TACode Optimize(TACode taCode, out bool applied)
        {
            var app              = false;
            var visited          = new Dictionary <Guid, bool>();
            ControlFlowGraph cfg = new ControlFlowGraph(taCode);
            var ioData           = TempFunc(taCode, cfg);

            foreach (var node in taCode.CodeList.ToList().OfType <Assign>())
            {
                visited[node.Result.Id] = false;
            }

            for (int j = taCode.CodeList.Count() - 1; j > 0; j--)
            {
                var node = taCode.CodeList.ElementAt(j) as Assign;
                if (node != null)
                {
                    for (int i = 0; i < cfg.CFGNodes.Count(); i++)
                    {
                        if (ioData[cfg.CFGNodes.ElementAt(i)].Item1.ContainsKey(node.Result.Id) && ioData[cfg.CFGNodes.ElementAt(i)].Item1[node.Result.Id].varType is VarValue.Type.CONST)
                        {
                            if (visited[node.Result.Id] == true)
                            {
                                break;
                            }
                            visited[node.Result.Id] = true;
                            node.Right         = ioData[cfg.CFGNodes.ElementAt(i)].Item1[node.Result.Id].value;
                            node.Left          = null;
                            node.Operation     = OpCode.Copy;
                            taCode.CodeList[j] = node;
                        }
                    }
                }
            }

            applied = app;
            return(taCode);
        }
        public void ReachingDefenitionTest0()
        {
            var taCode = new TACode();

            var ass1 = new Assign
            {
                Left      = new IntConst(1000),
                Operation = OpCode.Minus,
                Right     = new IntConst(5),
                Result    = new Var()
            };
            var ass2 = new Assign
            {
                Left      = new IntConst(2000),
                Operation = OpCode.Copy,
                Result    = new Var()
            };
            var ass3 = new Assign
            {
                Operation = OpCode.Copy,
                Right     = new IntConst(3000),
                Result    = new Var()
            };
            var ass4 = new Assign
            {
                Left      = ass1.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(1),
                Result    = ass1.Result
            };

            ass4.IsLabeled = true;
            var ass5 = new Assign
            {
                Left      = ass2.Result,
                Operation = OpCode.Minus,
                Right     = new IntConst(4),
                Result    = ass2.Result
            };
            var ass6 = new Assign
            {
                Operation = OpCode.Copy,
                Right     = new IntConst(4000),
                Result    = ass3.Result
            };
            var ass7 = new Assign
            {
                Operation = OpCode.Copy,
                Right     = new IntConst(5000),
                Result    = ass1.Result
            };

            ass7.IsLabeled = true;
            var ifgt1 = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = ass7.Label
            };
            var ifgt2 = new IfGoto
            {
                Condition   = new IntConst(2),
                TargetLabel = ass4.Label
            };
            var empty = new Empty {
            };
            {
                taCode.AddNode(ass1);
                taCode.AddNode(ass2);
                taCode.AddNode(ass3);
                taCode.AddNode(ass4);
                taCode.AddNode(ass5);
                taCode.AddNode(ifgt1);
                taCode.AddNode(ass6);
                taCode.AddNode(ass7);
                taCode.AddNode(ifgt2);
                taCode.AddNode(empty);
            }
            var cfg = new ControlFlowGraph(taCode);

            taCode.CreateBasicBlockList();

            var op = new Operations(taCode);
            var tf = new TransferFunction(taCode);

            var tmp = taCode.ToString();

            var(gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(0), op);
            Assert.True(gen.SetEquals(new HashSet <Guid> {
                ass1.Label, ass2.Label, ass3.Label
            }));
            Assert.True(kill.SetEquals(new HashSet <Guid> {
                ass4.Label, ass5.Label, ass6.Label, ass7.Label
            }));

            (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(1), op);
            Assert.True(gen.SetEquals(new HashSet <Guid> {
                ass4.Label, ass5.Label
            }));
            Assert.True(kill.SetEquals(new HashSet <Guid> {
                ass1.Label, ass2.Label, ass7.Label
            }));

            (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(2), op);
            Assert.True(gen.SetEquals(new HashSet <Guid> {
                ass6.Label
            }));
            Assert.True(kill.SetEquals(new HashSet <Guid> {
                ass3.Label
            }));

            (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(3), op);
            Assert.True(gen.SetEquals(new HashSet <Guid> {
                ass7.Label
            }));
            Assert.True(kill.SetEquals(new HashSet <Guid> {
                ass1.Label, ass4.Label
            }));

            var inout = new GenericIterativeAlgorithm <HashSet <Guid> >()
            {
                Finish = (a, b) =>
                {
                    var(a1, a2) = a;
                    var(b1, b2) = b;

                    return(!a2.Except(b2).Any());
                },
                Comparer      = (x, y) => !x.Except(y).Any(),
                Fill          = () => (op.Lower, op.Lower),
                DebugToString = (x) => x.Aggregate("", (s, y) => s + ", " + TACodeNameManager.Instance[y])
            }.Analyze(cfg, op, tf);
 public TransferFunction(TACode ta) => taCode = ta;
        public void Test1()
        {
            var taCode = new TACode();
            var assgn1 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(91),
                Result    = new Var("b")
            };
            var assgn2 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = assgn1.Result,
                Result    = new Var("c")
            };
            var assgn3 = new Assign()
            {
                Left      = assgn1.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(10),
                Result    = new Var("d")
            };
            var ifgtH = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = assgn3.Label
            };

            assgn3.IsLabeled = true;

            var assgn4 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(2),
                Result    = new Var("j")
            };
            var assgn5 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(0),
                Result    = assgn3.Result
            };
            var assgn6 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = assgn2.Result,
                Result    = assgn3.Result
            };
            var ifgtX = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = assgn6.Label
            };

            assgn6.IsLabeled = true;

            taCode.AddNode(assgn1);
            taCode.AddNode(assgn2);
            taCode.AddNode(ifgtH);
            taCode.AddNode(assgn3);
            taCode.AddNode(assgn4);
            taCode.AddNode(assgn5);
            taCode.AddNode(ifgtX);
            taCode.AddNode(assgn6);

            var cfg = new ControlFlowGraph(taCode);
            IterativeAlgorithmAV ItAV = new IterativeAlgorithmAV(cfg);

            Assert.AreEqual(ItAV.IN.ElementAt(0).Value.Count, 0);
            Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(0), assgn1.Result);
            Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(1), assgn2.Result);
            Assert.AreEqual(ItAV.IN.ElementAt(2).Value.ElementAt(0), assgn2.Result);

            Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(0), assgn1.Result);
            Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(1), assgn2.Result);
            Assert.AreEqual(ItAV.OUT.ElementAt(1).Value.ElementAt(0), assgn2.Result);
            Assert.AreEqual(ItAV.OUT.ElementAt(2).Value.Count, 0);
        }
        public void ReachingExpressionsTest1()
        {
            var taCode = new TACode();

            //TAC выглядит следующим образом

            /**
             * 0)   t0 = 3            |
             * 1)   t1 = 5 + t0       | B1
             * 2)   t2 = t1 + t0      |
             *
             *
             * 3)   t3 = 4 + t2       |
             * 4)   t1 = 10           | B2
             * 5)   if (1) goto 3)    |
             *
             *
             * 6)   t4 = t1 + 5       |
             * 7)   t5 = t3 + t0      |
             * 8)   t0 = 100          | B3
             * 9)   if (2) goto 6)    |
             *
             *
             * 10)  t6 = t5 + 10      |
             * 11)  t7 = t6 + 10      |
             * 12)  t8 = t6 + t7      | B4
             * 13)  t6 = 3            |
             * 14)  t5 = 100          |
             *
             **/

            var ass1 = new Assign
            {
                Operation = OpCode.Plus,
                Right     = new IntConst(3),
                Result    = new Var()
            };

            var ass2 = new Assign
            {
                Left      = new IntConst(5),
                Operation = OpCode.Plus,
                Right     = ass1.Result,
                Result    = new Var()
            };

            var ass3 = new Assign
            {
                Left      = ass2.Result,
                Operation = OpCode.Plus,
                Right     = ass1.Result,
                Result    = new Var()
            };

            var ass4 = new Assign
            {
                Left      = new IntConst(4),
                Operation = OpCode.Plus,
                Right     = ass3.Result,
                Result    = new Var()
            };

            var ass5 = new Assign
            {
                Operation = OpCode.Plus,
                Right     = new IntConst(10),
                Result    = ass2.Result
            };

            var ifgt1 = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = ass4.Label
            };

            ass4.IsLabeled = true;

            var ass6 = new Assign
            {
                Left      = ass2.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(5),
                Result    = new Var()
            };

            var ass7 = new Assign
            {
                Left      = ass4.Result,
                Operation = OpCode.Plus,
                Right     = ass1.Result,
                Result    = new Var()
            };

            var ass8 = new Assign
            {
                Operation = OpCode.Plus,
                Right     = new IntConst(100),
                Result    = ass1.Result
            };

            var ifgt2 = new IfGoto
            {
                Condition   = new IntConst(2),
                TargetLabel = ass6.Label
            };

            ass6.IsLabeled = true;

            var ass9 = new Assign
            {
                Left      = ass7.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(10),
                Result    = new Var()
            };

            var ass10 = new Assign
            {
                Left      = ass9.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(10),
                Result    = new Var()
            };

            var ass11 = new Assign
            {
                Left      = ass9.Result,
                Operation = OpCode.Plus,
                Right     = ass10.Result,
                Result    = new Var()
            };

            var ass12 = new Assign
            {
                Operation = OpCode.Plus,
                Right     = new IntConst(3),
                Result    = ass9.Result
            };

            var ass13 = new Assign
            {
                Operation = OpCode.Plus,
                Right     = new IntConst(100),
                Result    = ass7.Result
            };

            taCode.AddNode(ass1);
            taCode.AddNode(ass2);
            taCode.AddNode(ass3);
            taCode.AddNode(ass4);
            taCode.AddNode(ass5);
            taCode.AddNode(ifgt1);
            taCode.AddNode(ass6);
            taCode.AddNode(ass7);
            taCode.AddNode(ass8);
            taCode.AddNode(ifgt2);
            taCode.AddNode(ass9);
            taCode.AddNode(ass10);
            taCode.AddNode(ass11);
            taCode.AddNode(ass12);
            taCode.AddNode(ass13);

            /**         CFG имеет следующий вид
             *
             *                  B1
             *                   |
             *                   |   ____
             *                   v  /    \
             *                  B2-v______|
             *                   |
             *                   |   ____
             *                   v  /    \
             *                  B3-v______|
             *                   |
             *                   |
             *                   V
             *                  B4
             * */

            var cfg = new ControlFlowGraph(taCode);

            /**************************Reaching definition test*************************/
            var op        = new Operations(taCode);
            var algo      = new IterativeAlgorithm();
            var transFunc = new TransferFunction(taCode);
            var inout     = algo.Analyze(cfg, op, transFunc);

            //Тестирование множест e_gen и e_kill для каждого базового блока
            var(e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(0));
            Assert.True(e_gen.SetEquals(new HashSet <Guid> {
                ass2.Label, ass3.Label
            }));
            Assert.True(e_kill.SetEquals(new HashSet <Guid> {
                ass4.Label, ass6.Label, ass7.Label
            }));

            (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(1));
            Assert.True(e_gen.SetEquals(new HashSet <Guid> {
                ass4.Label
            }));
            Assert.True(e_kill.SetEquals(new HashSet <Guid> {
                ass3.Label, ass6.Label, ass7.Label
            }));

            (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(2));
            Assert.True(e_gen.SetEquals(new HashSet <Guid> {
                ass6.Label
            }));
            Assert.True(e_kill.SetEquals(new HashSet <Guid> {
                ass2.Label, ass3.Label, ass7.Label, ass9.Label
            }));

            (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(3));
            Assert.True(e_gen.SetEquals(new HashSet <Guid> {
            }));
            Assert.True(e_kill.SetEquals(new HashSet <Guid> {
                ass9.Label, ass10.Label, ass11.Label
            }));

            //Текстирование IN/OUT множеств для каждого ББл
            var trueInOut = new DFA.InOutData <HashSet <System.Guid> >();

            trueInOut.Add(cfg.CFGNodes.ElementAt(0),
                          (new HashSet <Guid>(),
                           new HashSet <Guid> {
                ass2.Label, ass3.Label
            })
                          );
            trueInOut.Add(cfg.CFGNodes.ElementAt(1),
                          (new HashSet <Guid> {
                ass2.Label, ass3.Label
            },
                           new HashSet <Guid> {
                ass2.Label, ass4.Label
            })
                          );
            trueInOut.Add(cfg.CFGNodes.ElementAt(2),
                          (new HashSet <Guid> {
                ass2.Label, ass4.Label
            },
                           new HashSet <Guid> {
                ass4.Label, ass6.Label
            })
                          );
            trueInOut.Add(cfg.CFGNodes.ElementAt(3),
                          (new HashSet <Guid> {
                ass4.Label, ass6.Label
            },
                           new HashSet <Guid> {
                ass4.Label, ass6.Label
            })
                          );

            foreach (var x in cfg.CFGNodes)
            {
                HashSet <Guid> toutItem1 = trueInOut[x].Item1;
                HashSet <Guid> outItem1  = inout[x].Item1;
                HashSet <Guid> toutItem2 = trueInOut[x].Item2;
                HashSet <Guid> outItem2  = inout[x].Item2;

                var inEq  = toutItem1.SetEquals(outItem1);
                var outEq = toutItem2.SetEquals(outItem2);
                Assert.True(inEq && outEq);
            }
        }
        public void Test1()
        {
            var taCodeConstantFolding = new TACode();
            var assgn1 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new Var(),
                Result    = new Var()
            };
            var assgn2 = new Assign()
            {
                Left      = new IntConst(20),
                Operation = OpCode.Mul,
                Right     = new IntConst(3),
                Result    = new Var()
            };
            var assgn3 = new Assign()
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = new IntConst(1),
                Result    = new Var()
            };
            var assgn4 = new Assign()
            {
                Left      = new IntConst(100),
                Operation = OpCode.Div,
                Right     = new IntConst(50),
                Result    = new Var()
            };
            var assgn5 = new Assign()
            {
                Left      = new IntConst(30),
                Operation = OpCode.Minus,
                Right     = new IntConst(20),
                Result    = assgn1.Result
            };
            var assgn6 = new Assign()
            {
                Left      = assgn2.Result,
                Operation = OpCode.Plus,
                Right     = assgn5.Result,
                Result    = new Var()
            };

            taCodeConstantFolding.AddNode(assgn1);
            taCodeConstantFolding.AddNode(assgn2);
            taCodeConstantFolding.AddNode(assgn3);
            taCodeConstantFolding.AddNode(assgn4);
            taCodeConstantFolding.AddNode(assgn5);
            taCodeConstantFolding.AddNode(assgn6);

            var optConstFold = new ConstantFolding();

            optConstFold.Optimize(taCodeConstantFolding.CodeList.ToList(), out var applConstFold);

            /*
             * a = b
             * c = 20 * 3    -----> c = 60
             * d = 10 + 1    -----> d = 11
             * e = 100 / 50  -----> e = 2
             * a = 30 - 20   -----> a = 10
             * k = c + a
             */

            Assert.AreEqual(assgn2.Right, 60);
            Assert.AreEqual(assgn3.Right, 11);
            Assert.AreEqual(assgn4.Right, 2);
            Assert.AreEqual(assgn5.Right, 10);
            Assert.True(true);
        }
Beispiel #22
0
        private TACode GetTestGraph1()
        {
            var taCode = new TACode();

            var ass1 = new Assign
            {
                Left      = new IntConst(3),
                Operation = OpCode.Minus,
                Right     = new IntConst(5),
                Result    = new Var()
            };

            var ass2 = new Assign
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = new IntConst(2),
                Result    = new Var()
            };

            var ass3 = new Assign
            {
                Operation = OpCode.Minus,
                Right     = new IntConst(1),
                Result    = new Var()
            };

            var ifgt1 = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = ass3.Label
            };

            ass3.IsLabeled = true;

            var ass4 = new Assign
            {
                Left      = ass3.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(1999),
                Result    = new Var()
            };

            var ifgt2 = new IfGoto
            {
                Condition   = new IntConst(2),
                TargetLabel = ass2.Label
            };

            ass2.IsLabeled = true;

            var ass5 = new Assign
            {
                Left      = new IntConst(7),
                Operation = OpCode.Mul,
                Right     = new IntConst(4),
                Result    = new Var()
            };

            var ass6 = new Assign
            {
                Left      = new IntConst(100),
                Operation = OpCode.Div,
                Right     = new IntConst(25),
                Result    = new Var()
            };

            taCode.AddNode(ass1);
            taCode.AddNode(ass2);
            taCode.AddNode(ass3);
            taCode.AddNode(ifgt1);
            taCode.AddNode(ass4);
            taCode.AddNode(ifgt2);
            taCode.AddNode(ass5);
            taCode.AddNode(ass6);
            return(taCode);
        }
        public void Test1()
        {
            var taCodeConstProp = new TACode();
            var assgn1          = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(10),
                Result    = new Var()
            };
            var assgn2 = new Assign()
            {
                Left      = new Var(),
                Operation = OpCode.Minus,
                Right     = assgn1.Result,
                Result    = new Var()
            };
            var assgn3 = new Assign()
            {
                Left      = assgn2.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(1),
                Result    = new Var()
            };
            var assgn4 = new Assign()
            {
                Left      = assgn3.Result,
                Operation = OpCode.Mul,
                Right     = assgn1.Result,
                Result    = new Var()
            };
            var assgn5 = new Assign()
            {
                Left      = new IntConst(30),
                Operation = OpCode.Minus,
                Right     = new IntConst(20),
                Result    = assgn1.Result
            };
            var assgn6 = new Assign()
            {
                Left      = assgn2.Result,
                Operation = OpCode.Plus,
                Right     = assgn5.Result,
                Result    = new Var()
            };

            taCodeConstProp.AddNode(assgn1);
            taCodeConstProp.AddNode(assgn2);
            taCodeConstProp.AddNode(assgn3);
            taCodeConstProp.AddNode(assgn4);
            taCodeConstProp.AddNode(assgn5);
            taCodeConstProp.AddNode(assgn6);

            var optConstProp = new CopyPropagation();

            optConstProp.Optimize(taCodeConstProp.CodeList.ToList(), out var applCopProp);

            /*
             * a = 10
             * c = b - a     -----> c = b - 10
             * d = c + 1
             * e = d * a     -----> e = d * 10
             * a = 30 - 20
             * k = c + a     -----> k = c + a
             */

            Assert.AreEqual(assgn2.Right, assgn1.Result);
            Assert.AreEqual(assgn4.Right, assgn1.Result);
            Assert.AreNotSame(assgn6.Right, assgn1.Result);
            Assert.True(true);
        }
Beispiel #24
0
        public void Translate(TACode tACode)
        {
            gen = new GenCodeCreator();
            gen.Emit(OpCodes.Nop);
            foreach (var currentInstuction in tACode.CodeList)
            {
                if (currentInstuction.IsLabeled)
                {
                    var curLabel = gen.DefineLabel();
                    labels.Add(currentInstuction.Label.ToString(), curLabel);
                }
            }


            foreach (var currentInstuction in tACode.CodeList)
            {
                if (currentInstuction.IsLabeled)
                {
                    gen.Emit(OpCodes.Nop);
                    gen.MarkLabel(labels[currentInstuction.Label.ToString()]);
                }
                switch (currentInstuction)
                {
                case Assign assignNode:
                    try
                    {
                        if (!vars.ContainsKey(assignNode.Result.Id.ToString()))
                        {
                            vars.Add(assignNode.Result.Id.ToString(), gen.DeclareLocal(typeof(int)));
                        }

                        if (assignNode.Left != null)
                        {
                            if (assignNode.Left is Var)
                            {
                                gen.Emit(OpCodes.Ldloc, vars[(assignNode.Left as Var).Id.ToString()]);
                            }
                            else
                            {
                                gen.Emit(OpCodes.Ldc_I4, (assignNode.Left as IntConst).Num);
                            }
                        }


                        if (assignNode.Right is Var)
                        {
                            gen.Emit(OpCodes.Ldloc, vars[(assignNode.Right as Var).Id.ToString()]);
                        }
                        else
                        {
                            gen.Emit(OpCodes.Ldc_I4, (assignNode.Right as IntConst).Num);
                        }


                        switch (assignNode.Operation)
                        {
                        case ThreeAddrCode.OpCode.Plus:
                            if (assignNode.Left != null)
                            {
                                gen.Emit(OpCodes.Add);
                            }
                            break;

                        case ThreeAddrCode.OpCode.Minus:
                            if (assignNode.Left != null)
                            {
                                gen.Emit(OpCodes.Sub);
                            }
                            else
                            {
                                gen.Emit(OpCodes.Neg);
                            }
                            break;

                        case ThreeAddrCode.OpCode.Mul:
                            gen.Emit(OpCodes.Mul);
                            break;

                        case ThreeAddrCode.OpCode.Div:
                            gen.Emit(OpCodes.Div);
                            break;

                        case ThreeAddrCode.OpCode.UnaryMinus:
                            gen.Emit(OpCodes.Neg);
                            break;

                        case ThreeAddrCode.OpCode.Copy:
                            break;

                        case ThreeAddrCode.OpCode.Greater:
                            gen.Emit(OpCodes.Cgt);
                            break;

                        case ThreeAddrCode.OpCode.Less:
                            gen.Emit(OpCodes.Clt);
                            break;

                        case ThreeAddrCode.OpCode.GreaterEq:
                            gen.Emit(OpCodes.Clt);
                            gen.Emit(OpCodes.Ldc_I4_0);
                            gen.Emit(OpCodes.Ceq);
                            break;

                        case ThreeAddrCode.OpCode.LessEq:
                            gen.Emit(OpCodes.Cgt);
                            gen.Emit(OpCodes.Ldc_I4_0);
                            gen.Emit(OpCodes.Ceq);
                            break;

                        case ThreeAddrCode.OpCode.Equal:
                            gen.Emit(OpCodes.Ceq);
                            break;

                        case ThreeAddrCode.OpCode.NotEqual:
                            gen.Emit(OpCodes.Ceq);
                            gen.Emit(OpCodes.Ldc_I4_0);
                            gen.Emit(OpCodes.Ceq);
                            break;

                        case ThreeAddrCode.OpCode.Not:
                            gen.Emit(OpCodes.Ldc_I4_0);
                            gen.Emit(OpCodes.Ceq);
                            break;
                        }
                        ;
                        gen.Emit(OpCodes.Stloc, vars[assignNode.Result.Id.ToString()]);
                    }
                    catch (KeyNotFoundException e)
                    {
                        throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." +
                                                                    " Использование необъявленной переменной");
                    }
                    break;

                case Empty emptyNode:
                    gen.Emit(OpCodes.Nop);
                    break;

                case IfGoto ifgotoNode:
                    try
                    {
                        var curLabel = gen.DefineLabel();
                        if (ifgotoNode.Condition is Var)
                        {
                            gen.Emit(OpCodes.Ldloc, vars[(ifgotoNode.Condition as Var).Id.ToString()]);
                        }
                        else
                        {
                            gen.Emit(OpCodes.Ldc_I4, (ifgotoNode.Condition as IntConst).Num);
                        }
                        gen.Emit(OpCodes.Brfalse, curLabel);
                        gen.Emit(OpCodes.Br, labels[ifgotoNode.TargetLabel.ToString()]);
                        gen.Emit(OpCodes.Nop);
                        gen.MarkLabel(curLabel);
                    }
                    catch (KeyNotFoundException e)
                    {
                        throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." +
                                                                    " Использование необъявленной переменной или переход по необъявлеенной метке");
                    }
                    break;

                case Goto gotoNode:
                    try
                    {
                        gen.Emit(OpCodes.Br, labels[gotoNode.TargetLabel.ToString()]);
                    }
                    catch (KeyNotFoundException e)
                    {
                        throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." +
                                                                    " Переход по необъявленной метке");
                    }
                    break;

                case Print printNode:
                    try
                    {
                        if (printNode.Data is Var)
                        {
                            gen.Emit(OpCodes.Ldloc, vars[(printNode.Data as Var).Id.ToString()]);
                        }
                        else
                        {
                            gen.Emit(OpCodes.Ldc_I4, (printNode.Data as IntConst).Num);
                        }
                        gen.EmitWriteLine();
                        break;
                    }
                    catch (KeyNotFoundException e)
                    {
                        throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." +
                                                                    " Использование необъявленной переменной");
                    }

                default:
                    throw new Exception("Unknow type of node of TAcode");
                }
            }
            gen.Emit(OpCodes.Ret);
        }
        private void PostProcess(TACode code)
        {
            string postProcessCode = OutputSanitizer.Sanitize(code.ToString(), OutputSanitizer.SanitizeLevel.TextBox);

            PrintableCodeGenerated(null, postProcessCode);
        }
Beispiel #26
0
        public void Test1()
        {
            var taCodeAllOptimizations = new TACode();
            var assgn1 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new Var(),
                Result    = new Var()
            };
            var assgn2 = new Assign()
            {
                Left      = assgn1.Right,
                Operation = OpCode.Minus,
                Right     = assgn1.Result,
                Result    = new Var()
            };
            var assgn3 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(20),
                Result    = new Var()
            };
            var assgn4 = new Assign()
            {
                Left      = new IntConst(20),
                Operation = OpCode.Mul,
                Right     = new IntConst(3),
                Result    = new Var()
            };
            var assgn5 = new Assign()
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = assgn3.Result,
                Result    = new Var()
            };

            taCodeAllOptimizations.AddNode(assgn1);
            taCodeAllOptimizations.AddNode(assgn2);
            taCodeAllOptimizations.AddNode(assgn3);
            taCodeAllOptimizations.AddNode(assgn4);
            taCodeAllOptimizations.AddNode(assgn5);

            /*
             * a = b
             * c = b - a   -----> c = 0
             * n = 20
             * c = 20 * 3  -----> c = 60
             * d = 10 + n  -----> d = 30
             */
            var allOptimizations = new AllOptimizations();

            allOptimizations.ApplyAllOptimizations(taCodeAllOptimizations);

            Assert.AreEqual(assgn2.Right, 0);
            Assert.AreEqual(assgn4.Right, 60);
            Assert.AreEqual(assgn5.Right, 30);
            Assert.True(true);
        }
 public TransferFunction(TACode code)
 {
     _code = code;
 }
 public Operations(TACode code)
 {
     upper = new HashSet <Guid>(code.CodeList.Where(x => x is Assign).Select(x => x.Label));
 }
Beispiel #29
0
 public NumeratedGraph(TACode code, IGraphNumerator numerator) : base(code)
 {
     Numerator = numerator;
 }
Beispiel #30
0
        private static void TaCodeTest()
        {
            var taCode = new TACode();

            var ass1 = new Assign
            {
                Left = new IntConst(3),
                //Left = new IntConst(5),
                Operation = OpCode.Minus,
                Right     = new IntConst(5),
                Result    = new Var()
            };

            var ass2 = new Assign
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = new IntConst(2),
                Result    = new Var()
            };

            var ass3 = new Assign
            {
                Operation = OpCode.Minus,
                Right     = new IntConst(1),
                Result    = new Var()
            };

            var ifgt1 = new IfGoto
            {
                Condition   = new IntConst(1),
                TargetLabel = ass3.Label
            };

            ass3.IsLabeled = true; //На этот оперетор мы переходим по условию

            var ass4 = new Assign
            {
                Left      = ass3.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(1999),
                Result    = new Var()
            };

            var ifgt2 = new IfGoto
            {
                Condition   = new IntConst(2),
                TargetLabel = ass2.Label
            };

            ass2.IsLabeled = true; //На этот оперетор мы переходим по условию

            var ass5 = new Assign
            {
                Left      = new IntConst(7),
                Operation = OpCode.Mul,
                Right     = new IntConst(4),
                Result    = new Var()
            };

            var ass6 = new Assign
            {
                Left      = new IntConst(100),
                Operation = OpCode.Div,
                Right     = new IntConst(25),
                Result    = new Var()
            };

            taCode.AddNode(ass1);
            taCode.AddNode(ass2);
            taCode.AddNode(ass3);
            taCode.AddNode(ifgt1);
            taCode.AddNode(ass4);
            taCode.AddNode(ifgt2);
            taCode.AddNode(ass5);
            taCode.AddNode(ass6);

            var algOpt = new AlgebraicOptimization();

            algOpt.Optimize(taCode.CodeList.ToList(), out var applied);

            Console.WriteLine($"TA Code\n: {taCode}");

            var bBlocks = taCode.CreateBasicBlockList();

            foreach (var bbl in bBlocks)
            {
                Console.WriteLine($"Block[{bbl.BlockId}]:");
                var bblCodeStr = bbl.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine);
                Console.WriteLine($"{bblCodeStr}\n");
            }

            Console.WriteLine($"Algebraic Optimization was{(applied ? "" : "n't")} applied");

            Console.WriteLine("========================CFG test========================");
            var cfg = new ControlFlowGraph(taCode);

            foreach (var cfgn in cfg.CFGNodes)
            {
                Console.WriteLine($"Block[{cfgn.BlockId}]");
                var bblCodeStr = cfgn.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine);
                Console.WriteLine($"{bblCodeStr}\n");

                Console.WriteLine("Children:\n");
                foreach (var ch in cfgn.Children)
                {
                    Console.WriteLine($"Block[{ch.BlockId}]");
                    var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine);
                    Console.WriteLine($"{bblCodeCh}\n");
                }

                Console.WriteLine("Parents:\n");
                foreach (var ch in cfgn.Parents)
                {
                    Console.WriteLine($"Block[{ch.BlockId}]");
                    var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine);
                    Console.WriteLine($"{bblCodeCh}\n");
                }
                Console.WriteLine("-----------------------------------------");
            }
            //Copy Propagation Test
            var taCodeCopyProp = new TACode();
            var assgn1         = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new Var(),
                Result    = new Var()
            };
            var assgn2 = new Assign()
            {
                Left      = assgn1.Right,
                Operation = OpCode.Minus,
                Right     = assgn1.Result,
                Result    = new Var()
            };
            var assgn3 = new Assign()
            {
                Left      = assgn2.Result,
                Operation = OpCode.Plus,
                Right     = new IntConst(1),
                Result    = new Var()
            };
            var assgn4 = new Assign()
            {
                Left      = assgn3.Result,
                Operation = OpCode.Mul,
                Right     = assgn1.Result,
                Result    = new Var()
            };
            var assgn5 = new Assign()
            {
                Left      = new IntConst(30),
                Operation = OpCode.Minus,
                Right     = new IntConst(20),
                Result    = assgn1.Result
            };
            var assgn6 = new Assign()
            {
                Left      = assgn2.Result,
                Operation = OpCode.Plus,
                Right     = assgn5.Result,
                Result    = new Var()
            };

            taCodeCopyProp.AddNode(assgn1);
            taCodeCopyProp.AddNode(assgn2);
            taCodeCopyProp.AddNode(assgn3);
            taCodeCopyProp.AddNode(assgn4);
            taCodeCopyProp.AddNode(assgn5);
            taCodeCopyProp.AddNode(assgn6);

            /*
             * a = b
             * c = b - a     -----> c = b - b
             * d = c + 1
             * e = d * a     -----> e = d * b
             * a = 30 - 20
             * k = c + a     -----> k = c + a
             */

            Console.WriteLine($"Testing Copy Propagation Optimisation.\n Three Adress Code:\n {taCodeCopyProp}");
            var optCopyProp = new CopyPropagation();

            optCopyProp.Optimize(taCodeCopyProp.CodeList.ToList(), out var applCopProp);
            Console.WriteLine($"Optimisation Copy Propagation was{(applCopProp ? "" : "n't")} applied");
            Console.WriteLine($"Three Adress Code Code\n: {taCodeCopyProp}");
            Console.WriteLine("-----------------------------------------");

            //Constant Folding Test
            var taCodeConstantFolding = new TACode();
            var assign1 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new Var(),
                Result    = new Var()
            };
            var assign2 = new Assign()
            {
                Left      = new IntConst(20),
                Operation = OpCode.Mul,
                Right     = new IntConst(3),
                Result    = new Var()
            };
            var assign3 = new Assign()
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = new IntConst(1),
                Result    = new Var()
            };
            var assign4 = new Assign()
            {
                Left      = new IntConst(100),
                Operation = OpCode.Div,
                Right     = new IntConst(50),
                Result    = new Var()
            };
            var assign5 = new Assign()
            {
                Left      = new IntConst(30),
                Operation = OpCode.Minus,
                Right     = new IntConst(20),
                Result    = assign1.Result
            };
            var assign6 = new Assign()
            {
                Left      = assign2.Result,
                Operation = OpCode.Plus,
                Right     = assign5.Result,
                Result    = new Var()
            };

            taCodeConstantFolding.AddNode(assign1);
            taCodeConstantFolding.AddNode(assign2);
            taCodeConstantFolding.AddNode(assign3);
            taCodeConstantFolding.AddNode(assign4);
            taCodeConstantFolding.AddNode(assign5);
            taCodeConstantFolding.AddNode(assign6);

            /*
             * a = b
             * c = 20 * 3    -----> c = 60
             * d = 10 + 1    -----> d = 11
             * e = 100 / 50  -----> e = 2
             * a = 30 - 20   -----> a = 10
             * k = c + a
             */

            Console.WriteLine($"Testing Constant Folding Optimisation.\n Three Adress Code:\n {taCodeConstantFolding}");
            var optConstFold = new ConstantFolding();

            optConstFold.Optimize(taCodeConstantFolding.CodeList.ToList(), out var applConstFold);
            Console.WriteLine($"Optimisation Constant Folding was{(applConstFold ? "" : "n't")} applied");
            Console.WriteLine($"Three Adress Code Code\n: {taCodeConstantFolding}");
            Console.WriteLine("-----------------------------------------");

            //All Optimizations Together Test
            var taCodeAllOptimizations = new TACode();
            var a1 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new Var(),
                Result    = new Var()
            };
            var a2 = new Assign()
            {
                Left      = a1.Right,
                Operation = OpCode.Minus,
                Right     = a1.Result,
                Result    = new Var()
            };
            var a3 = new Assign()
            {
                Left      = null,
                Operation = OpCode.Copy,
                Right     = new IntConst(20),
                Result    = new Var()
            };
            var a4 = new Assign()
            {
                Left      = new IntConst(20),
                Operation = OpCode.Mul,
                Right     = new IntConst(3),
                Result    = new Var()
            };
            var a5 = new Assign()
            {
                Left      = new IntConst(10),
                Operation = OpCode.Plus,
                Right     = a3.Result,
                Result    = new Var()
            };

            taCodeAllOptimizations.AddNode(a1);
            taCodeAllOptimizations.AddNode(a2);
            taCodeAllOptimizations.AddNode(a3);
            taCodeAllOptimizations.AddNode(a4);
            taCodeAllOptimizations.AddNode(a5);

            /*
             * a = b
             * c = b - a   -----> c = 0
             * n = 20
             * c = 20 * 3  -----> c = 60
             * d = 10 + n  -----> d = 30
             */

            Console.WriteLine($"Testing All Optimizations Together.\n Three Adress Code:\n {taCodeAllOptimizations}");
            var allOptimizations = new AllOptimizations();

            allOptimizations.ApplyAllOptimizations(taCodeAllOptimizations);
            Console.WriteLine($"Three Adress Code Code\n: {taCodeAllOptimizations}");
            Console.WriteLine("-----------------------------------------");
        }