private List <Cmd> AddConstantWriteAsserts(List <Cmd> cs)
        {
            var result = new List <Cmd>();

            foreach (Cmd c in cs)
            {
                result.Add(c);

                if (c is AssertCmd)
                {
                    AssertCmd assertion = c as AssertCmd;
                    if (QKeyValue.FindBoolAttribute(assertion.Attributes, "sourceloc"))
                    {
                        sourceLocationAttributes = assertion.Attributes;

                        // Do not remove source location assertions
                        // This is done by the race instrumenter
                    }
                }

                if (c is AssignCmd)
                {
                    AssignCmd assign = c as AssignCmd;

                    foreach (var lhsRhs in assign.Lhss.Zip(assign.Rhss))
                    {
                        ConstantWriteCollector cwc = new ConstantWriteCollector(stateToCheck);
                        cwc.Visit(lhsRhs.Item1);
                        if (cwc.FoundWrite())
                        {
                            AssertCmd constantAssert = new AssertCmd(Token.NoToken, Expr.False);
                            constantAssert.Attributes =
                                new QKeyValue(Token.NoToken, "constant_write", new List <object>(), null);
                            for (QKeyValue attr = sourceLocationAttributes; attr != null; attr = attr.Next)
                            {
                                if (attr.Key != "sourceloc")
                                {
                                    constantAssert.Attributes = new QKeyValue(attr.tok, attr.Key, attr.Params, constantAssert.Attributes);
                                }
                            }

                            result.Add(constantAssert);
                        }
                    }
                }
            }

            return(result);
        }
Exemplo n.º 2
0
        private static bool AccessesGlobalArrayOrUnsafeBarrier(Cmd c, GPUVerifier verifier)
        {
            var stateToCheck = verifier.KernelArrayInfo;

            if (c is CallCmd)
            {
                // Speculate invariants if we see atomics, async_work_group_copy, and
                // wait_group_events, which relate to race checking
                CallCmd call = c as CallCmd;
                if (QKeyValue.FindBoolAttribute(call.Attributes, "atomic"))
                {
                    return(true);
                }

                if (QKeyValue.FindBoolAttribute(call.Attributes, "async_work_group_copy"))
                {
                    return(true);
                }

                if (QKeyValue.FindBoolAttribute(call.Attributes, "wait_group_events"))
                {
                    return(true);
                }

                // Speculate invariants if we see an unsafe barrier,
                // which we need to check for barrier divergence
                if (GPUVerifier.IsBarrier(call.Proc) &&
                    !QKeyValue.FindBoolAttribute(call.Proc.Attributes, "safe_barrier"))
                {
                    return(true);
                }

                // Speculate invariants if we see a call to a procedure that has a non-local array
                // or constant array in its modset
                List <Variable> vars = new List <Variable>();
                call.AddAssignedVariables(vars);
                foreach (Variable v in vars)
                {
                    if (stateToCheck.GetGlobalAndGroupSharedArrays(false).Contains(v))
                    {
                        return(true);
                    }

                    if (stateToCheck.GetConstantArrays().Contains(v))
                    {
                        return(true);
                    }
                }
            }

            // Speculate invariants if race instrumentation or a constant write
            // instrumentation will occur
            if (c is AssignCmd)
            {
                AssignCmd assign = c as AssignCmd;

                ReadCollector rc = new ReadCollector(stateToCheck);
                foreach (var rhs in assign.Rhss)
                {
                    rc.Visit(rhs);
                }
                foreach (var access in rc.NonPrivateAccesses)
                {
                    // Ignore disabled arrays
                    if (stateToCheck.GetGlobalAndGroupSharedArrays(false).Contains(access.V))
                    {
                        // Ignore read-only arrays (whether or not they are disabled)
                        if (!stateToCheck.GetReadOnlyGlobalAndGroupSharedArrays(true).Contains(access.V))
                        {
                            return(true);
                        }
                    }
                }

                foreach (var lhsRhs in assign.Lhss.Zip(assign.Rhss))
                {
                    WriteCollector wc = new WriteCollector(stateToCheck);
                    wc.Visit(lhsRhs.Item1);
                    if (wc.FoundNonPrivateWrite())
                    {
                        // Ignore disabled arrays
                        if (stateToCheck.GetGlobalAndGroupSharedArrays(false).Contains(wc.GetAccess().V))
                        {
                            return(true);
                        }
                    }
                }

                foreach (var lhsRhs in assign.Lhss.Zip(assign.Rhss))
                {
                    ConstantWriteCollector cwc = new ConstantWriteCollector(stateToCheck);
                    cwc.Visit(lhsRhs.Item1);
                    if (cwc.FoundWrite())
                    {
                        // Ignore disabled arrays
                        if (stateToCheck.GetGlobalAndGroupSharedArrays(false).Contains(cwc.GetAccess().V))
                        {
                            return(true);
                        }
                    }
                }
            }

            // Speculate invariants if we see an assert that is not a sourceloc or
            // block_sourceloc assert; such asserts is likely user supplied.
            if (c is AssertCmd)
            {
                AssertCmd assertion = c as AssertCmd;
                if (!QKeyValue.FindBoolAttribute(assertion.Attributes, "sourceloc") &&
                    !QKeyValue.FindBoolAttribute(assertion.Attributes, "block_sourceloc") &&
                    !assertion.Expr.Equals(Expr.True))
                {
                    return(true);
                }
            }

            // Speculate invariants if we see an assume that is not a partition; such
            // an assume is likely user supplied.
            if (c is AssumeCmd)
            {
                AssumeCmd assumption = c as AssumeCmd;
                if (!QKeyValue.FindBoolAttribute(assumption.Attributes, "partition"))
                {
                    return(true);
                }
            }

            return(false);
        }