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) } )); }
/// 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); }
// 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); }
// 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); }
// 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); }
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); } }
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); } }
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); }
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); }
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)); }
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)); }