コード例 #1
0
        /// <summary>
        /// Analyzes the loop nesting structure of the control-flow graph.
        /// The default implementation directs the tasks to Havlak's algorithm.
        /// </summary>
        protected virtual void AnalyzeLoops()
        {
            IGraphAdapter <BasicBlock <Ti> > a = BasicBlock <Ti> .LoopAnalysisAdapter;

            BasicBlock <Ti>[] reachable = a.GetPreOrder(BasicBlocks, EntryCB);
            a.InvertRelation(a.Succs, a.Preds, reachable);
            a.AnalyzeLoops(reachable, EntryCB);
        }
コード例 #2
0
        /// <summary>
        /// Determines the loop nesting structure of the given (control-flow) graph.
        /// </summary>
        /// <remarks>
        /// This is an implementation of Paul Havlak's loop analysis algorithm.
        /// Reference: ACM Transactions on Programming Languages and Systems, Vol. 19, No. 4, July 1997, Pages 557-567.
        /// </remarks>
        /// <param name="a">graph adapter</param>
        /// <param name="nodes">nodes to consider</param>
        /// <param name="start">entry node</param>
        public static void AnalyzeLoops <T>(this IGraphAdapter <T> a,
                                            IList <T> nodes, T start)
        {
            T[] order = a.GetPreOrder(nodes, start);

            // fix_loops part
#if false
            foreach (T w in order)
            {
                a.RedBackIn[w] = new HashSet <T>();
                a.OtherIn[w]   = new HashSet <T>();
                foreach (T v in a.Preds[w])
                {
                    if (a.PreOrderIndex[w] < a.PreOrderIndex[v])
                    {
                        a.RedBackIn[w].Add(v);
                    }
                    else
                    {
                        a.OtherIn[w].Add(v);
                    }
                }
                if (a.RedBackIn[w].Count > 0 && a.OtherIn[w].Count > 1)
                {
                    throw new NotImplementedException();
                }
            }
#endif

            foreach (T w in order /*nodes*/)
            {
                a.BackPreds[w]    = new HashSet <T>();
                a.NonBackPreds[w] = new HashSet <T>();
                a.Header[w]       = start;
                a.Type[w]         = ENodeType.Nonheader;
                foreach (T v in a.Preds[w])
                {
                    if (a.IsAncestor(w, v))
                    {
                        a.BackPreds[w].Add(v);
                    }
                    else
                    {
                        a.NonBackPreds[w].Add(v);
                    }
                }
            }
            a.Header[start] = default(T);
            HashSet <T>   P  = new HashSet <T>();
            UnionFind <T> uf = new PreOrderSetAdapter <T>(a).CreateUnionFind(order);
            for (int iw = order.Length - 1; iw >= 0; iw--)
            {
                T w = order[iw];
                P.Clear();
                foreach (T v in a.BackPreds[w])
                {
                    if (!v.Equals(w))
                    {
                        P.Add(uf.Find(v));
                    }
                    else
                    {
                        a.Type[w] = ENodeType.Self;
                    }
                }
                Queue <T> worklist = new Queue <T>(P);
                if (P.Count > 0)
                {
                    a.Type[w] = ENodeType.Reducible;
                }
                while (worklist.Count > 0)
                {
                    T x = worklist.Dequeue();
                    foreach (T y in a.NonBackPreds[x])
                    {
                        T y_ = uf.Find(y);
                        if (!a.IsAncestor(w, y_))
                        {
                            a.Type[w] = ENodeType.Irreducible;
                            a.NonBackPreds[w].Add(y_);
                        }
                        else if (!P.Contains(y_) && !w.Equals(y_))
                        {
                            P.Add(y_);
                            worklist.Enqueue(y_);
                        }
                    }
                }
                foreach (T x in P)
                {
                    a.Header[x] = w;
                    uf.Union(x, w);
                }
            }
        }