Exemple #1
0
        private static Variable ExtractOffsetVar(CallCounterexample err)
        {
            var VFV = new VariableFinderVisitor(
                RaceInstrumentationUtil.MakeOffsetVariableName(QKeyValue.FindStringAttribute(err.FailingRequires.Attributes, "array"), GetAccessType(err)));

            VFV.Visit(err.FailingRequires.Condition);
            return(VFV.GetVariable());
        }
Exemple #2
0
        private IEnumerable <SourceLocationInfo> GetPossibleSourceLocationsForFirstAccessInRace(CallCounterexample CallCex, string ArrayName, AccessType AccessType, string RaceyState)
        {
            string AccessHasOccurred = RaceInstrumentationUtil.MakeHasOccurredVariableName(ArrayName, AccessType);
            string AccessOffset      = RaceInstrumentationUtil.MakeOffsetVariableName(ArrayName, AccessType);

            AssumeCmd ConflictingAction = DetermineConflictingAction(CallCex, RaceyState, AccessHasOccurred, AccessOffset);

            var ConflictingState = QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "captureState");

            if (ConflictingState.Contains("loop_head_state"))
            {
                // The state may have been renamed (for example, if k-induction has been employed),
                // so we need to find the original state name.  This can be computed as the substring before the first
                // occurrence of '$'.  This inversion is fragile, and would be a good candidate for making robust
                string ConflictingStatePrefix;
                if (ConflictingState.Contains('$'))
                {
                    ConflictingStatePrefix = ConflictingState.Substring(0, ConflictingState.IndexOf('$'));
                }
                else
                {
                    ConflictingStatePrefix = ConflictingState;
                }
                Program originalProgram = GetOriginalProgram();
                var     blockGraph      = originalProgram.ProcessLoops(GetOriginalImplementation(originalProgram));
                Block   header          = FindLoopHeaderWithStateName(ConflictingStatePrefix, blockGraph);
                Debug.Assert(header != null);
                HashSet <Block> LoopNodes = new HashSet <Block>(
                    blockGraph.BackEdgeNodes(header).Select(Item => blockGraph.NaturalLoops(header, Item)).SelectMany(Item => Item)
                    );
                return(GetSourceLocationsFromBlocks("_CHECK_" + AccessType + "_" + ArrayName, LoopNodes));
            }
            else if (ConflictingState.Contains("call_return_state"))
            {
                return(GetSourceLocationsFromCall("_CHECK_" + AccessType + "_" + ArrayName,
                                                  QKeyValue.FindStringAttribute(ConflictingAction.Attributes, "procedureName")));
            }
            else
            {
                Debug.Assert(ConflictingState.Contains("check_state"));
                return(new HashSet <SourceLocationInfo> {
                    new SourceLocationInfo(ConflictingAction.Attributes, GetSourceFileName(), ConflictingAction.tok)
                });
            }
        }
Exemple #3
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.SizeTType);
            Variable accessValueVariable =
                RaceInstrumentationUtil.MakeValueVariable(v.Name, access, mt.Result);
            Variable accessBenignFlagVariable =
                GPUVerifier.MakeBenignFlagVariable(v.Name);
            Variable accessAsyncHandleVariable =
                RaceInstrumentationUtil.MakeAsyncHandleVariable(v.Name, access, Verifier.SizeTType);

            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.SizeTType));

            Debug.Assert(!(mt.Result is MapType));

            List <Variable> locals        = new List <Variable>();
            Variable        trackVariable =
                new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "track", 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(Verifier.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);
        }
Exemple #4
0
 private void ShowRaceInstrumentationVariables(Model Model, string CapturedState, Program OriginalProgram)
 {
     foreach (var v in OriginalProgram.TopLevelDeclarations.OfType <Variable>().Where(Item =>
                                                                                      QKeyValue.FindBoolAttribute(Item.Attributes, "race_checking")))
     {
         foreach (var t in AccessType.Types)
         {
             if (v.Name.StartsWith("_" + t + "_HAS_OCCURRED_"))
             {
                 string     ArrayName;
                 AccessType Access;
                 GetArrayNameAndAccessTypeFromAccessHasOccurredVariable(v, out ArrayName, out Access);
                 var AccessOffsetVar = OriginalProgram.TopLevelDeclarations.OfType <Variable>().Where(Item =>
                                                                                                      Item.Name == RaceInstrumentationUtil.MakeOffsetVariableName(ArrayName, Access)).ToList()[0];
                 if (ExtractVariableValueFromCapturedState(v.Name, CapturedState, Model) == "true")
                 {
                     if (GetStateFromModel(CapturedState, Model).TryGet(AccessOffsetVar.Name) is Model.Number)
                     {
                         Console.Error.WriteLine("  " + Access.ToString().ToLower() + " " + Access.Direction() + " "
                                                 + ArrayOffsetString(Model, CapturedState, v, AccessOffsetVar, ArrayName)
                                                 + " (" + ThreadDetails(Model, 1, false) + ")");
                     }
                     else
                     {
                         Console.Error.WriteLine("  " + Access.ToString().ToLower() + " " + Access.Direction() + " " + ArrayName.TrimStart(new char[] { '$' })
                                                 + " (unknown offset)" + " (" + ThreadDetails(Model, 1, false) + ")");
                     }
                 }
                 break;
             }
         }
     }
 }
Exemple #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);
        }