Example #1
0
 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>();
 }
Example #2
0
        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);
        }
Example #3
0
        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!");
            }
        }