コード例 #1
0
        private void Analyse(Implementation impl, BigBlock bb)
        {
            Analyse(impl, bb.simpleCmds);

            if (bb.ec is WhileCmd)
            {
                WhileCmd wc = bb.ec as WhileCmd;

                ExprMayAffectControlFlow(impl.Name, wc.Guard);

                Analyse(impl, wc.Body);
            }
            else if (bb.ec is IfCmd)
            {
                IfCmd ifCmd = bb.ec as IfCmd;

                ExprMayAffectControlFlow(impl.Name, ifCmd.Guard);

                Analyse(impl, ifCmd.thn);
                if (ifCmd.elseBlock != null)
                {
                    Analyse(impl, ifCmd.elseBlock);
                }
                Debug.Assert(ifCmd.elseIf == null);
            }
        }
コード例 #2
0
        private void AddAccessFuncs(AccessType access)
        {
            foreach (var mr in SharedStateAnalyser.GetMemoryRegions(this.EP))
            {
                List <Variable> inParams = new List <Variable>();

                if (mr.TypedIdent.Type.IsMap)
                {
                    inParams.Add(new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "ptr",
                                                                                 this.AC.MemoryModelType)));
                }

                Procedure proc = new Procedure(Token.NoToken, this.MakeAccessFuncName(access, mr.Name),
                                               new List <TypeVariable>(), inParams, new List <Variable>(),
                                               new List <Requires>(), new List <IdentifierExpr>(), new List <Ensures>());
                proc.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

                this.AC.TopLevelDeclarations.Add(proc);
                this.AC.ResContext.AddProcedure(proc);

                var cmds = new List <Cmd>();

                foreach (var ls in this.AC.MemoryLocksets)
                {
                    if (!ls.TargetName.Equals(mr.Name))
                    {
                        continue;
                    }
                    if (this.ShouldSkipLockset(ls))
                    {
                        continue;
                    }

                    foreach (var cls in this.AC.CurrentLocksets)
                    {
                        if (!cls.Lock.Name.Equals(ls.Lock.Name))
                        {
                            continue;
                        }

                        IdentifierExpr lsExpr = new IdentifierExpr(ls.Id.tok, ls.Id);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, lsExpr)
                        }, new List <Expr> {
                            Expr.And(new IdentifierExpr(cls.Id.tok, cls.Id), lsExpr)
                        }));

                        proc.Modifies.Add(lsExpr);
                        break;
                    }
                }

                if (access == AccessType.WRITE)
                {
                    foreach (var acv in this.AC.GetWriteAccessCheckingVariables())
                    {
                        if (!acv.Name.Split('_')[1].Equals(mr.Name))
                        {
                            continue;
                        }

                        var wacs = this.AC.GetWriteAccessCheckingVariables().Find(val =>
                                                                                  val.Name.Contains(this.AC.GetWriteAccessVariableName(this.EP, mr.Name)));
                        var wacsExpr = new IdentifierExpr(wacs.tok, wacs);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, wacsExpr)
                        }, new List <Expr> {
                            Expr.True
                        }));

                        proc.Modifies.Add(wacsExpr);
                    }
                }
                else if (access == AccessType.READ)
                {
                    foreach (var acv in this.AC.GetReadAccessCheckingVariables())
                    {
                        if (!acv.Name.Split('_')[1].Equals(mr.Name))
                        {
                            continue;
                        }

                        var racs = this.AC.GetReadAccessCheckingVariables().Find(val =>
                                                                                 val.Name.Contains(this.AC.GetReadAccessVariableName(this.EP, mr.Name)));
                        var racsExpr = new IdentifierExpr(racs.tok, racs);

                        cmds.Add(new AssignCmd(Token.NoToken,
                                               new List <AssignLhs>()
                        {
                            new SimpleAssignLhs(Token.NoToken, racsExpr)
                        }, new List <Expr> {
                            Expr.True
                        }));

                        proc.Modifies.Add(racsExpr);
                    }
                }

                List <BigBlock> blocks = null;
                if (mr.TypedIdent.Type.IsMap)
                {
                    var ptr = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "ptr",
                                                                              this.AC.MemoryModelType));
                    var watchdog = this.AC.GetAccessWatchdogConstants().Find(val =>
                                                                             val.Name.Contains(this.AC.GetAccessWatchdogConstantName(mr.Name)));

                    var ptrExpr      = new IdentifierExpr(ptr.tok, ptr);
                    var watchdogExpr = new IdentifierExpr(watchdog.tok, watchdog);
                    var guardExpr    = Expr.Eq(watchdogExpr, ptrExpr);

                    var ifStmts = new StmtList(new List <BigBlock> {
                        new BigBlock(Token.NoToken, null, cmds, null, null)
                    }, Token.NoToken);
                    var ifCmd = new IfCmd(Token.NoToken, guardExpr, ifStmts, null, null);

                    blocks = new List <BigBlock> {
                        new BigBlock(Token.NoToken, "_" + access.ToString(), new List <Cmd>(), ifCmd, null)
                    };
                }
                else
                {
                    blocks = new List <BigBlock> {
                        new BigBlock(Token.NoToken, "_" + access.ToString(), cmds, null, null)
                    };
                }

                Implementation impl = new Implementation(Token.NoToken, this.MakeAccessFuncName(access, mr.Name),
                                                         new List <TypeVariable>(), inParams, new List <Variable>(), new List <Variable>(),
                                                         new StmtList(blocks, Token.NoToken));

                impl.Proc = proc;
                impl.AddAttribute("inline", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(1)) });

                this.AC.TopLevelDeclarations.Add(impl);
            }
        }
コード例 #3
0
        private void setControlStatement(BasicBlock current, IfCmd ifCmd, BasicBlock next)
        {
//            ExpressionFactory file = new ExpressionFactory(procedure);

            BasicBlock trueBranch  = cfg.addNode("$trueBranch_" + labelIndex.ToString());
            BasicBlock falseBranch = cfg.addNode("$falseBranch_" + labelIndex.ToString());
            BasicBlock join        = cfg.addNode("$join_" + labelIndex.ToString());

            labelIndex++;


            join.setControlStatement(new UnconditionalBranch(join, next));

            ProgramVariable ndcondition;

            if (ifCmd.Guard != null)
            {
                Expression conditionExpression = procedure.expressionFactory.makeExpression(ifCmd.Guard);
                if (!pathConditionMap.TryGetValue(conditionExpression.ToStringN(), out ndcondition))
                {
                    ndcondition = scope.makeFreshProgramVariable(pathConditionPrefix, makeBooleanType());
                    pathConditionMap[conditionExpression.ToStringN()] = ndcondition;
                }
                current.appendStatement(
                    new Assume(
                        new BasicFAE(
                            BFunction.equivalence,
                            new ExpressionList(
                                new BasicProgramVariableExpression(ndcondition),
                                conditionExpression
                                )
                            )
                        )
                    );
            }
            else
            {
                ndcondition = scope.makeFreshProgramVariable(pathConditionPrefix, makeBooleanType());
                nondeterministicConditionVariables.Add(ndcondition);
            }

//            nondeterministicConditionVariables.Add(ndcondition);

            current.setControlStatement(new ConditionalBranch(current, ndcondition, trueBranch, falseBranch));


            bool hasTrueBranch = ifCmd.thn != null && ifCmd.thn.BigBlocks != null && ifCmd.thn.BigBlocks.Count > 0;

            if (hasTrueBranch)
            {
                BasicBlock thenBranch = addBigBlocks(ifCmd.thn, join);
                trueBranch.setControlStatement(new UnconditionalBranch(trueBranch, thenBranch));
            }
            else
            {
                trueBranch.setControlStatement(new UnconditionalBranch(trueBranch, join));
            }

            Debug.Assert(ifCmd.elseBlock == null || ifCmd.elseIf == null);
            if (ifCmd.elseBlock != null)
            {
                BasicBlock elseBranch = addBigBlocks(ifCmd.elseBlock, join);
                falseBranch.setControlStatement(new UnconditionalBranch(falseBranch, elseBranch));
            }
            else if (ifCmd.elseIf != null)
            {
                setControlStatement(falseBranch, ifCmd.elseIf, next);
            }
            else
            {
                falseBranch.setControlStatement(new UnconditionalBranch(falseBranch, join));
            }
        }