Пример #1
0
        /// <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);
        }
Пример #2
0
        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();
        }
Пример #3
0
 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>();
 }
Пример #4
0
        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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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);
                }
            }
        }