private void AnalyseRegion(IRegion region, Graph <Block> cfg) { var header = region.Header(); var blockVarDefs = new Dictionary <Block, VarDefs>(); var blocks = region.SubBlocks().Where(i => i != header); var modSet = region.GetModifiedVariables(); blockVarDefs[header] = new VarDefs(header, cfg.BackEdgeNodes(header), modSet); blockVarDefs[header].Initialize(); foreach (var b in blocks) { blockVarDefs[b] = new VarDefs(b, cfg.Predecessors(b), modSet); } var changed = true; while (changed) { changed = false; foreach (var b in blocks) { if (blockVarDefs[b].ComputeTransfer(blockVarDefs)) { changed = true; } } } possibleInductionVarDefs[region.Identifier()] = blockVarDefs[header].FindSelfReferentialVariables(blockVarDefs) .ToDictionary(i => i.Item1.Name, i => i.Item2); }
public override void GenerateCandidates(Implementation impl, IRegion region) { HashSet <Variable> modset = region.GetModifiedVariables(); foreach (Variable v in impl.LocVars) { string basicName = Utilities.StripThreadIdentifier(v.Name); if (Verifier.MayBePowerOfTwoAnalyser.MayBePowerOfTwo(impl.Name, basicName)) { if (Verifier.ContainsNamedVariable(modset, basicName)) { var type = v.TypedIdent.Type; var bitwiseInv = Expr.Or( Expr.Eq(new IdentifierExpr(v.tok, v), Verifier.IntRep.GetZero(type)), Expr.Eq( Verifier.IntRep.MakeAnd( new IdentifierExpr(v.tok, v), Verifier.IntRep.MakeSub( new IdentifierExpr(v.tok, v), Verifier.IntRep.GetLiteral(1, type))), Verifier.IntRep.GetZero(type))); Verifier.AddCandidateInvariant(region, bitwiseInv, "pow2"); Verifier.AddCandidateInvariant( region, Expr.Neq(new IdentifierExpr(v.tok, v), Verifier.IntRep.GetZero(type)), "pow2NotZero"); } } } // Relational Power Of Two var incs = modset.Where(v => Verifier.RelationalPowerOfTwoAnalyser.IsInc(impl.Name, v.Name)); var decs = modset.Where(v => Verifier.RelationalPowerOfTwoAnalyser.IsDec(impl.Name, v.Name)); if (incs.ToList().Count() == 1 && decs.ToList().Count() == 1) { var inc = incs.Single(); var dec = decs.Single(); var type = inc.TypedIdent.Type; if (type.Equals(dec.TypedIdent.Type)) { for (int i = 1 << 15; i > 0; i >>= 1) { var mulInv = Expr.Eq( Verifier.IntRep.MakeMul( new IdentifierExpr(inc.tok, inc), new IdentifierExpr(dec.tok, dec)), Verifier.IntRep.GetLiteral(i, type)); Verifier.AddCandidateInvariant(region, mulInv, "relationalPow2"); var disjInv = Expr.Or( Expr.And( Expr.Eq(new IdentifierExpr(dec.tok, dec), Verifier.IntRep.GetZero(type)), Expr.Eq(new IdentifierExpr(inc.tok, inc), Verifier.IntRep.GetLiteral(2 * i, type))), mulInv); Verifier.AddCandidateInvariant(region, disjInv, "relationalPow2"); } } } }
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 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 = region.GetModifiedVariables().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) { // REVISIT: really we only want to guess for /integer/ variables. var type = v.TypedIdent.Type; if (type.BvBits >= 8) { var inv = verifier.IntRep.MakeSle(verifier.IntRep.GetZero(type), new IdentifierExpr(v.tok, v)); verifier.AddCandidateInvariant(region, inv, "guardNonNeg"); } } }
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"); } } } } }