コード例 #1
0
            private void LoopCheck()
            {
                var graph = new Graph <Absy>(new HashSet <Tuple <Absy, Absy> >(atomicityLabels.Keys));

                graph.AddSource(initialState);
                graph.ComputeLoops();

                var edgeToLoopHeader = new Dictionary <Tuple <Absy, Absy>, Block>();

                foreach (Block header in graph.SortHeadersByDominance())
                {
                    foreach (var source in graph.BackEdgeNodes(header))
                    {
                        edgeToLoopHeader[new Tuple <Absy, Absy>(source, header)] = header;
                        foreach (var node in graph.NaturalLoops(header, source))
                        {
                            if (node == header)
                            {
                                continue;
                            }
                            foreach (var pred in graph.Predecessors(node))
                            {
                                var edge = new Tuple <Absy, Absy>(pred, node);
                                if (edgeToLoopHeader.ContainsKey(edge))
                                {
                                    continue;
                                }
                                edgeToLoopHeader[edge] = header;
                            }
                        }
                    }
                }

                var parentLoopHeader = new Dictionary <Block, Block>();

                foreach (Block header in graph.Headers)
                {
                    foreach (var pred in graph.Predecessors(header).Except(graph.BackEdgeNodes(header)))
                    {
                        var edge = new Tuple <Absy, Absy>(pred, header);
                        if (edgeToLoopHeader.ContainsKey(edge))
                        {
                            parentLoopHeader[header] = edgeToLoopHeader[edge];
                            break;
                        }
                    }
                }

                var yieldingLoopHeaders = new HashSet <Block>(graph.Headers.OfType <Block>()
                                                              .Where(header => civlTypeChecker.IsYieldingLoopHeader(header, currLayerNum)));

                foreach (var header in parentLoopHeader.Keys)
                {
                    var parentHeader = parentLoopHeader[header];
                    if (yieldingLoopHeaders.Contains(header) && !yieldingLoopHeaders.Contains(parentHeader))
                    {
                        civlTypeChecker.Error(parentHeader,
                                              $"Loop header must be yielding at layer {currLayerNum}");
                    }
                }

                foreach (var edge in edgeToLoopHeader.Keys)
                {
                    var header = edgeToLoopHeader[edge];
                    if (yieldingLoopHeaders.Contains(header))
                    {
                        continue;
                    }
                    if (atomicityLabels[edge] == Y)
                    {
                        civlTypeChecker.Error(header,
                                              $"Loop header must be yielding at layer {currLayerNum}");
                    }
                }
            }