public static VarSet GetAllVars(Program p) { //List<GlobalVariable> globalDecls = BoogieUtil.GetGlobalVariables(p); var procedures = BoogieUtil.GetProcedures(p); var implementations = BoogieUtil.GetImplementations(p); var allVars = new VarSet(); foreach (var proc in procedures) { var uses = new GlobalVarsUsed(); uses.VisitRequiresSeq(proc.Requires); uses.VisitEnsuresSeq(proc.Ensures); // skip visiting modifies clause allVars.Add(new VarSet(uses.globalsUsed, proc.Name)); } foreach (var impl in implementations) { var uses = new GlobalVarsUsed(); uses.VisitBlockList(impl.Blocks); allVars.Add(new VarSet(uses.globalsUsed, impl.Name)); } //globalDecls.Iterate(x => procedures.Iterate(y => allVars.Add(x.Name, y.Name))); //globalDecls.Iterate(x => implementations.Iterate(y => allVars.Add(x.Name, y.Name))); return(allVars); }
public bool hasOldGlobalVarsToInstrument(Absy exp) { GlobalVarsUsed usesg = new GlobalVarsUsed(); usesg.Visit(exp); // If any used variable is also modified then return true if (usesg.oldVarsUsed.Any(x => globalsToInstrument.Contains(x))) { return(true); } return(false); }
public bool hasModifiedGlobalVars(Absy exp) { Debug.Assert(infoGathered); GlobalVarsUsed usesg = new GlobalVarsUsed(); usesg.Visit(exp); // If any used variable is also modified then return true if (usesg.Used.Any(x => modifiedGlobals.ContainsKey(x))) { return(true); } return(false); }
public static bool ApplyTemplates(HashSet <int> templates) { var commonGlobals = Minimize.FindCommonGlobals(); var ret = false; // Prune away ones that don't have constants associated with them templates = new HashSet <int>( templates.Where(t => !templateMap[t].All(tup => tup.Value.SetEquals(fileToKeepConstants[tup.Key])))); // Prune away ones that don't talk about common globals templates = new HashSet <int>( templates.Where(t => { var expr = SimplifyExpr.ToExpr(templateToStr[t]); var vu = new GlobalVarsUsed(); vu.VisitExpr(expr); return(vu.globalsUsed.IsSubsetOf(commonGlobals)); })); var newFileToProg = new Dictionary <string, PersistentProgram>(); var templateToConstants = new Dictionary <int, int>(); templates.Iter(t => templateToConstants.Add(t, 0)); foreach (var tup in fileToProg) { var program = tup.Value.getProgram(); BoogieUtil.DoModSetAnalysis(program); var globals = new HashSet <string>(program.TopLevelDeclarations.OfType <GlobalVariable>().Select(g => g.Name)); var newconstants = new HashSet <Constant>(); foreach (var t in templates) { var expr = SimplifyExpr.ToExpr(templateToStr[t]); var nonold = new GatherNonOldVariables(); nonold.VisitExpr(expr); var mustmod = new HashSet <string>(nonold.variables); mustmod.IntersectWith(globals); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { var mod = new HashSet <string>(impl.Proc.Modifies.Select(ie => ie.Name)); if (!mustmod.IsSubsetOf(mod)) { continue; } // create new constant var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++), btype.Bool), false); nc.AddAttribute("existential"); newconstants.Add(nc); if (!templateMap[t].ContainsKey(tup.Key)) { templateMap[t].Add(tup.Key, new HashSet <string>()); } templateMap[t][tup.Key].Add(nc.Name); ret = true; templateToConstants[t]++; impl.Proc.Ensures.Add(new Ensures(false, Expr.Imp(Expr.Ident(nc), expr))); } } program.AddTopLevelDeclarations(newconstants); newFileToProg.Add(tup.Key, new PersistentProgram(program)); } fileToProg = newFileToProg; foreach (var tup in templateToConstants) { Console.WriteLine("Applying template {0}: {1} ({2} constants created)", tup.Key, templateToStr[tup.Key], tup.Value); } return(ret); }
// This is the main place where the rewriting happens public override Block VisitBlock(Block block) { GlobalVarsUsed usesg = new GlobalVarsUsed(); // The new list of commands that we will construct List <Cmd> lcmds = new List <Cmd>(); foreach (Cmd cmd in block.Cmds) { if (!(cmd is CallCmd)) { lcmds.Add(cmd); continue; } CallCmd ccmd = cmd as CallCmd; // If the call command doesn't have any don't cares, then no need // to instrument bool found = false; found = ccmd.Outs.Any(x => (x == null)); found = found || ccmd.Ins.Any(x => (x == null)); if (!found) { lcmds.Add(cmd); continue; } // Get ready to instrument // This is the list of locals to havoc (for the arguments) List <IdentifierExpr> havocArgs = new List <IdentifierExpr>(); // Go through the arguments of the call for (int i = 0, n = ccmd.Ins.Count; i < n; i++) { if (ccmd.Ins[i] == null) { Variable lvar = getNewLocal(ccmd.Proc.InParams[i].TypedIdent.Type); havocArgs.Add(new IdentifierExpr(Token.NoToken, lvar)); ccmd.Ins[i] = Expr.Ident(lvar); } } /* * // havoc locals -- not needed; because locals are uninitialized * if (havocArgs.Length != 0) * { * lcmds.Add(new HavocCmd(Token.NoToken, havocArgs)); * } */ // Go through the return values for (int i = 0, n = ccmd.Outs.Count; i < n; i++) { if (ccmd.Outs[i] == null) { Variable lvar = getNewLocal(ccmd.Proc.OutParams[i].TypedIdent.Type); ccmd.Outs[i] = new IdentifierExpr(Token.NoToken, lvar); } } // the new call command lcmds.Add(ccmd); } block.Cmds = lcmds; return(block); }