Exemple #1
0
        void AnalyseAssignment(Variable variable, List <Tuple <IRegion, Expr> > defs, Graph <Block> cfg, HashSet <Variable> modSet)
        {
            // Ensure defs[0] refers to the definition from the outermost region
            // This also checks that the definitions are in different regions
            if (!OrderDefs(defs, cfg))
            {
                return;
            }

            var regionId       = defs[1].Item1.Identifier();
            var varDefAnalysis = verifier.varDefAnalysesRegion[impl];
            var varDef         = varDefAnalysis.GetPossibleInductionVariableDefintion(variable.Name, regionId);

            if (varDef == null)
            {
                return;
            }
            HashSet <string> loopFreeVars;
            var defInd = varDefAnalysis.SubstDefinitions(varDef, impl.Name, out loopFreeVars);

            if (loopFreeVars.Any(i => i != variable.Name))
            {
                return;
            }
            var modSetLoop = LoopInvariantGenerator.GetModifiedVariables(defs[1].Item1);
            var v          = new VariablesOccurringInExpressionVisitor();

            v.Visit(defs[0].Item2);
            if (v.GetVariables().Intersect(modSetLoop).Any())
            {
                return;
            }
            AddDefinitionPair(variable, defInd, defs[0].Item2, regionId, modSet);
        }
        private void DiscoverVariableAssignments(Variable variable)
        {
            Absy assignment = null;

            foreach (Block block in cfg.Nodes)
            {
                foreach (Cmd cmd in block.Cmds)
                {
                    if (cmd is AssignCmd)
                    {
                        AssignCmd assignCmd = cmd as AssignCmd;
                        var       lhss      = assignCmd.Lhss.OfType <SimpleAssignLhs>();
                        foreach (var LhsRhs in lhss.Zip(assignCmd.Rhss))
                        {
                            if (LhsRhs.Item1.DeepAssignedVariable.Name == variable.Name)
                            {
                                assignment = LhsRhs.Item2;
                                if (variable.Name == this.initialVariable.Name)
                                {
                                    unexpandedExpr = LhsRhs.Item2;
                                }
                                goto AnalyseAssignment;
                            }
                        }
                    }
                    else if (cmd is CallCmd)
                    {
                        CallCmd call = cmd as CallCmd;
                        foreach (IdentifierExpr outParam in call.Outs)
                        {
                            if (outParam.Name == variable.Name)
                            {
                                assignment = cmd;
                                goto AnalyseAssignment;
                            }
                        }
                    }
                }
            }

            // Label used to allow exit from multiple levels in the previous loop nest
AnalyseAssignment:
            if (assignment != null)
            {
                var visitor = new VariablesOccurringInExpressionVisitor();
                visitor.Visit(assignment);
                foreach (Variable discovered in visitor.GetVariables())
                {
                    if (TEMP_VARIABLE.IsMatch(discovered.Name) && discovered.Name != variable.Name)
                    {
                        DiscoverVariableAssignments(discovered);
                    }
                    else if (GPU_VARIABLE.IsMatch(discovered.Name))
                    {
                        GPUVariables.Add(discovered);
                    }
                }
            }
        }
Exemple #3
0
        public ExprTree(Expr expr)
        {
            this.expr = expr;
            root      = Node.CreateFromExpr(expr);
            levels[0] = new HashSet <Node>();
            levels[0].Add(root);
            SetLevels(root, 0);

            // Set node IDs and see if any scalar node is a race offset variable
            int nodeID = 0;

            foreach (Node node in nodes)
            {
                node.ID = nodeID++;
                if (node is ScalarSymbolNode)
                {
                    ScalarSymbolNode scalarNode = node as ScalarSymbolNode;
                    if (BoogieInterpreter.RegularExpressions.OffsetVariable.IsMatch(scalarNode.Symbol))
                    {
                        OffsetVariables.Add(scalarNode.Symbol);
                    }

                    if (BoogieInterpreter.RegularExpressions.WatchdoVariable.IsMatch(scalarNode.Symbol))
                    {
                        var visitor = new VariablesOccurringInExpressionVisitor();
                        visitor.Visit(this.expr);
                        string offsetVariable = string.Empty;
                        foreach (Variable variable in visitor.GetVariables())
                        {
                            if (BoogieInterpreter.RegularExpressions.TrackingVariable.IsMatch(variable.Name))
                            {
                                int    index      = variable.Name.IndexOf('$');
                                string arrayName  = variable.Name.Substring(index);
                                string accessType = variable.Name.Substring(0, index);
                                if (accessType == "_WRITE_HAS_OCCURRED_")
                                {
                                    offsetVariable = "_WRITE_OFFSET_" + arrayName;
                                }
                                else if (accessType == "_READ_HAS_OCCURRED_")
                                {
                                    offsetVariable = "_READ_OFFSET_" + arrayName;
                                }
                                else
                                {
                                    offsetVariable = "_ATOMIC_OFFSET_" + arrayName;
                                }
                                break;
                            }
                        }

                        OffsetVariables.Add(offsetVariable);
                    }
                }
            }
        }
        public HashSet <Variable> PartitionVariablesOfHeader()
        {
            if (header == null)
            {
                return(new HashSet <Variable>());
            }

            HashSet <Variable> partitionVars = new HashSet <Variable>();
            var   visitor                = new VariablesOccurringInExpressionVisitor();
            var   dualBlockGraph         = blockGraph.Dual(new Block());
            Block loopConditionDominator = header;

            // The dominator might have multiple successors, traverse these
            while (blockGraph.Successors(loopConditionDominator).Count(item => loopNodes[header].Contains(item)) > 1)
            {
                foreach (Block b in blockGraph.Successors(loopConditionDominator))
                {
                    foreach (var assume in b.Cmds.OfType <AssumeCmd>().Where(x => QKeyValue.FindBoolAttribute(x.Attributes, "partition")))
                    {
                        visitor.Visit(assume.Expr);
                        partitionVars.UnionWith(visitor.GetVariables());
                    }
                }

                // Find the immediate post-dominator of the successors
                Block block = null;
                foreach (var succ in blockGraph.Successors(loopConditionDominator).Where(item => loopNodes[header].Contains(item)))
                {
                    if (block == null)
                    {
                        block = succ;
                    }
                    else
                    {
                        block = dualBlockGraph.DominatorMap.LeastCommonAncestor(block, succ);
                    }
                }

                // Use the immediate post-dominator
                loopConditionDominator = block;
            }

            foreach (Block b in blockGraph.Successors(loopConditionDominator))
            {
                foreach (var assume in b.Cmds.OfType <AssumeCmd>().Where(x => QKeyValue.FindBoolAttribute(x.Attributes, "partition")))
                {
                    visitor.Visit(assume.Expr);
                    partitionVars.UnionWith(visitor.GetVariables());
                }
            }

            return(partitionVars);
        }
        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");
                            }
                        }
                    }
                }
            }
        }
Exemple #6
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");
                }
            }
        }
Exemple #7
0
        private void ExprMayAffectControlFlow(string proc, Expr e)
        {
            var visitor = new VariablesOccurringInExpressionVisitor();

            visitor.VisitExpr(e);
            foreach (Variable v in visitor.GetVariables())
            {
                if (!mayBeDerivedFrom[proc].ContainsKey(v.Name))
                {
                    continue;
                }
                foreach (string s in mayBeDerivedFrom[proc][v.Name])
                {
                    if (!arraysWhichMayAffectControlFlow.Contains(s))
                    {
                        SetArrayMayAffectControlFlow(s);
                    }
                }
            }
        }
Exemple #8
0
            public IEnumerable <Tuple <Variable, Expr> > FindSelfReferentialVariables(Dictionary <Block, VarDefs> blockVarDefs)
            {
                var predVarDefs = MergePredecessors(blockVarDefs, predecessors);

                foreach (var p in predVarDefs)
                {
                    if (p.Value == null || p.Value is IdentifierExpr)
                    {
                        continue;
                    }
                    var v = new VariablesOccurringInExpressionVisitor();
                    v.Visit(p.Value);
                    var modVars = v.GetVariables()
                                  .Where(i => i is Variable && modSet.Contains(i as Variable));
                    if (modVars.Count() == 1 && modVars.Single() as Variable == p.Key)
                    {
                        yield return(new Tuple <Variable, Expr>(p.Key, p.Value));
                    }
                }
            }
        public HashSet <Variable> PartitionVariablesOfRegion()
        {
            if (header == null)
            {
                return(new HashSet <Variable>());
            }
            HashSet <Variable> partitionVars = new HashSet <Variable>();

            foreach (Block loopNode in loopNodes[header])
            {
                var visitor = new VariablesOccurringInExpressionVisitor();
                foreach (Block succ in blockGraph.Successors(loopNode))
                {
                    foreach (var assume in succ.Cmds.OfType <AssumeCmd>().Where(x => QKeyValue.FindBoolAttribute(x.Attributes, "partition")))
                    {
                        visitor.Visit(assume.Expr);
                        partitionVars.UnionWith(visitor.GetVariables());
                    }
                }
            }
            return(partitionVars);
        }
Exemple #10
0
        private static void GetReadAndWrittenVariables(IRegion region, out IEnumerable <Variable> ReadVariables, out IEnumerable <Variable> WrittenVariables)
        {
            var readVisitor  = new VariablesOccurringInExpressionVisitor();
            var writeVisitor = new VariablesOccurringInExpressionVisitor();

            foreach (AssignCmd assignment in region.Cmds().OfType <AssignCmd>())
            {
                var mapLhss = assignment.Lhss.OfType <MapAssignLhs>();
                foreach (var LhsRhs in mapLhss.Zip(assignment.Rhss))
                {
                    writeVisitor.Visit(LhsRhs.Item1);
                    readVisitor.Visit(LhsRhs.Item2);
                }
                var simpleLhss = assignment.Lhss.OfType <SimpleAssignLhs>();
                foreach (var LhsRhs in simpleLhss.Zip(assignment.Rhss))
                {
                    readVisitor.Visit(LhsRhs.Item2);
                }
            }
            ReadVariables    = readVisitor.GetVariables();
            WrittenVariables = writeVisitor.GetVariables();
        }
        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");
                        }
                    }
                }
            }
        }
Exemple #12
0
        private void Analyse(Implementation impl, List <Cmd> cs)
        {
            foreach (var c in cs)
            {
                if (c is AssignCmd)
                {
                    AssignCmd assignCmd = c as AssignCmd;
                    for (int i = 0; i != assignCmd.Lhss.Count; i++)
                    {
                        if (assignCmd.Lhss[i] is SimpleAssignLhs)
                        {
                            SimpleAssignLhs lhs = assignCmd.Lhss[i] as SimpleAssignLhs;
                            Expr            rhs = assignCmd.Rhss[i];

                            VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
                            visitor.VisitExpr(rhs);

                            foreach (Variable v in visitor.GetVariables())
                            {
                                if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
                                {
                                    continue;
                                }
                                foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
                                {
                                    if (mayBeDerivedFrom[impl.Name].ContainsKey(lhs.AssignedVariable.Name) && !mayBeDerivedFrom[impl.Name][lhs.AssignedVariable.Name].Contains(s))
                                    {
                                        SetMayBeDerivedFrom(impl.Name, lhs.AssignedVariable.Name, s);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (c is CallCmd)
                {
                    CallCmd callCmd = c as CallCmd;

                    if (QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "barrier_invariant") ||
                        QKeyValue.FindBoolAttribute(callCmd.Proc.Attributes, "binary_barrier_invariant"))
                    {
                        foreach (Expr param in callCmd.Ins)
                        {
                            ExprMayAffectControlFlow(impl.Name, param);
                        }
                    }
                    else if (!GPUVerifier.IsBarrier(callCmd.Proc))
                    {
                        Implementation CalleeImplementation = verifier.GetImplementation(callCmd.callee);
                        if (CalleeImplementation != null)
                        {
                            for (int i = 0; i < CalleeImplementation.InParams.Count(); i++)
                            {
                                VariablesOccurringInExpressionVisitor visitor = new VariablesOccurringInExpressionVisitor();
                                visitor.VisitExpr(callCmd.Ins[i]);

                                foreach (Variable v in visitor.GetVariables())
                                {
                                    if (!mayBeDerivedFrom[impl.Name].ContainsKey(v.Name))
                                    {
                                        continue;
                                    }


                                    foreach (string s in mayBeDerivedFrom[impl.Name][v.Name])
                                    {
                                        if (!mayBeDerivedFrom[callCmd.callee][CalleeImplementation.InParams[i].Name].Contains(s))
                                        {
                                            SetMayBeDerivedFrom(callCmd.callee, CalleeImplementation.InParams[i].Name, s);
                                        }
                                    }
                                }
                            }

                            for (int i = 0; i < CalleeImplementation.OutParams.Count(); i++)
                            {
                                foreach (string s in mayBeDerivedFrom[callCmd.callee][CalleeImplementation.OutParams[i].Name])
                                {
                                    if (!mayBeDerivedFrom[impl.Name][callCmd.Outs[i].Name].Contains(s))
                                    {
                                        SetMayBeDerivedFrom(impl.Name, callCmd.Outs[i].Name, s);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (c is AssumeCmd)
                {
                    var assumeCmd = c as AssumeCmd;
                    ExprMayAffectControlFlow(impl.Name, assumeCmd.Expr);
                }
                else if (c is AssertCmd)
                {
                    var assertCmd = c as AssertCmd;
                    ExprMayAffectControlFlow(impl.Name, assertCmd.Expr);
                }
            }
        }