예제 #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;
    }
                private void FixpointComputation(APC entry, Postconditions initialState)
                {
                    var todo = new List <Tuple <APC, Preconditions> >()
                    {
                        new Tuple <APC, Preconditions>(entry, initialState)
                    };
                    var stable = new Set <APC>();

                    while (todo.Count != 0)
                    {
                        this.timeout.CheckTimeOut("backwards postcondition propagation");

                        var next = todo.ExtractFirst();

                        var nextPC    = next.Item1;
                        var nextState = next.Item2;

                        var newPre = nextState;

                        // do the block
                        {
                            APC pred;
                            while (CFG.HasSinglePredecessor(nextPC, out pred) && !CFG.IsJoinPoint(nextPC))
                            {
                                this.timeout.CheckTimeOut("backwards postcondition propagation (block)");

                                //var post = CFG.Predecessors(nextPC).First();
                                newPre = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this);

                                // no pre, killing the path
                                if (newPre == null)
                                {
                                    break;
                                }

                                // TODO: check for contraddictions

                                nextPC = pred;
                            }
                        }
                        if (nextPC.Equals(CFG.EntryAfterRequires) || nextPC.Equals(CFG.Entry))
                        {
                            this.invariants = newPre;

                            continue;
                        }

                        var fixpointReached = false;

                        if (CFG.IsJoinPoint(nextPC))
                        {
                            Preconditions prev;
                            if (this.joinPoints.TryGetValue(nextPC, out prev))
                            {
                                newPre = Join(prev, newPre, CFG.IsForwardBackEdgeTarget(nextPC.Block.First), out fixpointReached);

                                if (fixpointReached)
                                {
                                    stable.Add(nextPC.Block.First);
                                }
                            }
                            joinPoints[nextPC] = newPre;
                        }

                        // Split in the backwards analysis
                        foreach (var pred in CFG.Predecessors(nextPC))
                        {
                            if (fixpointReached && CFG.IsForwardBackEdge(pred, nextPC))
                            {
                                continue;
                            }
                            if (this.Mdriver.IsUnreachable(nextPC))
                            {
                                continue;
                            }
                            var transf = this.Mdriver.BackwardTransfer(nextPC, pred, newPre, this);
                            if (transf != null)
                            {
                                todo.Add(new Tuple <APC, Preconditions>(pred, transf));
                            }
                        }
                    }
                }
예제 #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);
        }
 public bool IsForwardBackEdge(APC from, APC to)
 {
     return(underlying.IsForwardBackEdge(from, to));
 }