예제 #1
0
        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");
        }
예제 #2
0
        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");
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        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");
                }
            }
        }
예제 #4
0
        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");
                }
            }
        }
예제 #5
0
        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");
                }
            }
        }
예제 #6
0
        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");
                        }
                    }
                }
            }
        }
예제 #7
0
        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");
            }
        }