コード例 #1
0
        public void FindReverseEdges3()
        {
            string programText = @"
            for i = 1..10
              if i < 5
                println(i);
              else
                println(i-5);
            ";

            SyntaxNode      root             = ParserWrap.Parse(programText);
            var             threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program;
            BasicBlocksList basicBlocks      = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode);
            Graph           g            = new Graph(basicBlocks);
            var             reverseEdges = FindReverseEdge.FindReverseEdges(g);

            List <Tuple <int, int> > tuples = new List <Tuple <int, int> >();

            foreach (var v in reverseEdges)
            {
                Trace.WriteLine(v.Source.BlockId + " -> " + v.Target.BlockId);
                tuples.Add(new Tuple <int, int>(v.Source.BlockId, v.Target.BlockId));
            }

            int start = g.GetMinBlockId();

            Assert.IsTrue(tuples.SequenceEqual(new List <Tuple <int, int> >()
            {
                new Tuple <int, int>(start + 5, start + 1)
            }
                                               ));
        }
コード例 #2
0
        /// Generates example graph:
        ///    B0
        ///   /  \
        ///  B1  B2
        ///   \  /
        ///    B3
        ///   /  \
        ///  B4  B5
        ///   \  /
        ///    B6
        public BasicBlocksList CreateTestGraph1Blocks()
        {
            var blocks = new BasicBlocksList();

            for (int i = 0; i < 7; i++)
            {
                blocks.Add(new BasicBlock(new List <ThreeAddressCommand>(), new List <int>(), null));
            }
            blocks.Blocks[0].InputBlocks = new List <int>();
            blocks.Blocks[1].InputBlocks = new List <int> {
                blocks.Blocks[0].BlockId
            };
            blocks.Blocks[2].InputBlocks = new List <int> {
                blocks.Blocks[0].BlockId
            };
            blocks.Blocks[3].InputBlocks = new List <int> {
                blocks.Blocks[1].BlockId, blocks.Blocks[2].BlockId
            };
            blocks.Blocks[4].InputBlocks = new List <int> {
                blocks.Blocks[3].BlockId
            };
            blocks.Blocks[5].InputBlocks = new List <int> {
                blocks.Blocks[3].BlockId
            };
            blocks.Blocks[6].InputBlocks = new List <int> {
                blocks.Blocks[4].BlockId, blocks.Blocks[5].BlockId
            };

            return(blocks);
        }
コード例 #3
0
        // constructor from recently prepared BasicBlocksList
        public Graph(BasicBlocksList listBlocks)
        {
            CFG.AddVertexRange(listBlocks.Blocks);

            foreach (BasicBlock block in listBlocks.Blocks)
            {
                blockMap.Add(block.BlockId, block);
            }

            foreach (var block in listBlocks.Blocks)
            {
                foreach (var numIn in block.InputBlocks)
                {
                    CFG.AddEdge(new Edge <BasicBlock>(this.getBlockById(numIn), block));
                }
            }

            spanTree.AddVertexRange(listBlocks.Blocks);
            var visited = new Dictionary <BasicBlock, bool>();

            foreach (var v in spanTree.Vertices)
            {
                visited[v] = false;
            }
            int c = spanTree.Vertices.Count();

            dfs(blockMap[blockMap.Keys.First()], visited, ref c);
        }
コード例 #4
0
        // get BasicBlocksList of all predecessors of the block
        public BasicBlocksList getParents(int id)
        {
            BasicBlocksList blockList = new BasicBlocksList();
            var             v         = getBlockById(id);

            foreach (var edge in CFG.InEdges(v))
            {
                blockList.Add(edge.Source);
            }

            return(blockList);
        }
コード例 #5
0
        // get BasicBlocksList of all ancestors of the block
        public BasicBlocksList getChildren(int id)
        {
            var result = new BasicBlocksList();
            var v      = getBlockById(id);

            foreach (var edge in CFG.OutEdges(v))
            {
                result.Add(edge.Target);
            }

            return(result);
        }
コード例 #6
0
        public void CFG2TACodeTransformationTest()
        {
            foreach (string sourseText in sources)
            {
                SyntaxTree.SyntaxNodes.SyntaxNode root            = ParserWrap.Parse(sourseText);
                var                        sourceThreeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program;
                BasicBlocksList            bbl = BasicBlocksGenerator.CreateBasicBlocks(sourceThreeAddressCode);
                Graph                      cfg = new Graph(bbl);
                List <ThreeAddressCommand> resultThreeAddressCode = cfg.transformToThreeAddressCode();

                CollectionAssert.AreEqual(sourceThreeAddressCode.Commands, resultThreeAddressCode);
            }
        }
コード例 #7
0
        public static IterativeAlgorithmOutput <V> Apply <V>(Graph graph, BasicIterativeAlgorithmParameters <V> param, Dictionary <int, int> order = null)
        {
            IterativeAlgorithmOutput <V> result = new IterativeAlgorithmOutput <V>();

            foreach (BasicBlock bb in graph)
            {
                result.Out[bb.BlockId] = param.StartingValue;
            }
            IEnumerable <BasicBlock> g = order == null ? graph : graph.OrderBy(x => order[x.BlockId]).Select(x => x);// order.Select(i => graph.getBlockById(i));
            bool changed = true;

            while (changed)
            {
                changed = false;
                foreach (BasicBlock bb in g)
                {
                    BasicBlocksList parents = param.ForwardDirection ? graph.getParents(bb.BlockId) : graph.getChildren(bb.BlockId);
                    if (parents.Blocks.Count > 0)
                    {
                        result.In[bb.BlockId] = param.GatherOperation(parents.Blocks.Select(b => result.Out[b.BlockId]));
                    }
                    else
                    {
                        result.In[bb.BlockId] = param.FirstValue;
                    }
                    V newOut = param.TransferFunction(result.In[bb.BlockId], bb);
                    changed = changed || !param.AreEqual(result.Out[bb.BlockId], newOut);
                    result.Out[bb.BlockId] = newOut;
                }
            }
            if (!param.ForwardDirection)
            {
                result = new IterativeAlgorithmOutput <V> {
                    In = result.Out, Out = result.In
                }
            }
            ;
            return(result);
        }
    }
コード例 #8
0
        public static BasicBlocksList CreateBasicBlocks(Program program)
        {
            BasicBlocksList            basicBlocks = new BasicBlocksList();
            List <ThreeAddressCommand> commands    = program.Commands;
            Dictionary <string, int>   labels      = new Dictionary <string, int>();
            List <int> firstCommandsOfBlocks       = new List <int>();
            List <int> lastCommandsOfBlocks        = new List <int>();

            firstCommandsOfBlocks.Add(0);
            for (int i = 0; i < commands.Count; ++i)
            {
                ThreeAddressCommand currentCommand = commands[i];
                if (currentCommand.Label != null)
                {
                    labels[currentCommand.Label] = i;
                    if (i > 0)
                    {
                        firstCommandsOfBlocks.Add(i);
                        lastCommandsOfBlocks.Add(i - 1);
                    }
                }
                if (currentCommand is Goto && i < commands.Count - 1)
                {
                    firstCommandsOfBlocks.Add(i + 1);
                    lastCommandsOfBlocks.Add(i);
                }
            }
            lastCommandsOfBlocks.Add(commands.Count - 1);
            firstCommandsOfBlocks = firstCommandsOfBlocks.Distinct().ToList();
            lastCommandsOfBlocks  = lastCommandsOfBlocks.Distinct().ToList();

            int[] BlockByFirstCommand = new int[commands.Count];
            int[] BlockByLastCommand  = new int[commands.Count];
            for (int i = 0; i < firstCommandsOfBlocks.Count; ++i)
            {
                BlockByFirstCommand[firstCommandsOfBlocks[i]] = i;
            }
            for (int i = 0; i < lastCommandsOfBlocks.Count; ++i)
            {
                BlockByLastCommand[lastCommandsOfBlocks[i]] = i;
            }

            List <int>[] PreviousBlocksByBlockID = new List <int> [commands.Count];
            List <int>[] NextBlocksByBlockID     = new List <int> [commands.Count];
            for (int i = 0; i < commands.Count; ++i)
            {
                PreviousBlocksByBlockID[i] = new List <int>();
                NextBlocksByBlockID[i]     = new List <int>();
            }

            foreach (var currentNumOfLastCommand in lastCommandsOfBlocks)
            {
                ThreeAddressCommand currentCommand = commands[currentNumOfLastCommand];
                int numOfCurrentBlock = BlockByLastCommand[currentNumOfLastCommand];
                if ((currentCommand.GetType() != typeof(Goto)) && (currentNumOfLastCommand < commands.Count - 1))
                {
                    int numOfNextBlock = numOfCurrentBlock + 1;
                    NextBlocksByBlockID[numOfCurrentBlock].Add(numOfNextBlock);
                    PreviousBlocksByBlockID[numOfNextBlock].Add(numOfCurrentBlock);
                }
                if (currentCommand is Goto)
                {
                    int numOfNextBlock = BlockByFirstCommand[labels[(currentCommand as Goto).GotoLabel]];
                    NextBlocksByBlockID[numOfCurrentBlock].Add(numOfNextBlock);
                    PreviousBlocksByBlockID[numOfNextBlock].Add(numOfCurrentBlock);
                }
            }

            for (int i = 0; i < firstCommandsOfBlocks.Count; ++i)
            {
                BasicBlock block = new BasicBlock();
                block.Commands = new List <ThreeAddressCommand>(commands.Take(lastCommandsOfBlocks[i] + 1).Skip(firstCommandsOfBlocks[i]).ToList());
                basicBlocks.Blocks.Add(block);
                basicBlocks.BlockByID[block.BlockId] = block;
            }

            for (int i = 0; i < basicBlocks.Count(); ++i)
            {
                for (int j = 0; j < PreviousBlocksByBlockID[i].Count; ++j)
                {
                    PreviousBlocksByBlockID[i][j] = basicBlocks.Blocks[PreviousBlocksByBlockID[i][j]].BlockId;
                }
                for (int j = 0; j < NextBlocksByBlockID[i].Count; ++j)
                {
                    NextBlocksByBlockID[i][j] = basicBlocks.Blocks[NextBlocksByBlockID[i][j]].BlockId;
                }
                basicBlocks.Blocks[i].InputBlocks.AddRange(PreviousBlocksByBlockID[i]);
                basicBlocks.Blocks[i].OutputBlocks.AddRange(NextBlocksByBlockID[i]);
            }

            return(basicBlocks);
        }
コード例 #9
0
        public void TestDefUse()
        {
            string programText = @"
                                a = 4;
                                b = 4;
                                c = a + b;
                                if 1 
                                    a = 3;
                                else
                                    b = 2;
                                print(c);
                                ";

            SyntaxNode      root             = ParserWrap.Parse(programText);
            var             threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program;
            BasicBlocksList basicBlocks      = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode);

            DefUseBlockCalculator defUse = new DefUseBlockCalculator();

            var defUseList = new List <KeyValuePair <int, Tuple <ISet <string>, ISet <string> > > >();

            foreach (var block in basicBlocks)
            {
                defUseList.Add(new KeyValuePair <int, Tuple <ISet <string>, ISet <string> > >(block.BlockId, defUse.GetDefUseSetsByBlock(block)));
            }

            Assert.IsTrue(defUseList[0].Value.Item1
                          .SetEquals(
                              new HashSet <string>(new string[]
            {
                "a",
                "t0",
                "b",
                "c"
            })));
            Assert.IsTrue(defUseList[0].Value.Item2.Count == 0);

            Assert.IsTrue(defUseList[1].Value.Item1
                          .SetEquals(
                              new HashSet <string>(new string[]
            {
                "a"
            })));
            Assert.IsTrue(defUseList[1].Value.Item2.Count == 0);

            Assert.IsTrue(defUseList[2].Value.Item1
                          .SetEquals(
                              new HashSet <string>(new string[]
            {
                "b"
            })));
            Assert.IsTrue(defUseList[2].Value.Item2.Count == 0);

            Assert.IsTrue(defUseList[3].Value.Item2
                          .SetEquals(
                              new HashSet <string>(new string[]
            {
                "c"
            })));
            Assert.IsTrue(defUseList[3].Value.Item1.Count == 0);
        }
コード例 #10
0
        public void BasicBlockList1()
        {
            string programText = @"
for i = 1 + 2 * 3 .. 10
  println(i);
";

            SyntaxNode root             = ParserWrap.Parse(programText);
            var        threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program;
            var        basicBlocks      = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode);

            BasicBlocksList            BBL      = new BasicBlocksList();
            List <ThreeAddressCommand> commands = new List <ThreeAddressCommand>();

            commands.Add(new Assignment("t0",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(2),
                                                            SyntaxTree.Operation.Multiply,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(3))));
            commands.Add(new Assignment("t1",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(1),
                                                            SyntaxTree.Operation.Add,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("t0"))));
            commands.Add(new Assignment("i",
                                        new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("t1")));
            BBL.Add(new BasicBlock(commands, new List <int>(), new List <int>()
            {
                1
            }));

            commands.Clear();
            commands.Add(new ConditionalGoto("$GL_2",
                                             new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("i"),
                                                                 SyntaxTree.Operation.Greater,
                                                                 new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(10))));
            commands[0].Label = "$GL_1";
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                0, 2
            }, new List <int>()
            {
                2, 3
            }));

            commands.Clear();
            commands.Add(new Print(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("i"), true));
            commands.Add(new Assignment("i",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("i"),
                                                            SyntaxTree.Operation.Add,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(1))));
            commands.Add(new Goto("$GL_1"));
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                1
            }, new List <int>()
            {
                1
            }));

            commands.Clear();
            commands.Add(new NoOperation("$GL_2"));
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                1
            }, new List <int>()));

            int start = basicBlocks.Blocks[0].BlockId;

            Assert.IsTrue(basicBlocks.Blocks[0].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[0].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[0].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[0].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[0].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[0].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[1].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[1].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[1].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[1].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[1].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[1].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[2].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[2].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[2].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[2].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[2].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[2].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[3].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[3].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[3].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[3].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[3].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[3].OutputBlocks));
        }
コード例 #11
0
        public void BasicBlockList2()
        {
            string programText = @"
x = 5;
if x < 5 
  x = x + 1;
else
  x = x - 1;
println(x);
";

            SyntaxNode root             = ParserWrap.Parse(programText);
            var        threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program;
            var        basicBlocks      = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode);

            BasicBlocksList            BBL      = new BasicBlocksList();
            List <ThreeAddressCommand> commands = new List <ThreeAddressCommand>();

            commands.Add(new Assignment("x",
                                        new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(5)));
            commands.Add(new Assignment("t0",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("x"),
                                                            SyntaxTree.Operation.Lesser,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(5))));
            commands.Add(new ConditionalGoto("$GL_2",
                                             new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("t0"),
                                                                 SyntaxTree.Operation.Equal,
                                                                 new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(0))));
            BBL.Add(new BasicBlock(commands, new List <int>(), new List <int>()
            {
                1, 2
            }));

            commands.Clear();
            commands.Add(new Assignment("t1",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("x"),
                                                            SyntaxTree.Operation.Add,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(1))));
            commands.Add(new Assignment("x",
                                        new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("t1")));
            commands.Add(new Goto("$GL_1"));
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                0
            }, new List <int>()
            {
                3
            }));

            commands.Clear();
            commands.Add(new NoOperation("$GL_2"));
            commands.Add(new Assignment("t2",
                                        new BinaryOperation(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("x"),
                                                            SyntaxTree.Operation.Subtract,
                                                            new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Int32Const(1))));
            commands.Add(new Assignment("x",
                                        new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("t2")));
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                0
            }, new List <int>()
            {
                3
            }));

            commands.Clear();
            commands.Add(new NoOperation("$GL_1"));
            commands.Add(new Print(new DataFlowAnalysis.IntermediateRepresentation.ThreeAddressCode.Model.Identifier("x"), true));
            BBL.Add(new BasicBlock(commands, new List <int>()
            {
                1, 2
            }, new List <int>()));

            int start = basicBlocks.Blocks[0].BlockId;

            Assert.IsTrue(basicBlocks.Blocks[0].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[0].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[0].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[0].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[0].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[0].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[1].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[1].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[1].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[1].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[1].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[1].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[2].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[2].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[2].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[2].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[2].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[2].OutputBlocks));

            Assert.IsTrue(basicBlocks.Blocks[3].Commands.Select(x => x.ToString()).SequenceEqual(BBL.Blocks[3].Commands.Select(x => x.ToString())));
            Assert.IsTrue(basicBlocks.Blocks[3].InputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[3].InputBlocks));
            Assert.IsTrue(basicBlocks.Blocks[3].OutputBlocks.Select(x => x - start).SequenceEqual(BBL.Blocks[3].OutputBlocks));
        }