Exemplo n.º 1
0
        /// <summary>
        /// Compute a pre order (ignoring back edges) of the CFG reachable from the entry node
        ///
        /// As a side effect, assigns each block its DF finishing number.
        /// </summary>
        public static FList /*<BasicBlocks>*/ Compute(ControlFlowGraph cfg)
        {
            // depth-first search

            bool[] markBit = new bool[cfg.BlockCount];

            FList result = null;
            int   DFTime = 0;

            // Use a stack to represent the state of the search.
            // Each stack element consists of a basic block and the
            // the index of the next successor of that block to process.

            Stack stack = new Stack();

            CfgBlock[] blocks = cfg.Blocks();

            CfgBlock start = cfg.Entry;

            // invariant: all blocks pushed on the stack are marked.
            markBit[start.Index] = true;
            stack.Push(new StackElem(start));
            while (stack.Count > 0)
            {
                StackElem  elem             = (StackElem)stack.Peek();
                CfgBlock   b                = elem.node;
                int        nextChild        = elem.nextChild;
                CfgBlock[] normalNodes      = cfg.NormalSucc(b);
                CfgBlock[] exnNodes         = cfg.ExcpSucc(b);
                int        normalNodesCount = normalNodes.Length;
                int        exnNodesCount    = exnNodes.Length;
                // Is there another child to process?
                if (nextChild < normalNodesCount + exnNodesCount)
                {
                    // Figure out the actual block.
                    CfgBlock child;
                    if (nextChild < normalNodesCount)
                    {
                        child = normalNodes[nextChild];
                    }
                    else
                    {
                        child = exnNodes[nextChild - normalNodesCount];
                    }
                    elem.nextChild = nextChild + 1;
                    // push the child block on to the stack.
                    if (!markBit[child.Index])
                    {
                        markBit[child.Index] = true;
                        stack.Push(new StackElem(child));
                    }
                }
                else
                {
                    // After all children are processed, place the block
                    // on the result.
                    stack.Pop();
                    b.priority = ++DFTime;
                    result     = FList.Cons(b, result);
                }
            }
            return(result);
        }