Пример #1
0
 public virtual AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
 {
     Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <AssignLhs>() != null);
     node.AssignedVariable =
         (IdentifierExpr)this.VisitIdentifierExpr(node.AssignedVariable);
     return(node);
 }
Пример #2
0
        public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
        {
            var e = VisitIdentifierExpr(node.AssignedVariable);

            if (!(e is IdentifierExpr))
            {
                throw new InvalidExpressionException("lhs must be an identifier, also after substitution --> malformed property??");
            }
            return(new SimpleAssignLhs(node.tok, (IdentifierExpr)e));
        }
Пример #3
0
        public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
        {
            if (boogieVarTranslation.VarTranslation.TryTranslateVariableId(node.AssignedVariable.Decl, out var varId,
                                                                           out _))
            {
                ReturnResult(varId);
                return(node);
            }

            throw new ProofGenUnexpectedStateException(GetType(),
                                                       "Cannot extract id from variable " + node.AssignedVariable.Name);
        }
Пример #4
0
        void AddAssignment(IRegion region, VarDefMap multiDefMap, SimpleAssignLhs lhs, Expr rhs)
        {
            if (lhs == null)
            {
                return;
            }

            var variable = lhs.DeepAssignedVariable;

            if (!multiDefMap.ContainsKey(variable))
            {
                multiDefMap[variable] = new List <Tuple <IRegion, Expr> >();
            }
            multiDefMap[variable].Add(new Tuple <IRegion, Expr>(region, rhs));
        }
Пример #5
0
        public override Cmd VisitAssignCmd(AssignCmd node)
        {
            HashSet <Variable> rhsVars = new HashSet <Variable>();

            for (int i = 0; i < node.Lhss.Count; i++)
            {
                AssignLhs lhs        = node.Lhss[i];
                Variable  lhsVar     = lhs.DeepAssignedVariable;
                string    domainName = FindDomainName(lhsVar);
                if (domainName == null)
                {
                    continue;
                }
                SimpleAssignLhs salhs = lhs as SimpleAssignLhs;
                if (salhs == null)
                {
                    Error(node, string.Format("Only simple assignment allowed on linear variable {0}", lhsVar.Name));
                    continue;
                }
                IdentifierExpr rhs = node.Rhss[i] as IdentifierExpr;
                if (rhs == null)
                {
                    Error(node, string.Format("Only variable can be assigned to linear variable {0}", lhsVar.Name));
                    continue;
                }
                string rhsDomainName = FindDomainName(rhs.Decl);
                if (rhsDomainName == null)
                {
                    Error(node, string.Format("Only linear variable can be assigned to linear variable {0}", lhsVar.Name));
                    continue;
                }
                if (domainName != rhsDomainName)
                {
                    Error(node, string.Format("Linear variable of domain {0} cannot be assigned to linear variable of domain {1}", rhsDomainName, domainName));
                    continue;
                }
                if (rhsVars.Contains(rhs.Decl))
                {
                    Error(node, string.Format("Linear variable {0} can occur only once in the right-hand-side of an assignment", rhs.Decl.Name));
                    continue;
                }
                rhsVars.Add(rhs.Decl);
            }
            return(base.VisitAssignCmd(node));
        }
        /// <summary>
        /// Apply the assignments in the form of assign statements.
        /// </summary>
        /// <param name="implementation">The implementation.</param>
        /// <param name="assignments">The assignments provided by the solver.</param>
        private void ApplyAssignments(Implementation implementation, Dictionary <string, bool> assignments)
        {
            foreach (KeyValuePair <string, bool> assignment in assignments)
            {
                IdentifierExpr expr    = new IdentifierExpr(Token.NoToken, assignment.Key, Type.Bool);
                Expr           literal = new LiteralExpr(Token.NoToken, assignment.Value);

                SimpleAssignLhs assign  = new SimpleAssignLhs(Token.NoToken, expr);
                AssignCmd       command = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                    assign
                },
                                                        new List <Expr> {
                    literal
                });

                implementation.Blocks[0].Cmds.Insert(0, command);
            }
        }
Пример #7
0
 // Return the variable that is being assigned to in the LHS of an assignment.
 //    id := ...  then id
 //    m[...] := ... then m
 private static IdentifierExpr getAssignedVariable(AssignLhs lhs)
 {
     if (lhs is SimpleAssignLhs)
     {
         SimpleAssignLhs sl = (SimpleAssignLhs)lhs;
         return(sl.AssignedVariable);
     }
     else if (lhs is MapAssignLhs)
     {
         MapAssignLhs ml = (MapAssignLhs)lhs;
         return(getAssignedVariable(ml.Map));
     }
     else
     {
         lhs.Emit(new TokenTextWriter(Console.Out));
         throw new InternalError("Unknown type of AssignLhs");
     }
 }
Пример #8
0
 //TODO: review conditions for multiple assignments to the same array, e.g., M[i], M[j] := x, y;
 // This transformation will not work in that case(maybe)?
 public override Block VisitBlock(Block node)
 {
     foreach (Cmd cmd in node.cmds)
     {
         if (cmd is AssignCmd)
         {
             var assign = cmd as AssignCmd;
             List <AssignLhs> newLhs = new List <AssignLhs>();
             List <Expr>      newRhs = new List <Expr>();
             for (int i = 0; i < assign.Lhss.Count; i++)
             {
                 var lhsi = assign.Lhss[i].AsExpr as NAryExpr;
                 if (lhsi != null && lhsi.Fun is MapSelect)
                 {
                     var rhsi = assign.Rhss[i];
                     Debug.Assert(lhsi.Args.Count.Equals(2));
                     var index = lhsi.Args[1];
                     var arr   = lhsi.Args[0];
                     Debug.Assert(arr is IdentifierExpr);
                     var newLhsi = new SimpleAssignLhs(Token.NoToken, arr as IdentifierExpr);
                     var newRhsi = new NAryExpr(Token.NoToken, new MapStore(Token.NoToken, 1), new List <Expr>()
                     {
                         arr, index, rhsi
                     });
                     newLhs.Add(newLhsi);
                     newRhs.Add(newRhsi);
                 }
                 else
                 {
                     newLhs.Add(assign.Lhss[i]);
                     newRhs.Add(assign.Rhss[i]);
                 }
             }
             assign.Rhss = newRhs;
             assign.Lhss = newLhs;
         }
     }
     return(base.VisitBlock(node));
 }
Пример #9
0
 /////////////////////////////////////////////////////////////////////////////////////
 private Expression getAssignmentSourceExpression(SimpleAssignLhs target, Expression source)
 {
     return(source);
 }
Пример #10
0
        private void Analyse(Implementation impl, List <Cmd> cs)
        {
            foreach (var c in cs)
            {
                if (c is AssignCmd)
                {
                    AssignCmd assignCmd = c as AssignCmd;
                    for (int i = 0; i != assignCmd.Lhss.Count; i++)
                    {
                        if (assignCmd.Lhss[i] is SimpleAssignLhs)
                        {
                            SimpleAssignLhs lhs = assignCmd.Lhss[i] as SimpleAssignLhs;
                            Expr            rhs = assignCmd.Rhss[i];

                            VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
                            visitor.VisitExpr(rhs);

                            foreach (Variable v in visitor.GetVariables())
                            {
                                if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
                                {
                                    continue;
                                }
                                foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
                                {
                                    if (mayBeDerivedFrom[impl.Name].ContainsKey(lhs.AssignedVariable.Name) && !mayBeDerivedFrom[impl.Name][lhs.AssignedVariable.Name].Contains(s))
                                    {
                                        SetMayBeDerivedFrom(impl.Name, lhs.AssignedVariable.Name, s);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (c is CallCmd)
                {
                    CallCmd callCmd = c as CallCmd;

                    if (QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "barrier_invariant") ||
                        QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "binary_barrier_invariant"))
                    {
                        foreach (Expr param in callCmd.Ins)
                        {
                            ExprMayAffectControlFlow(impl.Name, param);
                        }
                    }
                    else if (!GPUVerifier.IsBarrier(callCmd.Proc))
                    {
                        Implementation CalleeImplementation = verifier.GetImplementation(callCmd.callee);
                        if (CalleeImplementation != null)
                        {
                            for (int i = 0; i < CalleeImplementation.InParams.Count(); i++)
                            {
                                VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
                                visitor.VisitExpr(callCmd.Ins[i]);

                                foreach (Variable v in visitor.GetVariables())
                                {
                                    if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
                                    {
                                        continue;
                                    }


                                    foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
                                    {
                                        if (!mayBeDerivedFrom[callCmd.callee][CalleeImplementation.InParams[i].Name].Contains(s))
                                        {
                                            SetMayBeDerivedFrom(callCmd.callee, CalleeImplementation.InParams[i].Name, s);
                                        }
                                    }
                                }
                            }

                            for (int i = 0; i < CalleeImplementation.OutParams.Count(); i++)
                            {
                                foreach (string s in mayBeDerivedFrom[callCmd.callee][CalleeImplementation.OutParams[i].Name])
                                {
                                    if (!mayBeDerivedFrom[impl.Name][callCmd.Outs[i].Name].Contains(s))
                                    {
                                        SetMayBeDerivedFrom(impl.Name, callCmd.Outs[i].Name, s);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (c is AssumeCmd)
                {
                    var assumeCmd = c as AssumeCmd;
                    ExprMayAffectControlFlow(impl.Name, assumeCmd.Expr);
                }
                else if (c is AssertCmd)
                {
                    var assertCmd = c as AssertCmd;
                    ExprMayAffectControlFlow(impl.Name, assertCmd.Expr);
                }
            }
        }
Пример #11
0
        public override Cmd VisitCallCmd(CallCmd node)
        {
            var result = base.VisitCallCmd(node);

            var oldProc = programInCachedSnapshot.FindProcedure(node.Proc.Name);

            if (oldProc != null &&
                oldProc.DependencyChecksum != node.Proc.DependencyChecksum &&
                node.AssignedAssumptionVariable == null)
            {
                var  before = new List <Cmd>();
                var  beforePreconditionCheck = new List <Cmd>();
                var  after       = new List <Cmd>();
                var  axioms      = new List <Axiom>();
                Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
                // TODO(wuestholz): Try out two alternatives: only do this for low priority implementations or not at all.
                var canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program);
                if (canUseSpecs && oldProc.SignatureEquals(node.Proc))
                {
                    var desugaring = node.Desugaring;
                    Contract.Assert(desugaring != null);
                    var precond = node.CheckedPrecondition(oldProc, Program, e => FunctionExtractor.Extract(e, Program, axioms));
                    if (precond != null)
                    {
                        var assume = new AssumeCmd(node.tok, precond,
                                                   new QKeyValue(Token.NoToken, "precondition_previous_snapshot", new List <object>(), null));
                        assume.IrrelevantForChecksumComputation = true;
                        beforePreconditionCheck.Add(assume);
                    }

                    var unmods = node.UnmodifiedBefore(oldProc);
                    var eqs    = new List <Expr>();
                    foreach (var unmod in unmods)
                    {
                        var oldUnmod = new LocalVariable(Token.NoToken,
                                                         new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", unmod.Name, FreshTemporaryVariableName),
                                                                        unmod.Type));
                        var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldUnmod));
                        var rhs = new IdentifierExpr(Token.NoToken, unmod.Decl);
                        var cmd = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                            lhs
                        }, new List <Expr> {
                            rhs
                        });
                        cmd.IrrelevantForChecksumComputation = true;
                        before.Add(cmd);
                        var eq = LiteralExpr.Eq(new IdentifierExpr(Token.NoToken, oldUnmod),
                                                new IdentifierExpr(Token.NoToken, unmod.Decl));
                        eq.Type           = Type.Bool;
                        eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY;
                        eqs.Add(eq);
                    }

                    var mods     = node.ModifiedBefore(oldProc);
                    var oldSubst = new Dictionary <Variable, Expr>();
                    foreach (var mod in mods)
                    {
                        var oldMod = new LocalVariable(Token.NoToken,
                                                       new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", mod.Name, FreshTemporaryVariableName),
                                                                      mod.Type));
                        oldSubst[mod.Decl] = new IdentifierExpr(Token.NoToken, oldMod);
                        var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldMod));
                        var rhs = new IdentifierExpr(Token.NoToken, mod.Decl);
                        var cmd = new AssignCmd(Token.NoToken, new List <AssignLhs> {
                            lhs
                        }, new List <Expr> {
                            rhs
                        });
                        cmd.IrrelevantForChecksumComputation = true;
                        before.Add(cmd);
                    }

                    assumedExpr = node.Postcondition(oldProc, eqs, oldSubst, Program,
                                                     e => FunctionExtractor.Extract(e, Program, axioms));
                    if (assumedExpr == null)
                    {
                        assumedExpr = new LiteralExpr(Token.NoToken, true);
                    }
                }

                if (assumedExpr != null)
                {
                    var lv = new LocalVariable(Token.NoToken,
                                               new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
                                               new QKeyValue(Token.NoToken, "assumption", new List <object>(), null));
                    node.AssignedAssumptionVariable = lv;
                    currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
                    var lhs     = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
                    var rhs     = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
                    var assumed = new AssignCmd(node.tok, new List <AssignLhs> {
                        lhs
                    }, new List <Expr> {
                        rhs
                    });
                    assumed.IrrelevantForChecksumComputation = true;
                    after.Add(assumed);
                }

                node.ExtendDesugaring(before, beforePreconditionCheck, after);
                if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
                {
                    using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
                    {
                        var loc = node.tok != null && node.tok != Token.NoToken
              ? string.Format("{0}({1},{2})", node.tok.filename, node.tok.line, node.tok.col)
              : "<unknown location>";
                        Console.Out.WriteLine("Processing call to procedure {0} in implementation {1} (at {2}):", node.Proc.Name,
                                              currentImplementation.Name, loc);
                        foreach (var a in axioms)
                        {
                            Console.Out.Write("  >>> added axiom: ");
                            a.Expr.Emit(tokTxtWr);
                            Console.Out.WriteLine();
                        }

                        foreach (var b in before)
                        {
                            Console.Out.Write("  >>> added before: ");
                            b.Emit(tokTxtWr, 0);
                        }

                        foreach (var b in beforePreconditionCheck)
                        {
                            Console.Out.Write("  >>> added before precondition check: ");
                            b.Emit(tokTxtWr, 0);
                        }

                        foreach (var a in after)
                        {
                            Console.Out.Write("  >>> added after: ");
                            a.Emit(tokTxtWr, 0);
                        }
                    }
                }
            }

            return(result);
        }
Пример #12
0
        public Implementation Inject(Implementation implementation, Program programInCachedSnapshot)
        {
            Contract.Requires(implementation != null && programInCachedSnapshot != null);

            this.programInCachedSnapshot = programInCachedSnapshot;
            assumptionVariableCount      = 0;
            temporaryVariableCount       = 0;
            currentImplementation        = implementation;

            #region Introduce explict assumption about the precondition.

            var oldProc = programInCachedSnapshot.FindProcedure(currentImplementation.Proc.Name);
            if (oldProc != null &&
                oldProc.DependencyChecksum != currentImplementation.Proc.DependencyChecksum &&
                currentImplementation.ExplicitAssumptionAboutCachedPrecondition == null)
            {
                var  axioms      = new List <Axiom>();
                var  after       = new List <Cmd>();
                Expr assumedExpr = new LiteralExpr(Token.NoToken, false);
                var  canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program, true);
                if (canUseSpecs && oldProc.SignatureEquals(currentImplementation.Proc))
                {
                    var always = Substituter.SubstitutionFromHashtable(currentImplementation.GetImplFormalMap(), true,
                                                                       currentImplementation.Proc);
                    var forOld  = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>());
                    var clauses = oldProc.Requires.Select(r =>
                                                          Substituter.FunctionCallReresolvingApply(always, forOld, r.Condition, Program));
                    var conj = Expr.And(clauses, true);
                    assumedExpr = conj != null
            ? FunctionExtractor.Extract(conj, Program, axioms)
            : new LiteralExpr(Token.NoToken, true);
                }

                if (assumedExpr != null)
                {
                    var lv = new LocalVariable(Token.NoToken,
                                               new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool),
                                               new QKeyValue(Token.NoToken, "assumption", new List <object>(), null));
                    currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs);
                    var lhs     = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv));
                    var rhs     = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr);
                    var assumed = new AssignCmd(currentImplementation.tok, new List <AssignLhs> {
                        lhs
                    }, new List <Expr> {
                        rhs
                    });
                    assumed.IrrelevantForChecksumComputation = true;
                    currentImplementation.ExplicitAssumptionAboutCachedPrecondition = assumed;
                    after.Add(assumed);
                }

                if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking)
                {
                    using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false))
                    {
                        var loc = currentImplementation.tok != null && currentImplementation.tok != Token.NoToken
              ? string.Format("{0}({1},{2})", currentImplementation.tok.filename, currentImplementation.tok.line,
                              currentImplementation.tok.col)
              : "<unknown location>";
                        Console.Out.WriteLine("Processing implementation {0} (at {1}):", currentImplementation.Name, loc);
                        foreach (var a in axioms)
                        {
                            Console.Out.Write("  >>> added axiom: ");
                            a.Expr.Emit(tokTxtWr);
                            Console.Out.WriteLine();
                        }

                        foreach (var b in after)
                        {
                            Console.Out.Write("  >>> added after assuming the current precondition: ");
                            b.Emit(tokTxtWr, 0);
                        }
                    }
                }
            }

            #endregion

            var result = VisitImplementation(currentImplementation);
            currentImplementation        = null;
            this.programInCachedSnapshot = null;
            return(result);
        }
Пример #13
0
 public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
 {
     add(node);
     return(base.VisitSimpleAssignLhs(node));
 }
Пример #14
0
 public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
 {
     return(base.VisitSimpleAssignLhs((SimpleAssignLhs)node.Clone()));
 }
Пример #15
0
        private bool Analyse(Implementation impl, List<Cmd> cmdSeq, bool ControlFlowIsUniform)
        {
            foreach (Cmd c in cmdSeq)
            {
                if (c is AssignCmd)
                {
                    AssignCmd assignCmd = c as AssignCmd;
                    foreach (var a in assignCmd.Lhss.Zip(assignCmd.Rhss))
                    {

                        if (a.Item1 is SimpleAssignLhs)
                        {
                            SimpleAssignLhs lhs = a.Item1 as SimpleAssignLhs;
                            Expr rhs = a.Item2;
                            if (IsUniform(impl.Name, lhs.AssignedVariable.Name) &&
                                (!ControlFlowIsUniform || !IsUniform(impl.Name, rhs)))
                            {
                                SetNonUniform(impl.Name, lhs.AssignedVariable.Name);
                            }

                        }
                    }
                }
                else if (c is HavocCmd)
                {
                    HavocCmd havocCmd = c as HavocCmd;
                    foreach(IdentifierExpr ie in havocCmd.Vars)
                    {
                        if(IsUniform(impl.Name, ie.Decl.Name)) {
                            SetNonUniform(impl.Name, ie.Decl.Name);
                        }
                    }
                }
                else if (c is CallCmd)
                {
                    CallCmd callCmd = c as CallCmd;
                    DeclWithFormals Callee = GetProcedure(callCmd.callee);
                    Debug.Assert(Callee != null);

                    if (!ControlFlowIsUniform)
                    {
                        if (IsUniform(callCmd.callee))
                        {
                            SetNonUniform(callCmd.callee);
                        }
                    }
                    for (int i = 0; i < Callee.InParams.Count; i++)
                    {
                        if (IsUniform(callCmd.callee, Callee.InParams[i].Name)
                            && !IsUniform(impl.Name, callCmd.Ins[i]))
                        {
                            SetNonUniform(callCmd.callee, Callee.InParams[i].Name);
                        }
                    }

                    for (int i = 0; i < Callee.OutParams.Count; i++)
                    {
                        if (IsUniform(impl.Name, callCmd.Outs[i].Name)
                        && !IsUniform(callCmd.callee, Callee.OutParams[i].Name))
                        {
                            SetNonUniform(impl.Name, callCmd.Outs[i].Name);
                        }
                    }

                }
                else if (c is AssumeCmd)
                {
                    var ac = (AssumeCmd)c;
                    if (ControlFlowIsUniform && QKeyValue.FindBoolAttribute(ac.Attributes, "partition") &&
                        !IsUniform(impl.Name, ac.Expr))
                    {
                      ControlFlowIsUniform = false;
                    }
                }
            }

            return ControlFlowIsUniform;
        }
Пример #16
0
 public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
 {
     return(node);
 }
Пример #17
0
 ////////////////////////////////////////////////////////////////////////////////////
 internal ReferenceExpression makeReferenceExpression(SimpleAssignLhs assignLhs)
 {
     return(new Programs.Terms.Basic.ProgramVariable(scope.findVariable(assignLhs.AssignedVariable.Decl.Name)));
 }
Пример #18
0
    // perform in place update of liveSet
    public static void Propagate(Cmd cmd, HashSet <Variable /*!*/> /*!*/ liveSet, bool allGlobalsAreLive)
    {
        Contract.Requires(cmd != null);
        Contract.Requires(cce.NonNullElements(liveSet));
        if (cmd is AssignCmd)
        {
            AssignCmd /*!*/ assignCmd = (AssignCmd)cce.NonNull(cmd);
            // I must first iterate over all the targets and remove the live ones.
            // After the removals are done, I must add the variables referred on
            // the right side of the removed targets

            AssignCmd     simpleAssignCmd = assignCmd.AsSimpleAssignCmd;
            HashSet <int> indexSet        = new HashSet <int>();
            int           index           = 0;
            foreach (AssignLhs /*!*/ lhs in simpleAssignCmd.Lhss)
            {
                Contract.Assert(lhs != null);
                SimpleAssignLhs salhs = lhs as SimpleAssignLhs;
                Contract.Assert(salhs != null);
                Variable var = salhs.DeepAssignedVariable;
                if (var != null && (liveSet.Contains(var) || (allGlobalsAreLive && var is GlobalVariable)))
                {
                    indexSet.Add(index);
                    liveSet.Remove(var);
                }
                index++;
            }
            index = 0;
            foreach (Expr /*!*/ expr in simpleAssignCmd.Rhss)
            {
                Contract.Assert(expr != null);
                if (indexSet.Contains(index))
                {
                    VariableCollector /*!*/ collector = new VariableCollector();
                    collector.Visit(expr);
                    if (allGlobalsAreLive)
                    {
                        liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal));
                    }
                    else
                    {
                        liveSet.UnionWith(collector.usedVars);
                    }
                }
                index++;
            }
        }
        else if (cmd is HavocCmd)
        {
            HavocCmd /*!*/ havocCmd = (HavocCmd)cmd;
            foreach (IdentifierExpr /*!*/ expr in havocCmd.Vars)
            {
                Contract.Assert(expr != null);
                if (expr.Decl != null)
                {
                    liveSet.Remove(expr.Decl);
                }
            }
        }
        else if (cmd is PredicateCmd)
        {
            Contract.Assert((cmd is AssertCmd || cmd is AssumeCmd));
            PredicateCmd /*!*/ predicateCmd = (PredicateCmd)cce.NonNull(cmd);
            if (predicateCmd.Expr is LiteralExpr)
            {
                LiteralExpr le = (LiteralExpr)predicateCmd.Expr;
                if (le.IsFalse)
                {
                    liveSet.Clear();
                }
            }
            else
            {
                VariableCollector /*!*/ collector = new VariableCollector();
                collector.Visit(predicateCmd.Expr);
                if (allGlobalsAreLive)
                {
                    liveSet.UnionWith(collector.usedVars.Where(v => v is LocalVariable || v is Formal));
                }
                else
                {
                    liveSet.UnionWith(collector.usedVars);
                }
            }
        }
        else if (cmd is CommentCmd)
        {
            // comments are just for debugging and don't affect verification
        }
        else if (cmd is SugaredCmd)
        {
            SugaredCmd /*!*/ sugCmd = (SugaredCmd)cce.NonNull(cmd);
            Propagate(sugCmd.Desugaring, liveSet, allGlobalsAreLive);
        }
        else if (cmd is StateCmd)
        {
            StateCmd /*!*/   stCmd = (StateCmd)cce.NonNull(cmd);
            List <Cmd> /*!*/ cmds  = cce.NonNull(stCmd.Cmds);
            int len = cmds.Count;
            for (int i = len - 1; i >= 0; i--)
            {
                Propagate(cmds[i], liveSet, allGlobalsAreLive);
            }
            foreach (Variable /*!*/ v in stCmd.Locals)
            {
                Contract.Assert(v != null);
                liveSet.Remove(v);
            }
        }
        else
        {
            {
                Contract.Assert(false);
                throw new cce.UnreachableException();
            }
        }
    }
Пример #19
0
 public override AssignLhs VisitSimpleAssignLhs(SimpleAssignLhs node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <AssignLhs>() != null);
     return(base.VisitSimpleAssignLhs((SimpleAssignLhs)node.Clone()));
 }
Пример #20
0
        private void MakeDual(List <Cmd> cs, Cmd c)
        {
            if (c is CallCmd)
            {
                CallCmd call = c as CallCmd;

                if (QKeyValue.FindBoolAttribute(call.Proc.Attributes, "barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one instantiation
                    Debug.Assert(call.Ins.Count >= (2 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1)));
                    var biDescriptor = new UnaryBarrierInvariantDescriptor(
                        Verifier.UniformityAnalyser.IsUniform(call.callee) ? Expr.True : call.Ins[0],
                        Expr.Neq(call.Ins[Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1], Verifier.IntRep.GetZero(Verifier.IntRep.GetIntType(1))),
                        call.Attributes,
                        this,
                        procName,
                        Verifier);

                    for (var i = 1 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1); i < call.Ins.Count; i++)
                    {
                        biDescriptor.AddInstantiationExpr(call.Ins[i]);
                    }

                    barrierInvariantDescriptors.Add(biDescriptor);
                    return;
                }

                if (QKeyValue.FindBoolAttribute(call.Proc.Attributes, "binary_barrier_invariant"))
                {
                    // There may be a predicate, and there must be an invariant expression and at least one pair of
                    // instantiation expressions
                    Debug.Assert(call.Ins.Count >= (3 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1)));
                    var biDescriptor = new BinaryBarrierInvariantDescriptor(
                        Verifier.UniformityAnalyser.IsUniform(call.callee) ? Expr.True : call.Ins[0],
                        Expr.Neq(call.Ins[Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1], Verifier.IntRep.GetZero(Verifier.IntRep.GetIntType(1))),
                        call.Attributes,
                        this,
                        procName,
                        Verifier);

                    for (var i = 1 + (Verifier.UniformityAnalyser.IsUniform(call.callee) ? 0 : 1); i < call.Ins.Count; i += 2)
                    {
                        biDescriptor.AddInstantiationExprPair(call.Ins[i], call.Ins[i + 1]);
                    }

                    barrierInvariantDescriptors.Add(biDescriptor);
                    return;
                }

                if (GPUVerifier.IsBarrier(call.Proc))
                {
                    // Assert barrier invariants
                    foreach (var biIDescriptor in barrierInvariantDescriptors)
                    {
                        QKeyValue sourceLocationInfo = biIDescriptor.GetSourceLocationInfo();
                        cs.Add(biIDescriptor.GetAssertCmd());
                        var vd = new VariableDualiser(1, Verifier, procName);
                        if (GPUVerifyVCGenCommandLineOptions.BarrierAccessChecks)
                        {
                            foreach (Expr accessExpr in biIDescriptor.GetAccessedExprs())
                            {
                                var assert = new AssertCmd(Token.NoToken, accessExpr, MakeThreadSpecificAttributes(sourceLocationInfo, 1));
                                assert.Attributes = new QKeyValue(
                                    Token.NoToken, "barrier_invariant_access_check", new List <object> {
                                    Expr.True
                                }, assert.Attributes);
                                cs.Add(vd.VisitAssertCmd(assert));
                            }
                        }
                    }
                }

                List <Expr> uniformNewIns    = new List <Expr>();
                List <Expr> nonUniformNewIns = new List <Expr>();

                for (int i = 0; i < call.Ins.Count; i++)
                {
                    if (Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                        Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetInParameter(call.callee, i)))
                    {
                        uniformNewIns.Add(call.Ins[i]);
                    }
                    else if (!Verifier.OnlyThread2.Contains(call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(1, Verifier, procName).VisitExpr(call.Ins[i]));
                    }
                }

                for (int i = 0; i < call.Ins.Count; i++)
                {
                    if (!(Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                          Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetInParameter(call.callee, i))) &&
                        !Verifier.OnlyThread1.Contains(call.callee))
                    {
                        nonUniformNewIns.Add(new VariableDualiser(2, Verifier, procName).VisitExpr(call.Ins[i]));
                    }
                }

                List <Expr> newIns = uniformNewIns;
                newIns.AddRange(nonUniformNewIns);

                List <IdentifierExpr> uniformNewOuts    = new List <IdentifierExpr>();
                List <IdentifierExpr> nonUniformNewOuts = new List <IdentifierExpr>();
                for (int i = 0; i < call.Outs.Count; i++)
                {
                    if (Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                        Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetOutParameter(call.callee, i)))
                    {
                        uniformNewOuts.Add(call.Outs[i]);
                    }
                    else
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(1, Verifier, procName).VisitIdentifierExpr(call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }

                for (int i = 0; i < call.Outs.Count; i++)
                {
                    if (!(Verifier.UniformityAnalyser.knowsOf(call.callee) &&
                          Verifier.UniformityAnalyser.IsUniform(call.callee, Verifier.UniformityAnalyser.GetOutParameter(call.callee, i))))
                    {
                        nonUniformNewOuts.Add(new VariableDualiser(2, Verifier, procName).VisitIdentifierExpr(call.Outs[i].Clone() as IdentifierExpr) as IdentifierExpr);
                    }
                }

                List <IdentifierExpr> newOuts = uniformNewOuts;
                newOuts.AddRange(nonUniformNewOuts);

                CallCmd newCallCmd = new CallCmd(call.tok, call.callee, newIns, newOuts);

                newCallCmd.Proc = call.Proc;

                newCallCmd.Attributes = call.Attributes;

                if (newCallCmd.callee.StartsWith("_LOG_ATOMIC"))
                {
                    QKeyValue curr = newCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        newCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 1) }), curr.Next);
                    }

                    for (curr = newCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 1) }), curr.Next.Next);
                        }
                    }
                }
                else if (newCallCmd.callee.StartsWith("_CHECK_ATOMIC"))
                {
                    QKeyValue curr = newCallCmd.Attributes;
                    if (curr.Key.StartsWith("arg"))
                    {
                        newCallCmd.Attributes = new QKeyValue(Token.NoToken, curr.Key, new List <object>(new object[] { Dualise(curr.Params[0] as Expr, 2) }), curr.Next);
                    }

                    for (curr = newCallCmd.Attributes; curr.Next != null; curr = curr.Next)
                    {
                        if (curr.Next.Key.StartsWith("arg"))
                        {
                            curr.Next = new QKeyValue(Token.NoToken, curr.Next.Key, new List <object>(new object[] { Dualise(curr.Next.Params[0] as Expr, 2) }), curr.Next.Next);
                        }
                    }
                }

                cs.Add(newCallCmd);

                if (GPUVerifier.IsBarrier(call.Proc))
                {
                    foreach (var biDescriptor in barrierInvariantDescriptors)
                    {
                        foreach (var instantiation in biDescriptor.GetInstantiationCmds())
                        {
                            cs.Add(instantiation);
                        }
                    }

                    barrierInvariantDescriptors.Clear();
                }
            }
            else if (c is AssignCmd)
            {
                AssignCmd assign = c as AssignCmd;

                var vd1 = new VariableDualiser(1, Verifier, procName);
                var vd2 = new VariableDualiser(2, Verifier, procName);

                List <AssignLhs> lhss1 = new List <AssignLhs>();
                List <AssignLhs> lhss2 = new List <AssignLhs>();

                List <Expr> rhss1 = new List <Expr>();
                List <Expr> rhss2 = new List <Expr>();

                foreach (var pair in assign.Lhss.Zip(assign.Rhss))
                {
                    if (pair.Item1 is SimpleAssignLhs &&
                        Verifier.UniformityAnalyser.IsUniform(
                            procName, (pair.Item1 as SimpleAssignLhs).AssignedVariable.Name))
                    {
                        lhss1.Add(pair.Item1);
                        rhss1.Add(pair.Item2);
                    }
                    else
                    {
                        lhss1.Add(vd1.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        lhss2.Add(vd2.Visit(pair.Item1.Clone() as AssignLhs) as AssignLhs);
                        rhss1.Add(vd1.VisitExpr(pair.Item2.Clone() as Expr));
                        rhss2.Add(vd2.VisitExpr(pair.Item2.Clone() as Expr));
                    }
                }

                Debug.Assert(lhss1.Count > 0);
                cs.Add(new AssignCmd(Token.NoToken, lhss1, rhss1));

                if (lhss2.Count > 0)
                {
                    cs.Add(new AssignCmd(Token.NoToken, lhss2, rhss2));
                }
            }
            else if (c is HavocCmd)
            {
                HavocCmd havoc = c as HavocCmd;
                Debug.Assert(havoc.Vars.Count() == 1);

                HavocCmd newHavoc;

                var idents = new List <IdentifierExpr>
                {
                    (IdentifierExpr) new VariableDualiser(1, Verifier, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr),
                    (IdentifierExpr) new VariableDualiser(2, Verifier, procName).VisitIdentifierExpr(havoc.Vars[0].Clone() as IdentifierExpr)
                };
                newHavoc = new HavocCmd(havoc.tok, idents);

                cs.Add(newHavoc);
            }
            else if (c is AssertCmd)
            {
                AssertCmd a = c as AssertCmd;

                if (QKeyValue.FindBoolAttribute(a.Attributes, "sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "block_sourceloc") ||
                    QKeyValue.FindBoolAttribute(a.Attributes, "array_bounds"))
                {
                    // This is just a location marker, so we do not dualise it
                    cs.Add(new AssertCmd(
                               Token.NoToken,
                               new VariableDualiser(1, Verifier, procName).VisitExpr(a.Expr.Clone() as Expr),
                               (QKeyValue)a.Attributes.Clone()));
                }
                else
                {
                    var isUniform = Verifier.UniformityAnalyser.IsUniform(procName, a.Expr);
                    cs.Add(MakeThreadSpecificAssert(a, 1));
                    if (!GPUVerifyVCGenCommandLineOptions.AsymmetricAsserts && !ContainsAsymmetricExpression(a.Expr) && !isUniform)
                    {
                        cs.Add(MakeThreadSpecificAssert(a, 2));
                    }
                }
            }
            else if (c is AssumeCmd)
            {
                AssumeCmd ass = c as AssumeCmd;

                if (QKeyValue.FindStringAttribute(ass.Attributes, "captureState") != null)
                {
                    cs.Add(c);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "backedge"))
                {
                    AssumeCmd newAss = new AssumeCmd(
                        c.tok,
                        Expr.Or(
                            new VariableDualiser(1, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr),
                            new VariableDualiser(2, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr)));
                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
                else if (QKeyValue.FindBoolAttribute(ass.Attributes, "atomic_refinement"))
                {
                    // Generate the following:
                    // havoc v$1, v$2;
                    // assume !_USED[offset$1][v$1];
                    // _USED[offset$1][v$1] := true;
                    // assume !_USED[offset$2][v$2];
                    // _USED[offset$2][v$2] := true;
                    Expr variable = QKeyValue.FindExprAttribute(ass.Attributes, "variable");
                    Expr offset   = QKeyValue.FindExprAttribute(ass.Attributes, "offset");

                    List <Expr> offsets =
                        Enumerable.Range(1, 2).Select(x => new VariableDualiser(x, Verifier, procName).VisitExpr(offset.Clone() as Expr)).ToList();
                    List <Expr> vars =
                        Enumerable.Range(1, 2).Select(x => new VariableDualiser(x, Verifier, procName).VisitExpr(variable.Clone() as Expr)).ToList();
                    IdentifierExpr arrayRef =
                        new IdentifierExpr(Token.NoToken, Verifier.FindOrCreateUsedMap(QKeyValue.FindStringAttribute(ass.Attributes, "arrayref"), vars[0].Type));
                    bool isShared = QKeyValue.FindBoolAttribute(arrayRef.Decl.Attributes, "atomic_group_shared");

                    foreach (int i in Enumerable.Range(0, 2))
                    {
                        Expr assumeSelect = arrayRef;

                        if (isShared && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            assumeSelect = new NAryExpr(
                                Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                                assumeSelect, Verifier.GroupSharedIndexingExpr(i + 1)
                            });
                        }

                        assumeSelect = new NAryExpr(
                            Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                            assumeSelect, offsets[i]
                        });
                        assumeSelect = new NAryExpr(
                            Token.NoToken, new MapSelect(Token.NoToken, 1), new List <Expr> {
                            assumeSelect, vars[i]
                        });
                        AssumeCmd newAssume = new AssumeCmd(c.tok, Expr.Not(assumeSelect));
                        cs.Add(newAssume);

                        AssignLhs lhs = new SimpleAssignLhs(Token.NoToken, arrayRef);

                        if (isShared && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
                        {
                            lhs = new MapAssignLhs(
                                Token.NoToken, lhs, new List <Expr> {
                                Verifier.GroupSharedIndexingExpr(i + 1)
                            });
                        }

                        lhs = new MapAssignLhs(
                            Token.NoToken, lhs, new List <Expr> {
                            offsets[i]
                        });
                        lhs = new MapAssignLhs(
                            Token.NoToken, lhs, new List <Expr> {
                            vars[i]
                        });
                        AssignCmd assign = new AssignCmd(
                            c.tok, new List <AssignLhs> {
                            lhs
                        }, new List <Expr> {
                            Expr.True
                        });
                        cs.Add(assign);
                    }
                }
                else
                {
                    var       isUniform = Verifier.UniformityAnalyser.IsUniform(procName, ass.Expr);
                    AssumeCmd newAss    = new AssumeCmd(c.tok, new VariableDualiser(1, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    if (!ContainsAsymmetricExpression(ass.Expr) && !isUniform)
                    {
                        newAss.Expr = Expr.And(newAss.Expr, new VariableDualiser(2, Verifier, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    }

                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
            }
            else
            {
                Debug.Assert(false);
            }
        }