Beispiel #1
0
 public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     //Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <AssignLhs>() != null);
     CheckTypeParams(node, cce.NonNull(node.TypeParameters));
     return(base.VisitMapAssignLhs(node));
 }
Beispiel #2
0
 private void CheckMapIndex(MapAssignLhs node)
 {
     if (node.Indexes.Count > 1)
     {
         MultiDimensionalMapError();
     }
 }
Beispiel #3
0
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            MapAssignLhs clone = (MapAssignLhs)node.Clone();

            clone.Indexes = new List <Expr>(node.Indexes);

            return(base.VisitMapAssignLhs(clone));
        }
Beispiel #4
0
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            //Contract.Requires(node != null);
            Contract.Ensures(Contract.Result <AssignLhs>() != null);
            MapAssignLhs clone = (MapAssignLhs)node.Clone();

            clone.Indexes = new List <Expr /*!*/>(clone.Indexes);
            return(base.VisitMapAssignLhs(clone));
        }
Beispiel #5
0
        // map indices also qualify as variables read
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            node.Map = (AssignLhs)this.Visit(node.Map);
            for (int i = 0; i < node.Indexes.Count; ++i)
            {
                varsRead.Visit(node.Indexes[i]);
            }

            return(node);
        }
Beispiel #6
0
 public virtual AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     Contract.Requires(node != null);
     Contract.Ensures(Contract.Result <AssignLhs>() != null);
     node.Map = cce.NonNull((AssignLhs)this.Visit(node.Map));
     for (int i = 0; i < node.Indexes.Count; ++i)
     {
         node.Indexes[i] = cce.NonNull((Expr)this.Visit(node.Indexes[i]));
     }
     return(node);
 }
Beispiel #7
0
 private bool indicesAreTracked(MapAssignLhs lhs)
 {
     // Go through all indices of the map
     foreach (var e in lhs.Indexes)
     {
         if (!isTracked(e))
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #8
0
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            var v = node.DeepAssignedVariable;

            if (QKeyValue.FindBoolAttribute(v.Attributes, "group_shared") && !GPUVerifyVCGenCommandLineOptions.OnlyIntraGroupRaceChecking)
            {
                return(new MapAssignLhs(Token.NoToken, new MapAssignLhs(Token.NoToken, node.Map,
                                                                        new List <Expr>(new Expr[] { GPUVerifier.GroupSharedIndexingExpr(id) })),
                                        node.Indexes.Select(idx => this.VisitExpr(idx)).ToList()));
            }
            return(base.VisitMapAssignLhs(node));
        }
Beispiel #9
0
        ////////////////////////////////////////////////////////////////////////////////////
        internal ReferenceExpression makeReferenceExpression(MapAssignLhs assignLhs)
        {
            ReferenceExpression map = makeReferenceExpression(assignLhs.Map);

            ExpressionList indices = new ExpressionList();

//            indices.append(map);
            foreach (Microsoft.Boogie.Expr e in assignLhs.Indexes)
            {
                indices.append(makeExpression(e));
            }

            return(new Programs.Terms.Basic.MapLookup(map, indices));
        }
Beispiel #10
0
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            Debug.Assert(NoWrittenVariable());

            if (!State.ContainsConstantArray(node.DeepAssignedVariable))
            {
                return(node);
            }

            Variable WrittenVariable = node.DeepAssignedVariable;

            CheckMapIndex(node);
            Debug.Assert(!(node.Map is MapAssignLhs));

            access = new AccessRecord(WrittenVariable, node.Indexes[0]);

            return(node);
        }
Beispiel #11
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");
     }
 }
Beispiel #12
0
        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            Debug.Assert(NoWrittenVariable());

            if (!State.ContainsGlobalOrGroupSharedArray(node.DeepAssignedVariable, true) &&
                !State.ContainsPrivateArray(node.DeepAssignedVariable))
            {
                return(node);
            }

            Variable WrittenVariable = node.DeepAssignedVariable;

            CheckMapIndex(node);
            Debug.Assert(!(node.Map is MapAssignLhs));

            access = new AccessRecord(WrittenVariable, node.Indexes[0]);

            isPrivate = (State.ContainsPrivateArray(WrittenVariable));

            return(node);
        }
Beispiel #13
0
        //m[m][b] := c;
        //m:A b:B c:C
        // type(m) = [A] ([B]C)
        // ==>               m [m :=                       m[m] [b:=c]]
        // ==> MU<[A]([B]C)>(m, m ,MU<[B]C>( ML<[A]([B]C)>(m,m), b, c )

        //m[m] := b
        // ==> m := m[m:=b]
        // ==> m := MU<[A]B>(m,m,b)

        /////////////////////////////////////////////////////////////////////////////////////
        private Expression getAssignmentSourceExpression(MapAssignLhs target, Expression source)
        {
            var arguments = new List <Expression>();

            arguments.Add(procedure.expressionFactory.makeExpression(target.Map.AsExpr));

            foreach (var e in target.Indexes)
            {
                arguments.Add(procedure.expressionFactory.makeExpression(e));
            }

            arguments.Add(source);

            var mt = arguments[0].type as MapType;

            Debug.Assert(mt != null);

            var argumentTypes = new IType[arguments.Count];

            for (int i = 0; i < arguments.Count; i++)
            {
                argumentTypes[i] = arguments[i].type;
            }

            IType resultType = arguments[0].type;

            var typeArguments = new IType[target.TypeParameters.FormalTypeParams.Count];

            for (int i = 0; i < typeArguments.Length; i++)
            {
                typeArguments[i] = makeType(target.TypeParameters[target.TypeParameters.FormalTypeParams[i]]);
            }

            Expression recSource = new BasicFAE(
                BasicMapWrite.makeMapWrite(typeArguments, argumentTypes, resultType), new ExpressionList(arguments)
                );

            return(getAssignmentSourceExpression(target.Map, recSource));
        }
Beispiel #14
0
        /////////////////
        // here begin the visit overrides that are only necessary for the cloning, and have nothing to do with the substitution itself
        // --> one might move them to a clone visitor..
        /////////////////

        public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
        {
            var dispatchedIndices = new List <Expr>();

            foreach (var ind in node.Indexes)
            {
                dispatchedIndices.Add(VisitExpr(ind));
            }

            AssignLhs newAssignLhs = null;

            if (node.Map is MapAssignLhs)
            {
                newAssignLhs = VisitMapAssignLhs(node.Map as MapAssignLhs);
            }
            else if (node.Map is SimpleAssignLhs)
            {
                newAssignLhs = VisitSimpleAssignLhs(node.Map as SimpleAssignLhs);
            }


            return(new MapAssignLhs(node.tok, newAssignLhs, dispatchedIndices));
        }
Beispiel #15
0
 public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     Debug.Assert(node.Indexes.Count() == 1, "Expecting 1D maps only");
     this.Visit(node.AsExpr); //makes it as MapSelect(M,e)
     return(node);
 }
Beispiel #16
0
 public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     add(node);
     return(base.VisitMapAssignLhs(node));
 }
Beispiel #17
0
 public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     return(base.VisitMapAssignLhs((MapAssignLhs)node.Clone()));
 }
Beispiel #18
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.Zero(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.Zero(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 BIDescriptor in BarrierInvariantDescriptors)
                    {
                        QKeyValue SourceLocationInfo = BIDescriptor.GetSourceLocationInfo();
                        cs.Add(BIDescriptor.GetAssertCmd());
                        var vd = new VariableDualiser(1, verifier.uniformityAnalyser, procName);
                        if (GPUVerifyVCGenCommandLineOptions.BarrierAccessChecks)
                        {
                            foreach (Expr AccessExpr in BIDescriptor.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.uniformityAnalyser, 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.uniformityAnalyser, 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.uniformityAnalyser, 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.uniformityAnalyser, 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.uniformityAnalyser, procName);
                var vd2 = new VariableDualiser(2, verifier.uniformityAnalyser, 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;

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

                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.uniformityAnalyser, 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.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr),
                                                                    new VariableDualiser(2, verifier.uniformityAnalyser, 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  = (new int[] { 1, 2 }).Select(x => new VariableDualiser(x, verifier.uniformityAnalyser, procName).VisitExpr(offset.Clone() as Expr)).ToList();
                    List <Expr>    vars     = (new int[] { 1, 2 }).Select(x => new VariableDualiser(x, verifier.uniformityAnalyser, procName).VisitExpr(variable.Clone() as Expr)).ToList();
                    IdentifierExpr arrayref = new IdentifierExpr(Token.NoToken, verifier.FindOrCreateUsedMap(QKeyValue.FindStringAttribute(ass.Attributes, "arrayref"), vars[0].Type));

                    foreach (int i in (new int[] { 0, 1 }))
                    {
                        AssumeCmd newAss = new AssumeCmd(c.tok, Expr.Not(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                                                                      new List <Expr> {
                            new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1),
                                         new List <Expr> {
                                arrayref, offsets[i]
                            }),
                            vars[i]
                        })));

                        cs.Add(newAss);

                        var lhs = new MapAssignLhs(Token.NoToken, new MapAssignLhs(Token.NoToken, new SimpleAssignLhs(Token.NoToken, arrayref),
                                                                                   new List <Expr> {
                            offsets[i]
                        }), 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.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    if (!ContainsAsymmetricExpression(ass.Expr) && !isUniform)
                    {
                        newAss.Expr = Expr.And(newAss.Expr, new VariableDualiser(2, verifier.uniformityAnalyser, procName).VisitExpr(ass.Expr.Clone() as Expr));
                    }
                    newAss.Attributes = ass.Attributes;
                    cs.Add(newAss);
                }
            }
            else
            {
                Debug.Assert(false);
            }
        }
Beispiel #19
0
 public override AssignLhs VisitMapAssignLhs(MapAssignLhs node)
 {
     problematicNode = node;
     return(node);
 }