Пример #1
0
		public StronglyConnectedComponents (ControlFlowGraph cfg)
		{
			this.cfg = cfg;
			this.sccMap = null;

			IEnumerable/*<StronglyConnectedComponent<CfgBlock>>*/ all_sccs =
				StronglyConnectedComponent.ConstructSCCs(this.cfg.Blocks(), new BackwardGraphNavigator(this.cfg));
			this.sccs = GraphUtil.TopologicallySortComponentGraph(DataStructUtil.DefaultSetFactory, all_sccs);
		}
    /// <summary>
    /// Starts the analysis at the first instruction of the given block
    /// </summary>
    protected virtual void Run (ControlFlowGraph cfg, CfgBlock startBlock, IDataFlowState startState) 
    {
      this.Reinitialize(cfg);

      pendingStates[startBlock.Index] = startState;
      joinWorkItems.Enqueue(startBlock);

      while (joinWorkItems.Count > 0) 
      {
        //joinWorkItems.Dump();
        CfgBlock currentBlock = joinWorkItems.Dequeue();	

        if (Analyzer.Debug) 
        {
          Console.WriteLine("\n*** Working on block {0} [{1} statements, line {2}]\n", 
            ((currentBlock).UniqueKey), 
            currentBlock.Length, 
            (currentBlock.Length == 0)? -1 : ((Statement)currentBlock[0]).SourceContext.StartLine);
        }

        // Flow the current state through the block.
        IDataFlowState currentState = PopPendingState(currentBlock);
				
        currentState = VisitBlock(currentBlock, currentState);

        // NOTE: VisitBlock may have explicitly pushed states onto some successors. In that case
        // it should return null to avoid this code pushing the same state onto all successors.

        if (currentState != null) 
        {
          foreach (CfgBlock succ in currentBlock.NormalSuccessors) 
          {
            PushState(currentBlock, succ, currentState);
          }
        }

      } //while
    }
 /// <summary>
 /// Starts the analysis from the entry block of the CFG
 /// </summary>
 protected virtual void Run (ControlFlowGraph cfg, IDataFlowState startState) 
 {
   this.Run(cfg, cfg.Entry, startState);
 }
    private void Reinitialize (ControlFlowGraph cfg) 
    {
      this.cfg = cfg;
      this.pendingStates = new IDataFlowState[cfg.BlockCount];
      this.doneStates = new IDataFlowState[cfg.BlockCount];

      // initialize work queue and disabled queue
      joinWorkItems = new WorkQueue(cfg.PreOrderCompare);
    }
Пример #5
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;
    }
Пример #6
0
      public FinallyBlockDuplicator (
        ControlFlowGraph cfg, 
        Method method, 
        IList/*<Block>*/ new_blocks,
        Hashtable/*<Block,Block>*/ block2next, 
        NormalFlowBlockNavigator nfbnav,
        IList/*<ExceptionHandler>*/ all_ehs
        ) {
        this.dupVisitor = new DupVisitor(method.DeclaringType.DeclaringModule, method.DeclaringType);
        this.cfg        = cfg;
        this.method     = method;
        this.new_blocks = new_blocks;
        this.block2next = block2next;
        this.bnav       = new UnionGraphNavigator(nfbnav, new ControlFlowGraph.ExcpFlowBlockNavigator(cfg));
        this.allExceptionHandlers    = all_ehs;

        // init the block -> index map
        this.b2index = new Hashtable();
        StatementList blocks = method.Body.Statements;
        for(int i = 0; i < blocks.Count; i++) {
          b2index[(Block) blocks[i]] = i;
        }

        // init the exception handler -> last block map
        this.lastHandledBlock = new Hashtable();
        foreach (ExceptionHandler eh in this.allExceptionHandlers) {
          if (eh.HandlerType != NodeType.Finally && eh.HandlerType != NodeType.FaultHandler) { continue; } 
          this.lastHandledBlock[eh] = LastBlockInsideHandler(eh);
        }

        // 2. deal with the "leave" instructions
        TreatLeaveInstructions ();

        // 3. The original finally / fault handlers should be turned into catch handlers
        ConvertFinallyHandlerIntoCatchHandler();
      }
Пример #7
0
 internal void AssignIndex(ControlFlowGraph cfg, int index) {
   this.cfg = cfg;
   this.index = index;
 }
Пример #8
0
 public static ControlFlowGraph Cast(ControlFlowGraph cfg) {
   return cfg;
 }
Пример #9
0
		/// <summary>
		/// Get the CFG for a method.  Results are cached, so getting the CFG for the same
		/// method twice will return the same CFG object.
		/// </summary>
		/// <param name="method">Method whose CFG we want to get.</param>
		/// <returns>CFG for <c>method</c>; cached.</returns>
		public virtual ControlFlowGraph ComputeControlFlowGraph (Method method)
		{
			ControlFlowGraph cfg = (ControlFlowGraph) method2cfg[method];
			if (cfg == null)
			{
				cfg = new ControlFlowGraph(method);
				method2cfg.Add(method, cfg);
			}
			return cfg;
		}
Пример #10
0
 public NormalFlowBlockNavigator(ControlFlowGraph parent, Hashtable/*<Block,Block>*/ block2next) {
   this.parent = parent;
   this.block2next = block2next;
 }
Пример #11
0
 public ExcpFlowBlockNavigator(ControlFlowGraph parent) {
   this.parent = parent;
 }