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)); }
private void CheckMapIndex(MapAssignLhs node) { if (node.Indexes.Count > 1) { MultiDimensionalMapError(); } }
public override AssignLhs VisitMapAssignLhs(MapAssignLhs node) { MapAssignLhs clone = (MapAssignLhs)node.Clone(); clone.Indexes = new List <Expr>(node.Indexes); return(base.VisitMapAssignLhs(clone)); }
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)); }
// 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); }
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); }
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); }
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)); }
//////////////////////////////////////////////////////////////////////////////////// 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)); }
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); }
// 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"); } }
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); }
//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)); }
///////////////// // 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)); }
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); }
public override AssignLhs VisitMapAssignLhs(MapAssignLhs node) { add(node); return(base.VisitMapAssignLhs(node)); }
public override AssignLhs VisitMapAssignLhs(MapAssignLhs node) { return(base.VisitMapAssignLhs((MapAssignLhs)node.Clone())); }
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); } }
public override AssignLhs VisitMapAssignLhs(MapAssignLhs node) { problematicNode = node; return(node); }