public StormInstrumentationPass() { passName = "Storm instrumentation"; pinfo = null; policy = null; vmgr = null; inst = null; tinfo_instrument = new InsertionTrans(); tinfo_async = new InsertionTrans(); blockExecutionContextMap = new Dictionary <string, int>(); }
public override CBAProgram runCBAPass(CBAProgram p) { if (p.mode == ConcurrencyMode.FixedContext) { InstrumentationConfig.addRaiseException = false; } // Step1: Gather program information pinfo = new ProgramInfo(p.mainProcName, p, LanguageSemantics.assertNotReachableName()); TidArithmetic.reset(); if (pinfo.threadIdType.IsBv) { TidArithmetic.useIntArithmetic = false; p.AddTopLevelDeclaration(TidArithmetic.getBvAdd()); p.AddTopLevelDeclaration(TidArithmetic.getBvGt()); } else { TidArithmetic.useIntArithmetic = true; } // Step2: Set up a variable manager vmgr = new VariableManager(pinfo); // Step3: Set up the instrumentation policy // The globals not to instrument are: // -- ones not modified by any procedure // -- ones not shared // -- ones to treat as thread-local HashSet <string> globalsToInstrument = new HashSet <string>(); foreach (var g in pinfo.declaredGlobals) { string name = g.Key; if (!pinfo.modifiedGlobals.ContainsKey(name)) { continue; } if (!LanguageSemantics.isShared(name)) { continue; } if (pinfo.threadLocalGlobals.ContainsKey(name)) { continue; } globalsToInstrument.Add(name); } var rprocs = findRecursiveProcs(p); //foreach (var be in rprocs) Console.WriteLine("{0} -> {1}", be.Item1, be.Item2); policy = new InstrumentationPolicy(p.contextBound, globalsToInstrument, pinfo.procsWithImplementation, pinfo.asyncProcs, rprocs, p.mode); //policy.print(Log.getWriter(Log.Debug)); // Step4: Split program declarations based on the instrumentation policy // skipping this step (not needed for basic CBA reduction) // Step5: Carry out the K-split instrumentation inst = new Instrumenter(policy, vmgr, pinfo, tinfo_instrument); List <Declaration> newDecls = inst.instrument(p.TopLevelDeclarations.ToList()); foreach (var trp in inst.blocksWithFixedK) { blockExecutionContextMap.Add(trp.fst + "::" + trp.snd, trp.trd); } // Step6: Instrument main with initialization and the Checker Implementation mainProcImpl = BoogieUtil.findProcedureImpl(newDecls, p.mainProcName); inst.instrumentGivenMainImpl(mainProcImpl); // Step7: Instrument Async calls bool instrumentedAsync = false; InstrumentAsyncCalls ainst = new InstrumentAsyncCalls(vmgr, pinfo, tinfo_async); foreach (var decl in newDecls) { if (decl is Implementation) { ainst.VisitImplementation(decl as Implementation); instrumentedAsync = instrumentedAsync || ainst.hasAsync; } } if (!instrumentedAsync) { Log.WriteLine(Log.Debug, "Warning: Did not find any async call"); } // Step8: Set entrypoint mainProcImpl.AddAttribute("entrypoint"); // Step9: Add new variable declarations newDecls.AddRange(vmgr.getNewDeclarations(policy.executionContextBound)); newDecls.AddRange(BoogieAstFactory.newDecls); BoogieAstFactory.newDecls.Clear(); // Thats it. Program ret = new Program(); ret.TopLevelDeclarations = newDecls; if (InstrumentationConfig.printInstrumented) { // Re-resolve ret ProgTransformation.PersistentProgram tprog = new ProgTransformation.PersistentProgram(ret); var instrumented = tprog.getProgram(); // Re-do the modsets -- make them as concise as possible. BoogieUtil.DoModSetAnalysis(instrumented); // Temporary fix for Boogie's bug while inlining calls // that have don't care expressions. RewriteCallDontCares rdc = new RewriteCallDontCares(); rdc.VisitProgram(instrumented); BoogieUtil.PrintProgram(instrumented, InstrumentationConfig.instrumentedFile); throw new NormalExit("Printed " + InstrumentationConfig.instrumentedFile); } // Resolve the program (Do not typecheck because that does inlining). //BoogieUtil.PrintProgram(ret, "instrumented.bpl"); //ret = BoogieUtil.ReadAndOnlyResolve("instrumented.bpl"); if (p.mode == ConcurrencyMode.FixedContext) { InstrumentationConfig.addRaiseException = true; } p = new CBAProgram(ret, p.mainProcName, p.contextBound); return(p); }
public VariableManager(ProgramInfo pinfo) { varkName = "k"; csProcName = "contextSwitch"; raiseExceptionName = "raiseException"; errorVarName = "assertsPassed"; inAtomicBlockName = "inAtomicBlock"; tidVarName = LanguageSemantics.tidName; tidCountVarName = "tidCount"; oldkVarName = "old_k"; oldtidVarName = "old_tid"; cbaMainName = pinfo.mainProcName; csProcBound = -1; vark = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, varkName, Microsoft.Boogie.Type.Int)); raiseException = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, raiseExceptionName, Microsoft.Boogie.Type.Bool)); errorVar = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, errorVarName, Microsoft.Boogie.Type.Bool)); inAtomicBlock = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inAtomicBlockName, Microsoft.Boogie.Type.Bool)); tidVar = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, tidVarName, pinfo.threadIdType)); tidCountVar = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, tidCountVarName, pinfo.threadIdType)); // Construct type int -> bool var ts = new List <Microsoft.Boogie.Type>(); ts.Add(pinfo.threadIdType); MapType mt = new MapType(Token.NoToken, new List <TypeVariable>(), ts, Microsoft.Boogie.Type.Bool); // Construct type int -> int mt = new MapType(Token.NoToken, new List <TypeVariable>(), ts, Microsoft.Boogie.Type.Int); oldkLocalVars = new Dictionary <string, LocalVariable>(); oldtidLocalVars = new Dictionary <string, LocalVariable>(); declaredGlobals = pinfo.declaredGlobals; numCopiesCreated = 0; gblVarCopies = new Dictionary <string, List <GlobalVariable> >(); gblVarInitCopies = new Dictionary <string, List <GlobalVariable> >(); // Make some copies for now makeCopies(1); // Check if any of variables we're going to insert // have any clashes with what is existing if (declaredGlobals.ContainsKey(varkName) || declaredGlobals.ContainsKey(raiseExceptionName) || declaredGlobals.ContainsKey(errorVarName) || declaredGlobals.ContainsKey(inAtomicBlockName) || pinfo.allProcs.Contains(csProcName)) { throw new InvalidProg("Possible name clashes!"); } }