Ejemplo 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);
        }
    /// <summary>
    /// Examines a CFG and removes the stack manipulating instructions by introducing
    /// some explicit variables for stack locations.  After this transformation, no more
    /// Pop, Dup etc.
    /// </summary>
    /// <param name="cfg">Control Flow Graph that is modified by the transformation.
    /// This argument WILL be mutated.</param>
    /// <returns>A map that assigns to each block from <c>cfg</c> the stack depth at its
    /// beginning.  Useful as a pseudo-liveness information.</returns>
    public static int[] Process(ControlFlowGraph cfg) 
    {
      StackRemovalTransformation sd = new StackRemovalTransformation(cfg);

			StackRemovalVisitor srv = new StackRemovalVisitor();

      // should be in order.
      foreach (CfgBlock block in cfg.PreOrder) {
        int depth = sd.InitialDepthOfBlock(block, cfg);

        if (depth < 0) { 
          continue;
        }

        // set block starting depth
        srv.depth = depth;

        StatementList stats = block.Statements;
        for(int i = 0, n = stats.Count; i < n; i++) {
          stats[i] = (Statement) srv.Visit(stats[i]);
          if (cfg.GenericsUse == null) { cfg.GenericsUse = srv.GenericsUse; }
          if (cfg.PointerUse == null) { cfg.PointerUse = srv.PointerUse; }
          if (srv.SawMissingInfo) { cfg.HasMissingInfo = true; }
        }

        // push final depth onto successors.
        foreach (CfgBlock succ in cfg.NormalSucc(block)) {
          sd.PushDepth(succ, srv.depth);
        }
      }

      // finalize stack depth info on each block
      foreach (CfgBlock block in cfg.Blocks()) 
      {
        int depth = sd.block2depth[block.Index];
        // cache depth on block
        block.stackDepth = depth;

        if (depth < 0) {
          // unreachable
          // set statementlist to null in case some backward analysis or other code gets to it
          if (block.Statements.Count > 0) {
            block.Statements = new StatementList(0);
          }
        }
      }
      return sd.block2depth;
    }
Ejemplo n.º 3
0
        /// <summary>
        /// Examines a CFG and removes the stack manipulating instructions by introducing
        /// some explicit variables for stack locations.  After this transformation, no more
        /// Pop, Dup etc.
        /// </summary>
        /// <param name="cfg">Control Flow Graph that is modified by the transformation.
        /// This argument WILL be mutated.</param>
        /// <returns>A map that assigns to each block from <c>cfg</c> the stack depth at its
        /// beginning.  Useful as a pseudo-liveness information.</returns>
        public static int[] Process(ControlFlowGraph cfg)
        {
            StackRemovalTransformation sd = new StackRemovalTransformation(cfg);

            StackRemovalVisitor srv = new StackRemovalVisitor();

            // should be in order.
            foreach (CfgBlock block in cfg.PreOrder)
            {
                int depth = sd.InitialDepthOfBlock(block, cfg);

                if (depth < 0)
                {
                    continue;
                }

                // set block starting depth
                srv.depth = depth;

                StatementList stats = block.Statements;
                for (int i = 0, n = stats.Count; i < n; i++)
                {
                    stats[i] = (Statement)srv.Visit(stats[i]);
                    if (cfg.GenericsUse == null)
                    {
                        cfg.GenericsUse = srv.GenericsUse;
                    }
                    if (cfg.PointerUse == null)
                    {
                        cfg.PointerUse = srv.PointerUse;
                    }
                    if (srv.SawMissingInfo)
                    {
                        cfg.HasMissingInfo = true;
                    }
                }

                // push final depth onto successors.
                foreach (CfgBlock succ in cfg.NormalSucc(block))
                {
                    sd.PushDepth(succ, srv.depth);
                }
            }

            // finalize stack depth info on each block
            foreach (CfgBlock block in cfg.Blocks())
            {
                int depth = sd.block2depth[block.Index];
                // cache depth on block
                block.stackDepth = depth;

                if (depth < 0)
                {
                    // unreachable
                    // set statementlist to null in case some backward analysis or other code gets to it
                    if (block.Statements.Count > 0)
                    {
                        block.Statements = new StatementList(0);
                    }
                }
            }
            return(sd.block2depth);
        }