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");
                        }
                    }
                }
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }