/// <summary> /// Gets the nodes where the code graph is merging. /// </summary> /// <returns>The merge nodes.</returns> public Dictionary <ProgramNode, MergeNodeType> GetMergeNodes() { Dictionary <ProgramNode, MergeNodeType> list = new Dictionary <ProgramNode, MergeNodeType>(); // look for diamond structures and loops in the code // this is useful for fixing errors where the usage of the global variable is inside the if/else block // but the solution needs a barrier outside the block foreach (ProgramNode node in Graph.Nodes) { // identify merge points if (node.Predecessors.Count > 1) { List <BackEdge> backEdges = Graph.BackEdges; if (backEdges.Any(x => x.Destination == node)) { // loop structures BackEdge edge = backEdges.First(x => x.Destination == node); List <ProgramNode> loopNodes = Graph.GetLoopNodes(edge); if (loopNodes.Any(x => nodesContainingBarriers.Contains(x))) { list.Add(node, MergeNodeType.Loop); } } else { // if-else diamond structures // can be simplified by identifying the least common ancestor and inspecting if the intermediate nodes have barriers ProgramNode lca = GetLCA(node.Predecessors); if (lca != null) { List <ProgramNode> intermediateNodes = GetIntermediateNodes(lca, node); if (intermediateNodes.Any(x => nodesContainingBarriers.Contains(x))) { if (!list.ContainsKey(lca)) { list.Add(lca, MergeNodeType.IfElse); } } } } } } return(list); }
private void OnBackEdge([NotNull] TEdge edge) { Debug.Assert(edge != null); BackEdge?.Invoke(edge); }
protected void OnBackEdge(EdgeType edge) { BackEdge?.Invoke(edge); }
/// <inheritdoc/> public void OnBackEdge(TGraph g, TEdge e) => BackEdge?.Invoke(g, e);