예제 #1
0
        //Алгоритм построения естественного цикла обратного ребра n → d.
        public CFGNaturalCycle(ControlFlowGraph cfg, Edge <ThreeAddressCode> loopEdge)
        {
            //loopSet ≔ {n, d}
            var visitedVertex = new HashSet <ThreeAddressCode>();

            // Пометим d как посещённый
            visitedVertex.Add(loopEdge.Target);
            EntryBlock = loopEdge.Target;
            Graph.AddVertex(EntryBlock);
            var targetVertex = new Queue <ThreeAddressCode>();

            targetVertex.Enqueue(loopEdge.Source);
            ExitBlocks.Add(loopEdge.Source);
            Graph.AddVertex(loopEdge.Source);
            Graph.AddEdge(new Edge <ThreeAddressCode>(loopEdge.Source, EntryBlock));
            //Выполним поиск в глубину на обратном графе потока, начиная с n. Внесём все
            //посещённые узлы в loopSet.
            while (targetVertex.Count() > 0)
            {
                var curVertex     = targetVertex.Dequeue();
                var containVertex = cfg.ContainsVertex(curVertex);
                // Рассмотрим обратный граф потока управления (все стрелочки – в обратную сторону)
                var incomingEdges = containVertex ? cfg.InEdges(curVertex) : new List <Edge <ThreeAddressCode> >();
                foreach (var edge in incomingEdges)
                {
                    if (!visitedVertex.Contains(edge.Source))
                    {
                        targetVertex.Enqueue(edge.Source);
                    }
                    if (!Graph.Vertices.Contains(edge.Source))
                    {
                        Graph.AddVertex(edge.Source);
                    }
                    Graph.AddEdge(new Edge <ThreeAddressCode>(edge.Source, edge.Target));
                }
                visitedVertex.Add(curVertex);
            }
        }