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()); }
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) }); } }
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); }
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; } } } }
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); }