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)); }
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); }
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)); }
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); }
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)); }
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; }
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; }
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; }
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; }