public void Path() { // Artificially construct a path of four nodes in sequential order. var graph = TestGraphs.CreatePath(); var n1 = graph.GetNodeByOffset(0); var n2 = graph.GetNodeByOffset(1); var n3 = graph.GetNodeByOffset(2); var n4 = graph.GetNodeByOffset(3); var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph); Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode); Assert.True(dominatorTree.Dominates(n1, n1)); Assert.True(dominatorTree.Dominates(n1, n2)); Assert.True(dominatorTree.Dominates(n1, n3)); Assert.True(dominatorTree.Dominates(n1, n4)); Assert.False(dominatorTree.Dominates(n2, n1)); Assert.True(dominatorTree.Dominates(n2, n2)); Assert.True(dominatorTree.Dominates(n2, n3)); Assert.True(dominatorTree.Dominates(n2, n4)); Assert.False(dominatorTree.Dominates(n3, n1)); Assert.False(dominatorTree.Dominates(n3, n2)); Assert.True(dominatorTree.Dominates(n3, n3)); Assert.True(dominatorTree.Dominates(n3, n4)); Assert.False(dominatorTree.Dominates(n4, n1)); Assert.False(dominatorTree.Dominates(n4, n2)); Assert.False(dominatorTree.Dominates(n4, n3)); Assert.True(dominatorTree.Dominates(n4, n4)); }
/// <summary> /// Analyzes <paramref name="interval"/> and makes a loop from it, if possible. /// </summary> /// <param name="interval">The interval to be analyzed.</param> /// <returns>Returns true if a loop was made.</returns> private bool TryMakeLoop(IntervalConstruct interval, DominatorTree dominatorTree) { DFSTree dfsTree = DFSTBuilder.BuildTree(interval); if (dfsTree.BackEdges.Count == 0) { /// No back edges in the interval, so no loop can be made. return(false); } HashSet <ILogicalConstruct> loopBody; HashSet <ILogicalConstruct> possibleLatchingNodes = BuildLoop(dfsTree, out loopBody); ConditionLogicalConstruct loopCondition; LoopType typeOfLoop = DetermineLoopType(loopBody, possibleLatchingNodes, interval, dominatorTree, out loopCondition); if (loopBody.Count > 0) { LoopLogicalConstruct loop = new LoopLogicalConstruct(interval.Entry as ILogicalConstruct, loopBody, typeOfLoop, loopCondition, typeSystem); CleanUpEdges(loop); /// Covers the case in IrregularbackedgeExitLoop UpdateDominatorTree(dominatorTree, loop); return(true); } else { /// Empty loops should not be created. Instead, backedges that form such loops will be marked as goto. foreach (DFSTEdge backedge in dfsTree.BackEdges) { MarkAsGotoEdge(backedge.Start.Construct as ILogicalConstruct, backedge.End.Construct as ILogicalConstruct); } } return(false); }
public void Loop() { var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance); var nodes = new ControlFlowNode <int> [4]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = new ControlFlowNode <int>(i, i); cfg.Nodes.Add(nodes[i]); } nodes[0].ConnectWith(nodes[2]); nodes[1].ConnectWith(nodes[2]); nodes[2].ConnectWith(nodes[1], ControlFlowEdgeType.Conditional); nodes[2].ConnectWith(nodes[3]); cfg.Entrypoint = nodes[0]; var tree = DominatorTree.FromGraph(cfg); Assert.Equal(new HashSet <INode> { nodes[2] }, tree.GetDominanceFrontier(nodes[1])); Assert.Equal(new HashSet <INode> { nodes[2] }, tree.GetDominanceFrontier(nodes[2])); }
/* * Translate into SSA form */ private static void ConvertIntoSSAForm(IRGraph graph) { DominatorTree dominatorTree = new DominatorTree(graph); InsertPhiFunctions(graph, dominatorTree); RenameVariables(graph, dominatorTree); }
public void Loop() { // Artificially construct a looping construct. var graph = TestGraphs.CreateLoop(); var n1 = graph.GetNodeByOffset(0); var n2 = graph.GetNodeByOffset(1); var n3 = graph.GetNodeByOffset(2); var n4 = graph.GetNodeByOffset(4); var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph); Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode); Assert.True(dominatorTree.Dominates(n1, n1)); Assert.True(dominatorTree.Dominates(n1, n2)); Assert.True(dominatorTree.Dominates(n1, n3)); Assert.True(dominatorTree.Dominates(n1, n4)); Assert.False(dominatorTree.Dominates(n2, n1)); Assert.True(dominatorTree.Dominates(n2, n2)); Assert.False(dominatorTree.Dominates(n2, n3)); Assert.False(dominatorTree.Dominates(n2, n4)); Assert.False(dominatorTree.Dominates(n3, n1)); Assert.True(dominatorTree.Dominates(n3, n2)); Assert.True(dominatorTree.Dominates(n3, n3)); Assert.True(dominatorTree.Dominates(n3, n4)); Assert.False(dominatorTree.Dominates(n4, n1)); Assert.False(dominatorTree.Dominates(n4, n2)); Assert.False(dominatorTree.Dominates(n4, n3)); Assert.True(dominatorTree.Dominates(n4, n4)); }
private bool TryMakeLoop(IntervalConstruct interval, DominatorTree dominatorTree) { V_0 = DFSTBuilder.BuildTree(interval); if (V_0.get_BackEdges().get_Count() == 0) { return(false); } V_2 = this.BuildLoop(V_0, out V_1); V_4 = this.DetermineLoopType(V_1, V_2, interval, dominatorTree, out V_3); if (V_1.get_Count() > 0) { V_5 = new LoopLogicalConstruct(interval.get_Entry() as ILogicalConstruct, V_1, V_4, V_3, this.typeSystem); this.CleanUpEdges(V_5); this.UpdateDominatorTree(dominatorTree, V_5); return(true); } V_6 = V_0.get_BackEdges().GetEnumerator(); try { while (V_6.MoveNext()) { V_7 = V_6.get_Current(); this.MarkAsGotoEdge(V_7.get_Start().get_Construct() as ILogicalConstruct, V_7.get_End().get_Construct() as ILogicalConstruct); } } finally { ((IDisposable)V_6).Dispose(); } return(false); }
public void SingleNode() { var graph = TestGraphs.CreateSingularGraph(); var dominatorTree = DominatorTree <DummyInstruction> .FromGraph(graph); Assert.Equal(graph.Entrypoint, dominatorTree.Root.OriginalNode); Assert.True(dominatorTree.Dominates(graph.Entrypoint, graph.Entrypoint)); }
/// <summary> /// Builds if constructs in the specified construct. /// </summary> /// <param name="construct"></param> private void BuildIfConstructs(ILogicalConstruct construct) { DominatorTree dominatorTree = GetDominatorTreeFromContext(construct); DFSTree dfsTree = DFSTBuilder.BuildTree(construct); foreach (ConditionLogicalConstruct condition in GetPostOrderedIfConditionCandidates(dfsTree)) { TryBuildIfConstruct(condition, dominatorTree, dfsTree); } }
/* * Test find reachable blocks methods */ private static void TestFindReachableBlocks(int index, SortedSet <int> expected) { IRGraph cfg = BuildSampleCFG(); SortedSet <IRBlock> result = DominatorTree.FindReachableBlocks(cfg, index); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Reachable blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
private void ProcessSwitchConstructs(ILogicalConstruct parent, List <CFGBlockLogicalConstruct> switchBlocks) { DominatorTree dominatorTree = GetDominatorTreeFromContext(parent); DFSTree dfsTree = DFSTBuilder.BuildTree(parent); switchBlocks.Sort((x, y) => dfsTree.ConstructToNodeMap[y].ReversePostOrderIndex.CompareTo(dfsTree.ConstructToNodeMap[x].ReversePostOrderIndex)); foreach (CFGBlockLogicalConstruct switchBlock in switchBlocks) { CreateSwitchConstruct(switchBlock, parent, this.logicalContext.CFG.SwitchBlocksInformation[switchBlock.TheBlock], dominatorTree); } }
private void UpdateDominatorTree(DominatorTree dominatorTree, IfLogicalConstruct theIfConstruct) { V_0 = new HashSet <ISingleEntrySubGraph>(); dummyVar0 = V_0.Add(theIfConstruct.get_Condition()); V_0.UnionWith(theIfConstruct.get_Then().get_Children()); if (theIfConstruct.get_Else() != null) { V_0.UnionWith(theIfConstruct.get_Else().get_Children()); } dominatorTree.MergeNodes(V_0, theIfConstruct.get_Condition(), theIfConstruct); return; }
public void Simple() { var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance); var n = new ControlFlowNode <int>(0, 0); cfg.Nodes.Add(n); cfg.Entrypoint = n; var tree = DominatorTree.FromGraph(cfg); Assert.Empty(tree.GetDominanceFrontier(n)); }
private void UpdateDominatorTree(DominatorTree dominatorTree, IfLogicalConstruct theIfConstruct) { HashSet <ISingleEntrySubGraph> ifNodes = new HashSet <ISingleEntrySubGraph>(); ifNodes.Add(theIfConstruct.Condition); ifNodes.UnionWith(theIfConstruct.Then.Children); if (theIfConstruct.Else != null) { ifNodes.UnionWith(theIfConstruct.Else.Children); } dominatorTree.MergeNodes(ifNodes, theIfConstruct.Condition, theIfConstruct); }
/* * Test Building Full Dominator Tree */ private static void TestCalculatingDominanceFrontier(int index, SortedSet <int> expected) { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); SortedSet <IRBlock> result = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index)); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
private static void CFGReducibility_DominatorTree_PrettyPrinter_Demonstration() { string fpath = @"..\..\..\CodeSamples\reducibilityBadSample.txt"; astRoot = AST(fpath); if (astRoot == null) { return; } var tacodeVisitor = new TACodeVisitor(); astRoot.Visit(tacodeVisitor); var prettyPrinter = new PrettyPrintVisitor(); astRoot.Visit(prettyPrinter); var cfg = new ControlFlowGraph(tacodeVisitor.Code); var domTree = new DominatorTree(cfg); Console.WriteLine("###### CFG Reducibility(#59 by APC TEAM) based on DominatorTree(#56 by ДВП)"); Console.WriteLine("###### and PrettyPrinter(#5 by APC TEAM) DEMONSTARTION:"); Console.WriteLine("###### Sample 1:"); Console.WriteLine(prettyPrinter.Text); Console.WriteLine("###### Dominator Tree Matrix:"); Console.WriteLine(domTree.ToString()); Console.WriteLine($"###### CFG is reducible: {cfg.IsReducible}"); Console.WriteLine($"###### CFG depth is: {cfg.Depth}"); fpath = @"..\..\..\CodeSamples\reducibilityGoodSample.txt"; astRoot = null; astRoot = AST(fpath); if (astRoot == null) { return; } tacodeVisitor = new TACodeVisitor(); astRoot.Visit(tacodeVisitor); prettyPrinter = new PrettyPrintVisitor(); astRoot.Visit(prettyPrinter); cfg = new ControlFlowGraph(tacodeVisitor.Code); domTree = new DominatorTree(cfg); Console.WriteLine("###########################################"); Console.WriteLine("###### Sample 2:"); Console.WriteLine("###### Program text from PrettyPrinter:\n"); Console.WriteLine(prettyPrinter.Text); Console.WriteLine("###### Dominator Tree Matrix:"); Console.WriteLine(domTree.ToString()); Console.WriteLine($"###### CFG is reducible: {cfg.IsReducible}"); }
/// <summary> /// Generates the loops in the graph with entry point <paramref name="construct"/>. /// </summary> /// <param name="construct">The entry point of the graph.</param> private void ProcessLogicalConstruct(ILogicalConstruct construct) { DominatorTree dominatorTree = GetDominatorTreeFromContext(construct); int lastIterationIntervalsCount = int.MaxValue; RemoveBackEdgesFromSwitchConstructs(construct); while (lastIterationIntervalsCount > 1) { IntervalAnalyzer ia = new IntervalAnalyzer(construct, removedEdges); List <IntervalConstruct> intervals = ia.ReduceCfg(); List <IntervalConstruct> reverseIntervals = new List <IntervalConstruct>(intervals); reverseIntervals.Reverse(); /// Make only one loop at a time, since the newly made loop can be the header node of a bigger loop (if they are nested so). bool madeLoop = false; foreach (IntervalConstruct interval in reverseIntervals) { if (TryMakeLoop(interval, dominatorTree)) { madeLoop = true; break; } } if (madeLoop) { lastIterationIntervalsCount = intervals.Count; continue; } /// No loop was made in the last iteration and the interval count wasn't reduced. Then, an edge must be deleted from the graph, /// to ensure the reducibility. if (intervals.Count == lastIterationIntervalsCount) { RemoveBlockingEdges(intervals); } /// This is sanity check. Intervals are supposed to decrease in count, or stay the same with each iteration if (intervals.Count > lastIterationIntervalsCount) { throw new Exception("Intervails are more than in the last iteration."); } lastIterationIntervalsCount = intervals.Count; } }
private void CreateSwitchConstruct(CFGBlockLogicalConstruct switchBlock, ILogicalConstruct parentConstruct, SwitchData switchData, DominatorTree dominatorTree) { List <KeyValuePair <CFGBlockLogicalConstruct, List <int> > > cfgSuccessorToLabelsMap = GetOrderedCFGSuccessorToLabelsMap(switchData); Dictionary <ILogicalConstruct, HashSet <ISingleEntrySubGraph> > validCaseEntryToDominatedNodesMap = GetValidCases(dominatorTree, switchBlock); List <CaseLogicalConstruct> orderedCaseConstructs = new List <CaseLogicalConstruct>(); PairList <List <int>, CFGBlockLogicalConstruct> labelsToCFGSuccessorsList = new PairList <List <int>, CFGBlockLogicalConstruct>(); foreach (KeyValuePair <CFGBlockLogicalConstruct, List <int> > cfgSuccessorToLabelsPair in cfgSuccessorToLabelsMap) { ILogicalConstruct successor; HashSet <ISingleEntrySubGraph> dominatedNodes; if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(cfgSuccessorToLabelsPair.Key, parentConstruct, out successor) && validCaseEntryToDominatedNodesMap.TryGetValue(successor, out dominatedNodes)) { CaseLogicalConstruct newCaseConstruct = new CaseLogicalConstruct(successor); newCaseConstruct.CaseNumbers.AddRange(cfgSuccessorToLabelsPair.Value); newCaseConstruct.Body.UnionWith(dominatedNodes.Cast <ILogicalConstruct>()); newCaseConstruct.AttachCaseConstructToGraph(); orderedCaseConstructs.Add(newCaseConstruct); } else { labelsToCFGSuccessorsList.Add(cfgSuccessorToLabelsPair.Value, cfgSuccessorToLabelsPair.Key); } } CaseLogicalConstruct defaultCase = null; CFGBlockLogicalConstruct defaultCFGSuccessor = GetCFGLogicalConstructFromBlock(switchData.DefaultCase); ILogicalConstruct defaultSuccessor; HashSet <ISingleEntrySubGraph> defaultCaseNodes; if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(defaultCFGSuccessor, parentConstruct, out defaultSuccessor) && validCaseEntryToDominatedNodesMap.TryGetValue(defaultSuccessor, out defaultCaseNodes)) { defaultCase = new CaseLogicalConstruct(defaultSuccessor); if (HasSuccessors(defaultCaseNodes)) { defaultCase.Body.UnionWith(defaultCaseNodes.Cast <ILogicalConstruct>()); } defaultCase.AttachCaseConstructToGraph(); } SwitchLogicalConstruct theSwitch = SwitchLogicalConstruct.GroupInSwitchConstruct(switchBlock, orderedCaseConstructs, labelsToCFGSuccessorsList, defaultCase, defaultCFGSuccessor); UpdateDominatorTree(dominatorTree, theSwitch); }
private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree) { // setup data structures Dictionary <Ident, int> count = new Dictionary <Ident, int>(); Dictionary <Ident, Stack <int> > stack = new Dictionary <Ident, Stack <int> >(); foreach (Ident ident in graph.GetDefinedVars()) { count[ident] = 0; stack[ident] = new Stack <int>(); stack[ident].Push(0); } // recursively walk the dominator tree in-order starting with the root node Search(graph.GetGraphHead(), dominatorTree, count, stack); }
private void UpdateDominatorTree(DominatorTree dominatorTree, LoopLogicalConstruct theLoopConstruct) { HashSet <ISingleEntrySubGraph> loopNodes = new HashSet <ISingleEntrySubGraph>(); if (theLoopConstruct.LoopCondition != null) { loopNodes.Add(theLoopConstruct.LoopCondition); } if (theLoopConstruct.LoopBodyBlock != null) { loopNodes.UnionWith(theLoopConstruct.LoopBodyBlock.Children); } ISingleEntrySubGraph loopEntry = (theLoopConstruct.LoopType == LoopType.PreTestedLoop) ? theLoopConstruct.LoopCondition : theLoopConstruct.LoopBodyBlock.Entry; dominatorTree.MergeNodes(loopNodes, loopEntry, theLoopConstruct); }
private void UpdateDominatorTree(DominatorTree dominatorTree, SwitchLogicalConstruct theSwitchConstruct) { HashSet <ISingleEntrySubGraph> switchNodes = new HashSet <ISingleEntrySubGraph>(); switchNodes.Add(theSwitchConstruct.Entry); foreach (CaseLogicalConstruct @case in theSwitchConstruct.ConditionCases) { switchNodes.UnionWith(@case.Children); } if (theSwitchConstruct.DefaultCase != null) { switchNodes.UnionWith(theSwitchConstruct.DefaultCase.Children); } dominatorTree.MergeNodes(switchNodes, theSwitchConstruct.Entry, theSwitchConstruct); }
/* * Test the dominance set */ private static void TestDomaintes(int index, SortedSet <int> expected) { IRGraph cfg = BuildSampleCFG(); SortedSet <IRBlock> V = cfg.GetSetOfAllBlocks(); SortedSet <IRBlock> VSansR = new SortedSet <IRBlock>(); VSansR.UnionWith(V); VSansR.Remove(cfg.GetGraphHead()); SortedSet <IRBlock> result = DominatorTree.CalculateDominatesSet(cfg, V, VSansR, cfg.GetBlock(index)); SortedSet <int> intResult = ConvertToIndexSet(result); if (!intResult.SetEquals(expected)) { throw new Exception("Dominates blocks for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
private void UpdateDominatorTree(DominatorTree dominatorTree, SwitchLogicalConstruct theSwitchConstruct) { V_0 = new HashSet <ISingleEntrySubGraph>(); dummyVar0 = V_0.Add(theSwitchConstruct.get_Entry()); V_1 = theSwitchConstruct.get_ConditionCases(); V_2 = 0; while (V_2 < (int)V_1.Length) { V_0.UnionWith(V_1[V_2].get_Children()); V_2 = V_2 + 1; } if (theSwitchConstruct.get_DefaultCase() != null) { V_0.UnionWith(theSwitchConstruct.get_DefaultCase().get_Children()); } dominatorTree.MergeNodes(V_0, theSwitchConstruct.get_Entry(), theSwitchConstruct); return; }
public void ExceptionHandler() { var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance); for (int i = 0; i < 7; i++) { cfg.Nodes.Add(new ControlFlowNode <int>(i)); } cfg.Entrypoint = cfg.Nodes[0]; cfg.Nodes[0].ConnectWith(cfg.Nodes[1]); cfg.Nodes[1].ConnectWith(cfg.Nodes[2], ControlFlowEdgeType.Conditional); cfg.Nodes[1].ConnectWith(cfg.Nodes[3], ControlFlowEdgeType.FallThrough); cfg.Nodes[2].ConnectWith(cfg.Nodes[4], ControlFlowEdgeType.Unconditional); cfg.Nodes[3].ConnectWith(cfg.Nodes[4], ControlFlowEdgeType.FallThrough); cfg.Nodes[4].ConnectWith(cfg.Nodes[6], ControlFlowEdgeType.Unconditional); cfg.Nodes[5].ConnectWith(cfg.Nodes[6], ControlFlowEdgeType.Unconditional); var ehRegion = new ExceptionHandlerRegion <int>(); cfg.Regions.Add(ehRegion); ehRegion.ProtectedRegion.Entrypoint = cfg.Nodes[1]; ehRegion.ProtectedRegion.Nodes.AddRange(new[] { cfg.Nodes[1], cfg.Nodes[2], cfg.Nodes[3], cfg.Nodes[4], }); var handler = new HandlerRegion <int>(); ehRegion.Handlers.Add(handler); handler.Contents.Nodes.Add(cfg.Nodes[5]); handler.Contents.Entrypoint = cfg.Nodes[5]; var tree = DominatorTree <int> .FromGraph(cfg); Assert.True(tree.Dominates(cfg.Nodes[1], cfg.Nodes[6])); Assert.False(tree.Dominates(cfg.Nodes[4], cfg.Nodes[6])); Assert.False(tree.Dominates(cfg.Nodes[5], cfg.Nodes[6])); }
/* * Test Building Full Dominator Tree */ public static void TestBuildFullTree() { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); // Expected DominatorTreeNode expected = BuildExpectedDominatorTree(); // Compare Result to Expected if(!dominatorTree.GetRoot().Equals(expected)) { Console.WriteLine("\n\n *** RESULT ***"); printTree(dominatorTree.GetRoot()); Console.WriteLine("\n\n *** EXPECTED ***"); printTree(expected); throw new Exception("Dominator Tree built doesn't match expected dominator tree"); } }
/* * Test Building Full Dominator Tree */ public static void TestBuildFullTree() { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); // Expected DominatorTreeNode expected = BuildExpectedDominatorTree(); // Compare Result to Expected if (!dominatorTree.GetRoot().Equals(expected)) { Console.WriteLine("\n\n *** RESULT ***"); printTree(dominatorTree.GetRoot()); Console.WriteLine("\n\n *** EXPECTED ***"); printTree(expected); throw new Exception("Dominator Tree built doesn't match expected dominator tree"); } }
public void Path() { var cfg = new ControlFlowGraph <int>(IntArchitecture.Instance); var nodes = new ControlFlowNode <int> [3]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = new ControlFlowNode <int>(i, i); cfg.Nodes.Add(nodes[i]); if (i > 0) { nodes[i - 1].ConnectWith(nodes[i]); } } cfg.Entrypoint = nodes[0]; var tree = DominatorTree.FromGraph(cfg); Assert.All(nodes, n => Assert.Empty(tree.GetDominanceFrontier(n))); }
private void UpdateDominatorTree(DominatorTree dominatorTree, LoopLogicalConstruct theLoopConstruct) { V_0 = new HashSet <ISingleEntrySubGraph>(); if (theLoopConstruct.get_LoopCondition() != null) { dummyVar0 = V_0.Add(theLoopConstruct.get_LoopCondition()); } if (theLoopConstruct.get_LoopBodyBlock() != null) { V_0.UnionWith(theLoopConstruct.get_LoopBodyBlock().get_Children()); } if (theLoopConstruct.get_LoopType() == 1) { stackVariable10 = theLoopConstruct.get_LoopCondition(); } else { stackVariable10 = theLoopConstruct.get_LoopBodyBlock().get_Entry(); } dominatorTree.MergeNodes(V_0, stackVariable10, theLoopConstruct); return; }
private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition) { if (conditionSuccessor == dominatorTree.get_RootConstruct()) { return(null); } V_0 = null; if (conditionSuccessor.get_AllPredecessors().get_Count() == 1) { V_0 = new HashSet <ILogicalConstruct>(); V_1 = dominatorTree.GetDominatedNodes(conditionSuccessor).GetEnumerator(); try { while (V_1.MoveNext()) { V_2 = (ILogicalConstruct)V_1.get_Current(); if (V_2 != theCondition) { dummyVar0 = V_0.Add(V_2); } else { V_3 = null; goto Label1; } } goto Label0; } finally { ((IDisposable)V_1).Dispose(); } Label1: return(V_3); } Label0: return(V_0); }
public void DominatorTree() { var program = @" var a; input(a); 1: if a == 0 goto 2; if a == 1 goto 2; a = 2; 2: a = 3; "; var graph = GenCFG(program); var algorithm = new DominatorTree(); _ = algorithm.Execute(graph); var iterationsFast = algorithm.Iterations; _ = algorithm.Execute(graph, false); var iterationsSlow = algorithm.Iterations; Assert.LessOrEqual(iterationsFast, iterationsSlow); }
private void TestInternal(ControlFlowGraph graph, DominatorDictionary expectedDoms, ParentsDictionary expectedParents, ChildrenDictionary expectedChildren) { var dt = new DominatorTree(); var dominators = dt.GetDominators(graph); var tree = dt.Execute(graph); var blocks = graph.GetCurrentBasicBlocks(); Assert.AreEqual(blocks.Count, dominators.Count(), "Dominators count and blocks count are different"); for (var i = 0; i < blocks.Count(); ++i) { CollectionAssert.AreEquivalent(expectedDoms[i], dominators[blocks[i]], $"Check dominators: error for block #{i}"); } for (var i = 0; i < blocks.Count(); ++i) { Assert.AreEqual(expectedParents[i], tree.Parent(blocks[i]), $"Check parents: error for block #{i}"); CollectionAssert.AreEquivalent(expectedChildren[i], tree.Children(blocks[i]), $"Check children: error for block #{i}"); } }
/// <summary> /// Gets the dominated nodes of the condition successor, only if they can form a legal block for the if construct. /// </summary> /// <param name="dominatorTree"></param> /// <param name="conditionSuccessor"></param> /// <returns>On success - a set of the nodes fo the block. Otherwise it returns null.</returns> private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition) { if (conditionSuccessor == dominatorTree.RootConstruct) //Corner case - the successor cannot be the entry of the construct. { return(null); } HashSet <ILogicalConstruct> body = null; if (conditionSuccessor.AllPredecessors.Count == 1) //The condition successor must have only one predecessor - the condition. { body = new HashSet <ILogicalConstruct>(); foreach (ILogicalConstruct node in dominatorTree.GetDominatedNodes(conditionSuccessor)) { if (node == theCondition) { return(null); } body.Add(node); } } return(body); }
/* * Test Building Full Dominator Tree */ private static void TestCalculatingDominanceFrontier(int index, SortedSet<int> expected) { // Build Dominator Tree IRGraph cfg = BuildSampleCFG(); DominatorTree dominatorTree = new DominatorTree(cfg); SortedSet<IRBlock> result = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index)); SortedSet<int> intResult = ConvertToIndexSet(result); if(!intResult.SetEquals(expected)) { throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected)); } }
private static void RenameVariables(IRGraph graph, DominatorTree dominatorTree) { // setup data structures Dictionary<Ident, int> count = new Dictionary<Ident, int>(); Dictionary<Ident, Stack<int>> stack = new Dictionary<Ident, Stack<int>>(); foreach (Ident ident in graph.GetDefinedVars()) { count[ident] = 0; stack[ident] = new Stack<int>(); stack[ident].Push(0); } // recursively walk the dominator tree in-order starting with the root node Search(graph.GetGraphHead(), dominatorTree, count, stack); }
private static void Search(IRBlock block, DominatorTree dominatorTree, Dictionary<Ident, int> count, Dictionary<Ident, Stack<int>> stack) { // Algorithm from Ron Cytron et al to rename variables into SSA form foreach (IRTuple irt in block.GetStatements()) { Console.Write("Type: " + irt.GetType() + " "); irt.Print(); Console.WriteLine(); if (irt.getOp() != IrOp.PHI) { foreach (Ident v in irt.GetUsedVars()) { Console.WriteLine("Renaming variable: " + v); int i = stack[v].Peek(); RenameTupleSourcesHelper(irt, v, i); // replace uses of v with vi in statement } } foreach (Ident a in irt.GetDefinedVars()) { count[a] = count[a] + 1; int i = count[a]; stack[a].Push(i); irt.setDest(RenameVar(a, i)); // replace definitions of a with ai in statement } } // rename Phi function arguments in the successors List<IRBlock> successors = block.GetSuccessors(); for (int i = 0; i < successors.Count; i++) { foreach (IRTuple stmt in block.GetStatements()) { if (stmt.getOp() == IrOp.PHI) { IRTupleManyOp phi = (IRTupleManyOp)stmt; Ident v = phi.GetSources()[i]; int numbering = stack[v].Peek(); phi.SetSource(i, RenameVar(v, numbering)); } } } // for each descendant do the Search(X) renaming process DominatorTreeNode node = dominatorTree.GetNode(block); foreach (DominatorTreeNode descendant in node.GetDescendants()) { Search(descendant.GetBlock(), dominatorTree, count, stack); } // pop stack phase foreach (IRTuple irt in block.GetStatements()) { foreach (Ident v in irt.GetDefinedVars()) stack[v].Pop(); } }
/* * Translate into SSA form */ private static void ConvertIntoSSAForm(IRGraph graph) { DominatorTree dominatorTree = new DominatorTree(graph); InsertPhiFunctions(graph, dominatorTree); RenameVariables(graph, dominatorTree); }
private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree) { foreach (IRBlock block in graph.GetSetOfAllBlocks()) { Console.WriteLine(); Console.WriteLine("***"); Console.WriteLine("Block: " + block.GetIndex()); block.PrintStatements(); Console.Write("Predecessors: "); foreach (IRBlock pred in graph.GetPredecessors(block)) Console.Write(pred.GetIndex() + ", "); Console.WriteLine(); Console.Write("Live in : "); foreach (Ident ident in block.GetLiveIn()) Console.Write(ident + ", "); Console.WriteLine(); Console.Write("Defined vars: "); foreach (Ident ident in block.GetDefinedVars()) Console.Write(ident + ", "); Console.WriteLine(); } foreach (Ident v in graph.GetDefinedVars()) { // A(v) = blocks containing an assignment to v HashSet<IRBlock> Av = new HashSet<IRBlock>(); foreach (IRBlock block in graph.GetSetOfAllBlocks()) { if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v)) Av.Add(block); } // place Phi tuple for each v in the iterated dominance frontier of A(v) HashSet<IRBlock> needsPhiFunction = new HashSet<IRBlock>(); foreach (IRBlock Avblock in Av) { // create set of blocks that need phi functions foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock)) { needsPhiFunction.Add(block); } } // only want one phi function per block for each variable where appropiate foreach (IRBlock block in needsPhiFunction) { // Phi function should have as many arguments as it does predecessors List<Ident> sources = new List<Ident>(); foreach (IRBlock b in graph.GetPredecessors(block)) sources.Add(v); IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources); block.InsertStatement(phi, 0); Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex()); } } }