Пример #1
0
    public static bool isEqual(GenKillWeight w1, GenKillWeight w2) {
      Contract.Requires(w2 != null);
      Contract.Requires(w1 != null);
      if (w1.isZero)
        return w2.isZero;
      if (w2.isZero)
        return w1.isZero;

      return (w1.gen.Equals(w2.gen) && w1.kill.Equals(w2.kill));
    }
Пример #2
0
    public ICFG(Implementation impl) {
      Contract.Requires(impl != null);
      this.graph = new Graph<Block/*!*/>();
      this.procsCalled = new Dictionary<string/*!*/, List<Block/*!*/>/*!*/>();
      this.nodes = new HashSet<Block/*!*/>();
      this.succEdges = new Dictionary<Block/*!*/, HashSet<Block/*!*/>/*!*/>();
      this.predEdges = new Dictionary<Block/*!*/, HashSet<Block/*!*/>/*!*/>();

      this.priority = new Dictionary<Block/*!*/, int>();

      this.srcNodes = new HashSet<Block/*!*/>();
      this.exitNodes = new HashSet<Block/*!*/>();

      this.weightBefore = new Dictionary<Block/*!*/, GenKillWeight/*!*/>();
      this.weightAfter = new Dictionary<Block/*!*/, GenKillWeight/*!*/>();
      this.liveVarsAfter = new Dictionary<Block/*!*/, HashSet<Variable/*!*/>/*!*/>();
      this.liveVarsBefore = new Dictionary<Block/*!*/, HashSet<Variable/*!*/>/*!*/>();

      summary = GenKillWeight.zero();
      this.impl = impl;

      Initialize(impl);

    }
Пример #3
0
    public static GenKillWeight combine(GenKillWeight w1, GenKillWeight w2) {
      Contract.Requires(w2 != null);
      Contract.Requires(w1 != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);
      if (w1.isZero)
        return w2;
      if (w2.isZero)
        return w1;

      HashSet<Variable> g = new HashSet<Variable>(w1.gen);
      g.UnionWith(w2.gen);
      HashSet<Variable> k = new HashSet<Variable>(w1.kill);
      k.IntersectWith(w2.kill);
      return new GenKillWeight(g, k);
      //return new GenKillWeight(w1.gen.Union(w2.gen), w1.kill.Intersection(w2.kill));
    }
Пример #4
0
    public static GenKillWeight projectLocals(GenKillWeight w) {
      Contract.Requires(w != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);
      HashSet<Variable/*!*/> gen = new HashSet<Variable>();
      foreach (Variable v in w.gen)
      {
          if (isGlobal(v))
              gen.Add(v);
      }
      HashSet<Variable/*!*/> kill = new HashSet<Variable>();
      foreach (Variable v in w.kill)
      {
          if (isGlobal(v))
              kill.Add(v);
      }

      return new GenKillWeight(gen, kill);
    }
Пример #5
0
    public static GenKillWeight extend(GenKillWeight w1, GenKillWeight w2) {
      Contract.Requires(w2 != null);
      Contract.Requires(w1 != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);
      if (w1.isZero || w2.isZero)
        return zero();

      HashSet<Variable> t = new HashSet<Variable>(w2.gen);
      t.ExceptWith(w1.kill);
      HashSet<Variable> g = new HashSet<Variable>(w1.gen);
      g.UnionWith(t);
      HashSet<Variable> k = new HashSet<Variable>(w1.kill);
      k.UnionWith(w2.kill);
      return new GenKillWeight(g, k);
      //return new GenKillWeight(w1.gen.Union(w2.gen.Difference(w1.kill)), w1.kill.Union(w2.kill));
    }
Пример #6
0
    private static GenKillWeight getWeightBeforeCall(Cmd cmd) {
      Contract.Requires(cmd != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);
      Contract.Assert((cmd is CallCmd));
      if (weightCacheBeforeCall.ContainsKey(cmd))
        return weightCacheBeforeCall[cmd];

      HashSet<Variable/*!*/>/*!*/ gen = new HashSet<Variable/*!*/>();
      HashSet<Variable/*!*/>/*!*/ kill = new HashSet<Variable/*!*/>();
      CallCmd/*!*/ ccmd = cce.NonNull((CallCmd/*!*/)cmd);

      foreach (Expr/*!*/ expr in ccmd.Ins) {
        Contract.Assert(expr != null);
        VariableCollector/*!*/ collector = new VariableCollector();
        collector.Visit(expr);
        gen.UnionWith(collector.usedVars);
      }

      Contract.Assert(ccmd.Proc != null);

      // Variables in requires are considered as "read"
      foreach (Requires/*!*/ re in ccmd.Proc.Requires) {
        Contract.Assert(re != null);
        VariableCollector/*!*/ collector = new VariableCollector();
        collector.Visit(re.Condition);
        foreach (Variable/*!*/ v in collector.usedVars) {
          Contract.Assert(v != null);
          if (v is GlobalVariable) {
            gen.Add(v);
          }
        }
      }

      // Old variables in ensures are considered as "read"
      foreach (Ensures/*!*/ re in ccmd.Proc.Ensures) {
        Contract.Assert(re != null);
        VariableCollector/*!*/ collector = new VariableCollector();
        collector.Visit(re.Condition);
        foreach (Variable/*!*/ v in collector.oldVarsUsed) {
          Contract.Assert(v != null);
          if (v is GlobalVariable) {
            gen.Add(v);
          }
        }
      }

      GenKillWeight/*!*/ ret = new GenKillWeight(gen, kill);
      Contract.Assert(ret != null);
      weightCacheAfterCall[cmd] = ret;
      return ret;
    }
Пример #7
0
    private static GenKillWeight getWeightAfterCall(Cmd cmd) {
      Contract.Requires(cmd != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);

      if (weightCacheAfterCall.ContainsKey(cmd))
        return weightCacheAfterCall[cmd];

      HashSet<Variable/*!*/>/*!*/ gen = new HashSet<Variable/*!*/>();
      HashSet<Variable/*!*/>/*!*/ kill = new HashSet<Variable/*!*/>();

      Contract.Assert(cmd is CallCmd);
      CallCmd/*!*/ ccmd = cce.NonNull((CallCmd)cmd);

      foreach (IdentifierExpr/*!*/ ie in ccmd.Outs) {
        Contract.Assert(ie != null);
        if (ie.Decl != null)
          kill.Add(ie.Decl);
      }

      // Variables in ensures are considered as "read"
      foreach (Ensures/*!*/ re in cce.NonNull(ccmd.Proc).Ensures) {
        Contract.Assert(re != null);
        VariableCollector/*!*/ collector = new VariableCollector();
        collector.Visit(re.Condition);
        foreach (Variable/*!*/ v in collector.usedVars) {
          Contract.Assert(v != null);
          if (v is GlobalVariable) {
            gen.Add(v);
          }
        }
      }

      GenKillWeight/*!*/ ret = new GenKillWeight(gen, kill);
      Contract.Assert(ret != null);
      weightCacheAfterCall[cmd] = ret;
      return ret;
    }
Пример #8
0
    private static GenKillWeight getWeight(Cmd cmd, Implementation impl, Program prog) {
      Contract.Requires(cmd != null);
      Contract.Ensures(Contract.Result<GenKillWeight>() != null);

      if (weightCache.ContainsKey(cmd))
        return weightCache[cmd];

      HashSet<Variable/*!*/>/*!*/ gen = new HashSet<Variable/*!*/>();
      HashSet<Variable/*!*/>/*!*/ kill = new HashSet<Variable/*!*/>();
      GenKillWeight/*!*/ ret;

      if (cmd is AssignCmd) {
        AssignCmd/*!*/ assignCmd = (AssignCmd)cmd;
        Contract.Assert(cmd != null);
        // I must first iterate over all the targets and remove the live ones.
        // After the removals are done, I must add the variables referred on 
        // the right side of the removed targets
        foreach (AssignLhs/*!*/ lhs in assignCmd.Lhss) {
          Contract.Assert(lhs != null);
          Variable var = lhs.DeepAssignedVariable;
          if (var != null) {
            if (lhs is SimpleAssignLhs) {
              // we should only remove non-map target variables because there is an implicit
              // read of a map variable in an assignment to it
              kill.Add(var);
            }
          }
        }
        int index = 0;
        foreach (Expr/*!*/ expr in assignCmd.Rhss) {
          Contract.Assert(expr != null);
          VariableCollector/*!*/ collector = new VariableCollector();
          collector.Visit(expr);
          gen.UnionWith(collector.usedVars);
          AssignLhs lhs = assignCmd.Lhss[index];
          if (lhs is MapAssignLhs) {
            // If the target is a map, then all indices are also read
            MapAssignLhs malhs = (MapAssignLhs)lhs;
            foreach (Expr e in malhs.Indexes) {
              VariableCollector/*!*/ c = new VariableCollector();
              c.Visit(e);
              gen.UnionWith(c.usedVars);
            }
          }
          index++;
        }
        ret = new GenKillWeight(gen, kill);
      } else if (cmd is HavocCmd) {
        HavocCmd/*!*/ havocCmd = (HavocCmd)cce.NonNull(cmd);
        foreach (IdentifierExpr/*!*/ expr in havocCmd.Vars) {
          Contract.Assert(expr != null);
          if (expr.Decl != null) {
            kill.Add(expr.Decl);
          }
        }
        ret = new GenKillWeight(gen, kill);
      } else if (cmd is PredicateCmd) {
        Contract.Assert((cmd is AssertCmd || cmd is AssumeCmd));
        PredicateCmd/*!*/ predicateCmd = (PredicateCmd)cce.NonNull(cmd);
        if (predicateCmd.Expr is LiteralExpr && prog != null && impl != null) {
          LiteralExpr le = (LiteralExpr)predicateCmd.Expr;
          if (le.IsFalse) {
            var globals = prog.GlobalVariables;
            Contract.Assert(cce.NonNullElements(globals));
            foreach (Variable/*!*/ v in globals) {
              Contract.Assert(v != null);
              kill.Add(v);
            }
            foreach (Variable/*!*/ v in impl.LocVars) {
              Contract.Assert(v != null);
              kill.Add(v);
            }
            foreach (Variable/*!*/ v in impl.OutParams) {
              Contract.Assert(v != null);
              kill.Add(v);
            }
          }
        } else {
          VariableCollector/*!*/ collector = new VariableCollector();
          collector.Visit(predicateCmd.Expr);
          gen.UnionWith(collector.usedVars);
        }
        ret = new GenKillWeight(gen, kill);
      } else if (cmd is CommentCmd) {
        ret = new GenKillWeight(gen, kill);
        // comments are just for debugging and don't affect verification
      } else if (cmd is SugaredCmd) {
        SugaredCmd/*!*/ sugCmd = (SugaredCmd)cmd;
        Contract.Assert(sugCmd != null);
        ret = getWeight(sugCmd.Desugaring, impl, prog);
      } else if (cmd is StateCmd) {
        StateCmd/*!*/ stCmd = (StateCmd)cmd;
        Contract.Assert(stCmd != null);
        List<Cmd>/*!*/ cmds = stCmd.Cmds;
        Contract.Assert(cmds != null);
        int len = cmds.Count;
        ret = GenKillWeight.one();
        for (int i = len - 1; i >= 0; i--) {
          GenKillWeight/*!*/ w = getWeight(cmds[i], impl, prog);
          Contract.Assert(w != null);
          ret = GenKillWeight.extend(w, ret);
        }
        foreach (Variable/*!*/ v in stCmd.Locals) {
          Contract.Assert(v != null);
          kill.Add(v);
        }
        ret = GenKillWeight.extend(new GenKillWeight(gen, kill), ret);
      } else {
        {
          Contract.Assert(false);
          throw new cce.UnreachableException();
        }
      }

      weightCache[cmd] = ret;
      return ret;
    }
Пример #9
0
 public bool setWeightBefore(GenKillWeight w) {
   Contract.Requires(w != null);
   GenKillWeight/*!*/ prev = cfg.weightBefore[block];
   Contract.Assert(prev != null);
   GenKillWeight/*!*/ curr = GenKillWeight.combine(w, prev);
   Contract.Assert(curr != null);
   if (GenKillWeight.isEqual(prev, curr))
     return false;
   cfg.weightBefore[block] = curr;
   return true;
 }