/// <summary> /// Add a new statement with no conflicts. /// </summary> /// <param name="statement"></param> /// <returns></returns> public NodeIndex AddNode(IStatement statement) { NodeIndex node = graph.AddNode(); indexOf[statement] = node; return(node); }
public void IndexedGraphTest() { IndexedGraph g = new IndexedGraph(); int a = g.AddNode(); int b = g.AddNode(); int c = g.AddNode(); int ab = g.AddEdge(a, b); int bb = g.AddEdge(b, b); // self loop int bc = g.AddEdge(b, c); int bc2 = g.AddEdge(b, c); // double edge Assert.Equal(c, g.TargetOf(bc)); Assert.Equal(bb, g.GetEdge(b, b)); Assert.Equal(0, g.EdgeCount(a, c)); Assert.Equal(2, g.EdgeCount(b, c)); Assert.Equal(4, g.EdgeCount()); Assert.Equal(1, g.NeighborCount(a)); Assert.Equal(2, g.NeighborCount(c)); Assert.Equal(1, g.TargetCount(a)); Assert.Equal(0, g.SourceCount(a)); Console.Write("EdgesOf(b):"); foreach (int edge in g.EdgesOf(b)) { Console.Write(" {0}", edge); } Console.WriteLine(); Console.Write("EdgesInto(b):"); foreach (int edge in g.EdgesInto(b)) { Console.Write(" {0}", edge); } Console.WriteLine(); Console.Write("EdgesOutOf(b):"); foreach (int edge in g.EdgesOutOf(b)) { Console.Write(" {0}", edge); } Console.WriteLine(); Console.Write("EdgesLinking(b,c):"); foreach (int edge in g.EdgesLinking(b, c)) { Console.Write(" {0}", edge); } Console.WriteLine(); }
public LoopMergingInfo(IList <IStatement> stmts) { graph = new IndexedGraph(); foreach (var stmt in stmts) { indexOf[stmt] = graph.AddNode(); } prohibitedLoopVars = graph.CreateEdgeData <ICollection <IVariableDeclaration> >(); offsetInfos = graph.CreateEdgeData <IOffsetInfo>(); }
private int GetMethodIndex(IMethodReference imr) { int index; if (!IndexOfMethod.TryGetValue(imr, out index)) { index = IndexOfMethod.Count; IndexOfMethod.Add(imr, index); methods.Add(new MethodInfo(imr.Resolve())); MethodGraph.AddNode(); } return(index); }
/// <summary> /// Creates the node (if needed) and adds directed edges to the graph. /// </summary> /// <param name="expr"></param> /// <returns></returns> private int CreateNodeAndEdges(IExpression expr) { Containers scope = new Containers(context); int node; if (!nodeOf.TryGetExact(expr, scope, out node)) { node = graph.AddNode(); nodeOf.Add(expr, node, scope); } if (Recognizer.GetParameterDeclaration(expr) != null || expr is ILiteralExpression) { // expr is an observed value observedNodes.Add(new KeyValuePair <int, IExpression>(node, expr)); } foreach (var vis in nodeOf.GetAll(expr)) { // If scopes are equal (same node), do nothing if (vis.Value == node) { continue; } if (scope.Contains(vis.Scope)) { // This scope contains the other scope, therefore is more specific graph.AddEdge(vis.Value, node); } else if (vis.Scope.Contains(scope)) { // This scope is contained in the other scope, therefore is more general graph.AddEdge(node, vis.Value); } } return(node); }
public DependencyGraph2(BasicTransformContext context, IEnumerable <IStatement> inputs, BackEdgeHandling backEdgeHandling, Action <IWhileStatement> beginWhile, Action <IWhileStatement> endWhile, Action <IConditionStatement> beginFirstIterPost, Action <IConditionStatement> endFirstIterPost, Action <IStatement, NodeIndex> action) { Set <NodeIndex> nodesInCurrentWhile = new Set <EdgeIndex>(); int whileDepth = 0; // create a dependency graph where while loops are flattened (the while loops themselves are not nodes) // the graph will only contain read-after-write and write-after-alloc dependencies for now // add write-after-read dependencies isWriteAfterRead = dependencyGraph.CreateEdgeData(false); DeadCodeTransform.ForEachStatement(inputs, delegate(IWhileStatement iws) { beginWhile(iws); nodesInCurrentWhile.Clear(); whileDepth++; }, delegate(IWhileStatement iws) { // all duplicates in a while loop should share all targets foreach (KeyValuePair <IStatement, Set <NodeIndex> > entry in duplicates) { IStatement ist = entry.Key; Set <NodeIndex> set = entry.Value; Set <NodeIndex> targets = new Set <EdgeIndex>(); // collect all targets in the while loop foreach (NodeIndex node in set) { foreach (NodeIndex target in dependencyGraph.TargetsOf(node)) { if (nodesInCurrentWhile.Contains(target)) { targets.Add(target); } } } Set <NodeIndex> backEdgeTargets = null; if (!backEdges.TryGetValue(ist, out backEdgeTargets)) { backEdgeTargets = new Set <EdgeIndex>(); backEdges[ist] = backEdgeTargets; } // add all targets to all duplicates in the loop foreach (NodeIndex node in set) { if (!nodesInCurrentWhile.Contains(node)) { continue; } foreach (NodeIndex target in targets) { if (!dependencyGraph.ContainsEdge(node, target)) { if (backEdgeHandling == BackEdgeHandling.Include) { dependencyGraph.AddEdge(node, target); } else if (backEdgeHandling == BackEdgeHandling.Reverse) { if (!dependencyGraph.ContainsEdge(target, node)) { dependencyGraph.AddEdge(target, node); } } if (target < node) { if (backEdgeTargets == null && !backEdges.TryGetValue(ist, out backEdgeTargets)) { backEdgeTargets = new Set <EdgeIndex>(); backEdges[ist] = backEdgeTargets; } backEdgeTargets.Add(target); } } } } } endWhile(iws); whileDepth--; }, beginFirstIterPost, endFirstIterPost, delegate(IStatement ist) { DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist); if (di == null) { context.Error("Dependency information not found for statement: " + ist); di = new DependencyInformation(); } NodeIndex targetIndex = dependencyGraph.AddNode(); Set <NodeIndex> backEdgeTargets; Set <NodeIndex> sources = new Set <NodeIndex>(); // for fast checking of duplicate sources foreach (IStatement source in di.GetDependenciesOfType(DependencyType.Dependency | DependencyType.Declaration)) { int sourceIndex; // we assume that the statements are already ordered properly to respect dependencies. // if the source is not in indexOfNode, then it must be a cyclic dependency in this while loop. if (indexOfNode.TryGetValue(source, out sourceIndex)) { if (!sources.Contains(sourceIndex)) { sources.Add(sourceIndex); EdgeIndex edge = dependencyGraph.AddEdge(sourceIndex, targetIndex); } } else { sourceIndex = -1; } if (sourceIndex == -1) { // add a back edge if (!backEdges.TryGetValue(source, out backEdgeTargets)) { backEdgeTargets = new Set <EdgeIndex>(); backEdges[source] = backEdgeTargets; } backEdgeTargets.Add(targetIndex); // add a dependency on the initializers of source Stack <IStatement> todo = new Stack <IStatement>(); todo.Push(source); while (todo.Count > 0) { IStatement source2 = todo.Pop(); DependencyInformation di2 = context.InputAttributes.Get <DependencyInformation>(source2); if (di2 == null) { context.Error("Dependency information not found for statement: " + source2); continue; } foreach (IStatement init in di2.Overwrites) { int initIndex; if (indexOfNode.TryGetValue(init, out initIndex)) { if (!sources.Contains(initIndex)) { sources.Add(initIndex); EdgeIndex edge = dependencyGraph.AddEdge(initIndex, targetIndex); } } else { todo.Push(init); } } } } } if (indexOfNode.ContainsKey(ist)) { Set <int> set; if (!duplicates.TryGetValue(ist, out set)) { set = new Set <int>(); duplicates[ist] = set; set.Add(indexOfNode[ist]); } set.Add(targetIndex); } // the same statement may appear multiple times. when looking up indexOfNode, we want to use the last occurrence of the statement. indexOfNode[ist] = targetIndex; // must do this at the end, in case the stmt depends on a previous occurrence of itself nodesInCurrentWhile.Add(targetIndex); nodes.Add(ist); if (backEdgeHandling != BackEdgeHandling.Ignore && backEdges.TryGetValue(ist, out backEdgeTargets)) { // now that ist has an index, we can fill in the back edges foreach (NodeIndex node in backEdgeTargets) { if (backEdgeHandling == BackEdgeHandling.Include) { if (dependencyGraph.ContainsEdge(targetIndex, node)) { throw new Exception("Internal: back edge already present"); } dependencyGraph.AddEdge(targetIndex, node); } else { // make a new edge, even if one exists. EdgeIndex edge = dependencyGraph.AddEdge(node, targetIndex); isWriteAfterRead[edge] = true; } } } action(ist, targetIndex); }); if (string.Empty.Length > 0) { // loop statements in their original order foreach (NodeIndex target in dependencyGraph.Nodes) { IStatement ist = nodes[target]; if (ist is IWhileStatement) { continue; } foreach (NodeIndex source in GetPreviousReaders(context, dependencyGraph, target, nodes, indexOfNode).ToReadOnlyList()) { if (source > target) { throw new Exception("Internal: source statement follows target"); } // make a new edge, even if one exists. EdgeIndex edge = dependencyGraph.AddEdge(source, target); isWriteAfterRead[edge] = true; } } } isWriteAfterWrite = dependencyGraph.CreateEdgeData(false); // loop statements in their original order foreach (NodeIndex target in dependencyGraph.Nodes) { IStatement ist = nodes[target]; if (ist is IWhileStatement) { continue; } foreach (NodeIndex source in GetOverwrites(context, dependencyGraph, target, nodes, indexOfNode).ToReadOnlyList()) { if (source > target) { throw new Exception("Internal: source statement follows target"); } if (dependencyGraph.ContainsEdge(source, target)) { foreach (EdgeIndex edge in dependencyGraph.EdgesLinking(source, target)) { isWriteAfterWrite[edge] = true; } } else { EdgeIndex edge = dependencyGraph.AddEdge(source, target); isWriteAfterWrite[edge] = true; } } } dependencyGraph.NodeCountIsConstant = true; dependencyGraph.IsReadOnly = true; for (int targetIndex = 0; targetIndex < dependencyGraph.Nodes.Count; targetIndex++) { IStatement ist = nodes[targetIndex]; DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist); if (di == null) { continue; } if (di.IsOutput) { outputNodes.Add(targetIndex); } } }