private void AddPredicatedEqualityCandidateInvariant(IRegion region, string loopPredicate, Variable v) { var inv = Expr.Imp( Expr.And( new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$1", Microsoft.Boogie.Type.Int))), new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$2", Microsoft.Boogie.Type.Int)))), Expr.Eq( new IdentifierExpr(Token.NoToken, new VariableDualiser(1, verifier, impl.Name).VisitVariable(v.Clone() as Variable)), new IdentifierExpr(Token.NoToken, new VariableDualiser(2, verifier, impl.Name).VisitVariable(v.Clone() as Variable)))); verifier.AddCandidateInvariant(region, inv, "predicatedEquality"); }
private static void GenerateCandidateForLoopBounds(GPUVerifier verifier, Implementation impl, IRegion region) { HashSet <Variable> loopCounters = new HashSet <Variable>(); HashSet <Variable> modifiedVariables = region.GetModifiedVariables(); // Get the partition variables associated with the header HashSet <Variable> partitionVars = region.PartitionVariablesOfRegion(); foreach (Variable v in partitionVars) { // Find the expression which defines a particular partition variable. // Visit the expression and select any variable in the mod set of the loop. // We assume that any variable satisfying these conditions is a loop counter Expr partitionDefExpr = verifier.VarDefAnalysesRegion[impl].DefOfVariableName(v.Name); if (partitionDefExpr == null) // multiple definitions or no definition { continue; } var visitor = new VariablesOccurringInExpressionVisitor(); visitor.Visit(partitionDefExpr); foreach (Variable variable in visitor.GetVariables()) { if (modifiedVariables.Contains(variable)) { loopCounters.Add(variable); } } } foreach (Variable loopCounter in loopCounters) { foreach (Block preheader in region.PreHeaders()) { foreach (AssignCmd cmd in preheader.Cmds.Where(x => x is AssignCmd).Reverse <Cmd>()) { var lhss = cmd.Lhss.Where(x => x is SimpleAssignLhs); foreach (var lhsRhs in lhss.Zip(cmd.Rhss)) { if (lhsRhs.Item1.DeepAssignedVariable.Name == loopCounter.Name) { verifier.AddCandidateInvariant(region, verifier.IntRep.MakeSle(new IdentifierExpr(loopCounter.tok, loopCounter), lhsRhs.Item2), "loopBound"); verifier.AddCandidateInvariant(region, verifier.IntRep.MakeSge(new IdentifierExpr(loopCounter.tok, loopCounter), lhsRhs.Item2), "loopBound"); verifier.AddCandidateInvariant(region, verifier.IntRep.MakeUle(new IdentifierExpr(loopCounter.tok, loopCounter), lhsRhs.Item2), "loopBound"); verifier.AddCandidateInvariant(region, verifier.IntRep.MakeUge(new IdentifierExpr(loopCounter.tok, loopCounter), lhsRhs.Item2), "loopBound"); } } } } } }
private static void GenerateCandidateForReducedStrengthStrideVariables(GPUVerifier verifier, Implementation impl, IRegion region) { var rsa = verifier.ReducedStrengthAnalysesRegion[impl]; var regionId = region.Identifier(); foreach (string iv in rsa.StridedInductionVariables(regionId)) { var sc = rsa.GetStrideConstraint(iv, regionId); Variable ivVariable = impl.LocVars.Where(item => item.Name == iv).First(); var ivExpr = new IdentifierExpr(Token.NoToken, ivVariable); var ivPred = sc.MaybeBuildPredicate(verifier, ivExpr); if (ivPred != null) { verifier.AddCandidateInvariant(region, ivPred, "loopCounterIsStrided"); } } }
private static void GenerateCandidateForNonNegativeGuardVariables(GPUVerifier verifier, Implementation impl, IRegion region) { HashSet <Variable> partitionVars = region.PartitionVariablesOfHeader(); HashSet <Variable> nonnegVars = new HashSet <Variable>(); var formals = impl.InParams.Select(x => x.Name); var modset = GetModifiedVariables(region).Select(x => x.Name); Regex pattern = new Regex(@"\bBV\d*_((SLE)|(SLT)|(SGE)|(SGT))\b"); foreach (var v in partitionVars) { var expr = verifier.varDefAnalysesRegion[impl].DefOfVariableName(v.Name); if (!(expr is NAryExpr)) { continue; } var nary = expr as NAryExpr; if (!pattern.Match(nary.Fun.FunctionName).Success) { continue; } var visitor = new VariablesOccurringInExpressionVisitor(); visitor.Visit(nary); nonnegVars.UnionWith( visitor.GetVariables().Where( x => x.Name.StartsWith("$") && !formals.Contains(x.Name) && modset.Contains(x.Name) && x.TypedIdent.Type.IsBv ) ); } foreach (var v in nonnegVars) { int BVWidth = v.TypedIdent.Type.BvBits; // REVISIT: really we only want to guess for /integer/ variables. if (BVWidth >= 8) { var inv = verifier.IntRep.MakeSle(verifier.Zero(BVWidth), new IdentifierExpr(v.tok, v)); verifier.AddCandidateInvariant(region, inv, "guardNonNeg"); } } }
private static void GenerateCandidateForEnablednessWhenAccessingSharedArrays(GPUVerifier verifier, Implementation impl, IRegion region) { Block header = region.Header(); if (verifier.UniformityAnalyser.IsUniform(impl.Name, header)) { return; } var cfg = Program.GraphFromImpl(impl); Dictionary <Block, HashSet <Block> > controlDependence = cfg.ControlDependence(); controlDependence.TransitiveClosure(); cfg.ComputeLoops(); List <Expr> guards = new List <Expr>(); foreach (var b in controlDependence.Keys.Where(item => controlDependence[item].Contains(region.Header()))) { foreach (var succ in cfg.Successors(b).Where(item => cfg.DominatorMap.DominatedBy(header, item))) { var guard = MaybeExtractGuard(verifier, impl, succ); if (guard != null) { guards.Add(guard); break; } } } if (guards.Count == 0) { return; } IEnumerable <Variable> readVariables; IEnumerable <Variable> writtenVariables; GetReadAndWrittenVariables(region, out readVariables, out writtenVariables); foreach (var v in readVariables.Where(item => verifier.KernelArrayInfo.GetGlobalAndGroupSharedArrays(false).Contains(item) && !verifier.KernelArrayInfo.GetReadOnlyGlobalAndGroupSharedArrays(true).Contains(item))) { foreach (var g in guards) { verifier.AddCandidateInvariant( region, Expr.Imp(Expr.Ident(verifier.FindOrCreateAccessHasOccurredVariable(v.Name, AccessType.READ)), g), "accessOnlyIfEnabledInEnclosingScopes", "do_not_predicate"); } } foreach (var v in writtenVariables.Where(item => verifier.KernelArrayInfo.GetGlobalAndGroupSharedArrays(false).Contains(item))) { foreach (var g in guards) { verifier.AddCandidateInvariant( region, Expr.Imp(Expr.Ident(verifier.FindOrCreateAccessHasOccurredVariable(v.Name, AccessType.WRITE)), g), "accessOnlyIfEnabledInEnclosingScopes", "do_not_predicate"); } } }
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"); } } } } }
private static void GenerateCandidateForEnabledness(GPUVerifier verifier, Implementation impl, IRegion region) { Block header = region.Header(); if (verifier.UniformityAnalyser.IsUniform(impl.Name, header)) { return; } var cfg = Program.GraphFromImpl(impl); Dictionary <Block, HashSet <Block> > controlDependence = cfg.ControlDependence(); controlDependence.TransitiveClosure(); cfg.ComputeLoops(); var loopNodes = cfg.BackEdgeNodes(header).Select(item => cfg.NaturalLoops(header, item)).SelectMany(item => item); Expr guardEnclosingLoop = null; foreach (var b in controlDependence.Keys.Where(item => controlDependence[item].Contains(region.Header()))) { foreach (var succ in cfg.Successors(b).Where(item => cfg.DominatorMap.DominatedBy(header, item))) { var guard = MaybeExtractGuard(verifier, impl, succ); if (guard != null) { guardEnclosingLoop = guardEnclosingLoop == null ? guard : Expr.And(guardEnclosingLoop, guard); break; } } } if (guardEnclosingLoop != null) { verifier.AddCandidateInvariant( region, Expr.Imp(Expr.Ident(verifier.FindOrCreateEnabledVariable()), guardEnclosingLoop), "conditionsImpliedByEnabledness"); } var cfgDual = cfg.Dual(new Block()); Block loopConditionDominator = header; // The dominator might have multiple successors while (cfg.Successors(loopConditionDominator).Count(item => loopNodes.Contains(item)) > 1) { // Find the immediate post-dominator of the successors Block block = null; foreach (var succ in cfg.Successors(loopConditionDominator).Where(item => loopNodes.Contains(item))) { if (block == null) { block = succ; } else { block = cfgDual.DominatorMap.LeastCommonAncestor(block, succ); } } // Use the immediate post-dominator loopConditionDominator = block; } Expr guardIncludingLoopCondition = null; foreach (var succ in cfg.Successors(loopConditionDominator).Where(item => loopNodes.Contains(item))) { var guard = MaybeExtractGuard(verifier, impl, succ); if (guard != null) { // There is at most one successor, so it's safe not use GuardIncludingLoopCondition on the rhs guardIncludingLoopCondition = guardEnclosingLoop == null ? guard : Expr.And(guardEnclosingLoop, guard); break; } } if (guardIncludingLoopCondition != null) { verifier.AddCandidateInvariant( region, Expr.Imp(guardIncludingLoopCondition, Expr.Ident(verifier.FindOrCreateEnabledVariable())), "conditionsImplyingEnabledness", "do_not_predicate"); } }