Пример #1
0
    public static Dictionary<CFGBlock, List<CFGBlock>> ComputeContainingLoopMap(ICFG cfg)
    {
      Contract.Requires(cfg != null);
      Contract.Ensures(Contract.Result<Dictionary<CFGBlock, List<CFGBlock>>>() != null);

      var result = new Dictionary<CFGBlock, List<CFGBlock>>();
      var visitedSubroutines = new Set<int>();
      var pendingSubroutines = new Stack<Subroutine>();
      var pendingAPCs = new Stack<APC>();

      var graph = cfg.AsBackwardGraph(includeExceptionEdges:false, skipContracts:true);
      foreach (var loophead in cfg.LoopHeads)
      {
        // push back-edge sources
        var loopPC = new APC(loophead, 0, null);
        foreach (var pred in cfg.Predecessors(loopPC))
        {
          if (cfg.IsForwardBackEdge(pred, loopPC))
          {
            var normalizedPred = new APC(pred.Block, 0, null);
            pendingAPCs.Push(normalizedPred);
          }
        }
        var visit = new DepthFirst.Visitor<APC, Unit>(graph,
          (APC pc) =>
          {
            if (pc.SubroutineContext != null)
            {
              // push continuation PC
              pendingAPCs.Push(new APC(pc.SubroutineContext.Head.One, 0, null));
              if (visitedSubroutines.AddQ(pc.Block.Subroutine.Id))
              {
                pendingSubroutines.Push(pc.Block.Subroutine);
              }
              return false; // stop exploration
            }
            return !pc.Equals(loopPC);
          });

        while (pendingAPCs.Count > 0)
        {
          var root = pendingAPCs.Pop();
          visit.VisitSubGraphNonRecursive(root);

          while (pendingSubroutines.Count > 0)
          {
            var sub = pendingSubroutines.Pop();
            pendingAPCs.Push(new APC(sub.Exit, 0, null));
          }
        }

        foreach (var visited in visit.Visited)
        {
          if (visited.SubroutineContext != null) continue; // ignore non-primary pcs
          MaterializeContainingLoop(result, visited.Block).AssumeNotNull().Add(loophead);
        }
      }

      return result;
    }
Пример #2
0
        protected void PostProcessBlocks()
        {
            var blockStack = new Stack <CFGBlock> ();

            this.successor_edges = new EdgeMap <EdgeTag> (this.successors);
            this.edge_info       = new DepthFirst.Visitor <CFGBlock, Dummy> (this, null, (block) => blockStack.Push(block), null);
            this.edge_info.VisitSubGraphNonRecursive(this.exception_exit);
            this.edge_info.VisitSubGraphNonRecursive(this.exit);
            this.edge_info.VisitSubGraphNonRecursive(this.entry);

            foreach (var successorEdge in this.successor_edges)
            {
                int idGen = UnusedBlockIndex;
                successorEdge.From.Renumber(ref idGen);
            }
            int idGen1 = 0;

            foreach (CFGBlock cfgBlock in blockStack)
            {
                cfgBlock.Renumber(ref idGen1);
            }

            SuccessorEdges.Filter((e) => e.From.Index != UnusedBlockIndex);
            this.predecessor_edges = this.successor_edges.Reverse();
            int finishTime = 0;
            var visitor    = new DepthFirst.Visitor <CFGBlock, EdgeTag> (this.predecessor_edges, null, block => block.ReversePostOrderIndex = finishTime++, null);

            visitor.VisitSubGraphNonRecursive(this.exit);
            foreach (CFGBlock node in blockStack)
            {
                visitor.VisitSubGraphNonRecursive(node);
            }

            SuccessorEdges.Resort();
            this.blocks = blockStack.ToArray();
            this.LabelsThatStartBlocks = null;
            Builder = null;
        }
Пример #3
0
        public static Dictionary <CFGBlock, List <CFGBlock> > ComputeContainingLoopMap(ICFG cfg)
        {
            Contract.Requires(cfg != null);
            Contract.Ensures(Contract.Result <Dictionary <CFGBlock, List <CFGBlock> > >() != null);

            var result             = new Dictionary <CFGBlock, List <CFGBlock> >();
            var visitedSubroutines = new Set <int>();
            var pendingSubroutines = new Stack <Subroutine>();
            var pendingAPCs        = new Stack <APC>();

            var graph = cfg.AsBackwardGraph(includeExceptionEdges: false, skipContracts: true);

            foreach (var loophead in cfg.LoopHeads)
            {
                // push back-edge sources
                var loopPC = new APC(loophead, 0, null);
                foreach (var pred in cfg.Predecessors(loopPC))
                {
                    if (cfg.IsForwardBackEdge(pred, loopPC))
                    {
                        var normalizedPred = new APC(pred.Block, 0, null);
                        pendingAPCs.Push(normalizedPred);
                    }
                }
                var visit = new DepthFirst.Visitor <APC, Unit>(graph,
                                                               (APC pc) =>
                {
                    if (pc.SubroutineContext != null)
                    {
                        // push continuation PC
                        pendingAPCs.Push(new APC(pc.SubroutineContext.Head.One, 0, null));
                        if (visitedSubroutines.AddQ(pc.Block.Subroutine.Id))
                        {
                            pendingSubroutines.Push(pc.Block.Subroutine);
                        }
                        return(false);  // stop exploration
                    }
                    return(!pc.Equals(loopPC));
                });

                while (pendingAPCs.Count > 0)
                {
                    var root = pendingAPCs.Pop();
                    visit.VisitSubGraphNonRecursive(root);

                    while (pendingSubroutines.Count > 0)
                    {
                        var sub = pendingSubroutines.Pop();
                        pendingAPCs.Push(new APC(sub.Exit, 0, null));
                    }
                }

                foreach (var visited in visit.Visited)
                {
                    if (visited.SubroutineContext != null)
                    {
                        continue;                                    // ignore non-primary pcs
                    }
                    MaterializeContainingLoop(result, visited.Block).AssumeNotNull().Add(loophead);
                }
            }

            return(result);
        }
Пример #4
0
        // Callgraph-ordered
        public override IEnumerable <Method> OrderedMethods()
        {
            var components = StronglyConnectedComponents.Compute(this.callGraph);

            // components are in caller to callee order, so reverse it
            components.Reverse();

            var classGraph    = new SingleEdgeGraph <Type, Unit>(null);
            var mAlreadyThere = new Set <Type>();
            Predicate <Node> nodeStartVisitor = n =>
            {
                if (n.Kind != Node.Tag.method)
                {
                    return(true);
                }
                var m  = n.Method;
                var dt = this.md.DeclaringType(m);
                if (mAlreadyThere.Add(dt))
                {
                    classGraph.AddNode(dt);
                }
                // add edge dt -> type(each successor)
                foreach (var suc in this.callGraph.Successors(n))
                {
                    if (suc.Two.Kind != Node.Tag.method)
                    {
                        continue;
                    }
                    var succmethod = suc.Two.Method;
                    var tsuc       = this.md.DeclaringType(succmethod);
                    if (mAlreadyThere.Add(tsuc))
                    {
                        classGraph.AddNode(tsuc);
                    }
                    classGraph.AddEdge(dt, Unit.Value, tsuc);
                }
                return(true);
            };
            var dfs_construct_class_graph = new DepthFirst.Visitor <Node, Unit>(this.callGraph, nodeStartVisitor);

            dfs_construct_class_graph.VisitAll();

            // Now get the ordering of the class graph
            var class_components = StronglyConnectedComponents.Compute(classGraph);

            class_components.Reverse();

            // Stores the class order
            var class_order = new Dictionary <Type, int>();
            int index       = 0;

            foreach (var compo in class_components)
            {
                foreach (var cl in compo)
                {
                    class_order.Add(cl, index++);
                }
            }

            var indexes = new Dictionary <Method, int>();

            Comparison <Method> compareMethods = (m1, m2) =>
            {
                var t1 = class_order[this.md.DeclaringType(m1)];
                var t2 = class_order[this.md.DeclaringType(m2)];
                if (t1 != t2)
                {
                    return(t2 - t1);
                }
                // regarding to class order, m1 == m2, i.e. keep global methods order
                return(indexes[m2] - indexes[m1]);
            };

            // Stores the global method order to decide inside class graph strong components
            // And populate the method list
            var ordered_methods = new PriorityQueue <Method>(compareMethods);

            index = 0;
            foreach (var component in components)
            {
                foreach (var node in component)
                {
                    if (node.Kind == Node.Tag.method)
                    {
                        indexes[node.Method] = index++;
                        ordered_methods.Add(node.Method);
                    }
                }
            }

            while (ordered_methods.Count > 0)
            {
                yield return(ordered_methods.Pull());
            }
        }