Пример #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;
    }