internal override AssertCmd GetAssertCmd() { AssertCmd result = base.GetAssertCmd(); result.Expr = Expr.Imp(GPUVerifier.ThreadsInSameGroup(), result.Expr); return(result); }
private void AddBarrierDivergenceCandidates(HashSet <Variable> localVars, Implementation impl, IRegion region) { if (!verifier.ContainsBarrierCall(region) && !GPUVerifyVCGenCommandLineOptions.WarpSync) { return; } Expr guard = region.Guard(); if (guard != null && verifier.UniformityAnalyser.IsUniform(impl.Name, guard)) { return; } if (IsDisjunctionOfPredicates(guard)) { string loopPredicate = ((guard as NAryExpr).Args[0] as IdentifierExpr).Name; loopPredicate = loopPredicate.Substring(0, loopPredicate.IndexOf('$')); // Int type used here, but it doesn't matter as we will print and then re-parse the program var uniformEnabledPredicate = Expr.Eq( new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$1", Type.Int))), new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$2", Type.Int)))); verifier.AddCandidateInvariant(region, uniformEnabledPredicate, "loopPredicateEquality"); verifier.AddCandidateInvariant(region, Expr.Imp(verifier.ThreadsInSameGroup(), uniformEnabledPredicate), "loopPredicateEquality"); Dictionary <string, int> assignmentCounts = GetAssignmentCounts(impl); HashSet <string> alreadyConsidered = new HashSet <string>(); foreach (var v in localVars) { string lv = Utilities.StripThreadIdentifier(v.Name); if (alreadyConsidered.Contains(lv)) { continue; } alreadyConsidered.Add(lv); if (verifier.UniformityAnalyser.IsUniform(impl.Name, v.Name)) { continue; } if (GPUVerifier.IsPredicate(lv)) { continue; } if (!assignmentCounts.ContainsKey(lv) || assignmentCounts[lv] <= 1) { continue; } if (!verifier.ContainsNamedVariable(region.GetModifiedVariables(), lv)) { continue; } AddPredicatedEqualityCandidateInvariant(region, loopPredicate, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, lv, Type.Int))); } } }
private static void GenerateCandidateForNonUniformGuardVariables(GPUVerifier verifier, Implementation impl, IRegion region) { if (!verifier.ContainsBarrierCall(region) && !GPUVerifyVCGenCommandLineOptions.WarpSync) { return; } HashSet <Variable> partitionVars = region.PartitionVariablesOfHeader(); HashSet <Variable> guardVars = new HashSet <Variable>(); var formals = impl.InParams.Select(x => x.Name); var modset = region.GetModifiedVariables().Select(x => x.Name); foreach (var v in partitionVars) { Expr expr = verifier.VarDefAnalysesRegion[impl].DefOfVariableName(v.Name); if (expr == null) { continue; } var visitor = new VariablesOccurringInExpressionVisitor(); visitor.Visit(expr); guardVars.UnionWith( visitor.GetVariables().Where(x => x.Name.StartsWith("$") && !formals.Contains(x.Name) && modset.Contains(x.Name) && !verifier.UniformityAnalyser.IsUniform(impl.Name, x.Name) && x.TypedIdent.Type.IsBv && (x.TypedIdent.Type.BvBits % 8 == 0))); } List <AssignCmd> assignments = new List <AssignCmd>(); foreach (Block b in region.PreHeaders()) { foreach (AssignCmd c in b.Cmds.Where(x => x is AssignCmd)) { assignments.Add(c); } } foreach (var v in guardVars) { foreach (AssignCmd c in assignments) { foreach (var a in c.Lhss.Zip(c.Rhss)) { var lhs = a.Item1; var rhs = a.Item2; if (!(lhs is SimpleAssignLhs)) { continue; } var sLhs = (SimpleAssignLhs)lhs; var theVar = sLhs.DeepAssignedVariable; if (theVar.Name == v.Name) { var sub = verifier.IntRep.MakeSub(new IdentifierExpr(Token.NoToken, v), rhs as Expr); List <Expr> args = new List <Expr>(); args.Add(sub); Function otherbv = verifier.FindOrCreateOther(sub.Type); var inv = Expr.Eq(sub, new NAryExpr(Token.NoToken, new FunctionCall(otherbv), args)); verifier.AddCandidateInvariant(region, inv, "guardMinusInitialIsUniform"); var groupInv = Expr.Imp(verifier.ThreadsInSameGroup(), inv); verifier.AddCandidateInvariant(region, groupInv, "guardMinusInitialIsUniform"); } } } } }
protected override void AddLogAccessProcedure(Variable v, AccessType Access) { // This array should be included in the set of global or group shared arrays that // are *not* disabled Debug.Assert(verifier.KernelArrayInfo.GetGlobalAndGroupSharedArrays(false).Contains(v)); Procedure LogAccessProcedure = MakeLogAccessProcedureHeader(v, Access); Debug.Assert(v.TypedIdent.Type is MapType); MapType mt = v.TypedIdent.Type as MapType; Debug.Assert(mt.Arguments.Count == 1); Variable AccessHasOccurredVariable = GPUVerifier.MakeAccessHasOccurredVariable(v.Name, Access); Variable AccessOffsetVariable = RaceInstrumentationUtil.MakeOffsetVariable(v.Name, Access, verifier.IntRep.GetIntType(verifier.size_t_bits)); Variable AccessValueVariable = RaceInstrumentationUtil.MakeValueVariable(v.Name, Access, mt.Result); Variable AccessBenignFlagVariable = GPUVerifier.MakeBenignFlagVariable(v.Name); Variable AccessAsyncHandleVariable = RaceInstrumentationUtil.MakeAsyncHandleVariable(v.Name, Access, verifier.IntRep.GetIntType(verifier.size_t_bits)); Variable PredicateParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_P", Microsoft.Boogie.Type.Bool)); Variable OffsetParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_offset", mt.Arguments[0])); Variable ValueParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_value", mt.Result)); Variable ValueOldParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_value_old", mt.Result)); Variable AsyncHandleParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_async_handle", verifier.IntRep.GetIntType(verifier.size_t_bits))); Debug.Assert(!(mt.Result is MapType)); List <Variable> locals = new List <Variable>(); Variable TrackVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "track", Microsoft.Boogie.Type.Bool)); locals.Add(TrackVariable); List <BigBlock> bigblocks = new List <BigBlock>(); List <Cmd> simpleCmds = new List <Cmd>(); // Havoc tracking variable simpleCmds.Add(new HavocCmd(v.tok, new List <IdentifierExpr>(new IdentifierExpr[] { new IdentifierExpr(v.tok, TrackVariable) }))); Expr Condition = Expr.And(new IdentifierExpr(v.tok, PredicateParameter), new IdentifierExpr(v.tok, TrackVariable)); if (verifier.KernelArrayInfo.GetGroupSharedArrays(false).Contains(v)) { Condition = Expr.And(GPUVerifier.ThreadsInSameGroup(), Condition); } simpleCmds.Add(MakeConditionalAssignment(AccessHasOccurredVariable, Condition, Expr.True)); simpleCmds.Add(MakeConditionalAssignment(AccessOffsetVariable, Condition, new IdentifierExpr(v.tok, OffsetParameter))); if (!GPUVerifyVCGenCommandLineOptions.NoBenign && Access.isReadOrWrite()) { simpleCmds.Add(MakeConditionalAssignment(AccessValueVariable, Condition, new IdentifierExpr(v.tok, ValueParameter))); } if (!GPUVerifyVCGenCommandLineOptions.NoBenign && Access == AccessType.WRITE) { simpleCmds.Add(MakeConditionalAssignment(AccessBenignFlagVariable, Condition, Expr.Neq(new IdentifierExpr(v.tok, ValueParameter), new IdentifierExpr(v.tok, ValueOldParameter)))); } if ((Access == AccessType.READ || Access == AccessType.WRITE) && verifier.ArraysAccessedByAsyncWorkGroupCopy[Access].Contains(v.Name)) { simpleCmds.Add(MakeConditionalAssignment(AccessAsyncHandleVariable, Condition, Expr.Ident(AsyncHandleParameter))); } bigblocks.Add(new BigBlock(v.tok, "_LOG_" + Access + "", simpleCmds, null, null)); Implementation LogAccessImplementation = new Implementation(v.tok, "_LOG_" + Access + "_" + v.Name, new List <TypeVariable>(), LogAccessProcedure.InParams, new List <Variable>(), locals, new StmtList(bigblocks, v.tok)); GPUVerifier.AddInlineAttribute(LogAccessImplementation); LogAccessImplementation.Proc = LogAccessProcedure; verifier.Program.AddTopLevelDeclaration(LogAccessProcedure); verifier.Program.AddTopLevelDeclaration(LogAccessImplementation); }
protected override void AddLogAccessProcedure(Variable v, AccessType Access) { // This array should be included in the set of global or group shared arrays that // are *not* disabled Debug.Assert(verifier.KernelArrayInfo.ContainsGlobalOrGroupSharedArray(v, false)); Procedure LogAccessProcedure = MakeLogAccessProcedureHeader(v, Access); Debug.Assert(v.TypedIdent.Type is MapType); MapType mt = v.TypedIdent.Type as MapType; Debug.Assert(mt.Arguments.Count == 1); Variable AccessHasOccurredVariable = GPUVerifier.MakeAccessHasOccurredVariable(v.Name, Access); Variable AccessOffsetVariable = RaceInstrumentationUtil.MakeOffsetVariable(v.Name, Access, verifier.IntRep.GetIntType(verifier.size_t_bits)); Variable AccessValueVariable = RaceInstrumentationUtil.MakeValueVariable(v.Name, Access, mt.Result); Variable AccessBenignFlagVariable = GPUVerifier.MakeBenignFlagVariable(v.Name); Variable AccessAsyncHandleVariable = RaceInstrumentationUtil.MakeAsyncHandleVariable(v.Name, Access, verifier.IntRep.GetIntType(verifier.size_t_bits)); Variable PredicateParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_P", Type.Bool)); Variable OffsetParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_offset", mt.Arguments[0])); Variable ValueParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_value", mt.Result)); Variable ValueOldParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_value_old", mt.Result)); Variable AsyncHandleParameter = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_async_handle", verifier.IntRep.GetIntType(verifier.size_t_bits))); Debug.Assert(!(mt.Result is MapType)); Block LoggingCommands = new Block(Token.NoToken, "log_access_entry", new List <Cmd>(), new ReturnCmd(Token.NoToken)); Expr Condition = Expr.And(new IdentifierExpr(Token.NoToken, MakeTrackingVariable()), Expr.Eq(new IdentifierExpr(Token.NoToken, AccessOffsetVariable), new IdentifierExpr(Token.NoToken, OffsetParameter))); if (verifier.KernelArrayInfo.GetGroupSharedArrays(false).Contains(v)) { Condition = Expr.And(GPUVerifier.ThreadsInSameGroup(), Condition); } if (!GPUVerifyVCGenCommandLineOptions.NoBenign && Access.isReadOrWrite()) { Condition = Expr.And(Condition, Expr.Eq(new IdentifierExpr(Token.NoToken, AccessValueVariable), new IdentifierExpr(Token.NoToken, ValueParameter))); } Condition = Expr.And(new IdentifierExpr(Token.NoToken, PredicateParameter), Condition); LoggingCommands.Cmds.Add(MakeConditionalAssignment(AccessHasOccurredVariable, Condition, Expr.True)); if (!GPUVerifyVCGenCommandLineOptions.NoBenign && Access == AccessType.WRITE) { LoggingCommands.Cmds.Add(MakeConditionalAssignment(AccessBenignFlagVariable, Condition, Expr.Neq(new IdentifierExpr(Token.NoToken, ValueParameter), new IdentifierExpr(Token.NoToken, ValueOldParameter)))); } if ((Access == AccessType.READ || Access == AccessType.WRITE) && verifier.ArraysAccessedByAsyncWorkGroupCopy[Access].Contains(v.Name)) { LoggingCommands.Cmds.Add(MakeConditionalAssignment(AccessAsyncHandleVariable, Condition, Expr.Ident(AsyncHandleParameter))); } Implementation LogAccessImplementation = new Implementation(Token.NoToken, "_LOG_" + Access + "_" + v.Name, new List <TypeVariable>(), LogAccessProcedure.InParams, new List <Variable>(), new List <Variable>(), new List <Block> { LoggingCommands }); GPUVerifier.AddInlineAttribute(LogAccessImplementation); LogAccessImplementation.Proc = LogAccessProcedure; verifier.Program.AddTopLevelDeclaration(LogAccessProcedure); verifier.Program.AddTopLevelDeclaration(LogAccessImplementation); }