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