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);
        }
Example #2
0
        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");
                        }
                    }
                }
            }
        }