summaryrefslogtreecommitdiff
path: root/Source/GPUVerify/NonLocalAccessCollector.cs
blob: 6a934899160260ca84a87fcf6dd0369cc12801b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Boogie;
using System.Diagnostics;


namespace GPUVerify
{
    class NonLocalAccessCollector : StandardVisitor
    {
        public HashSet<Expr> Accesses = new HashSet<Expr>();

        private IKernelArrayInfo NonLocalState;

        public NonLocalAccessCollector(IKernelArrayInfo NonLocalState)
        {
            this.NonLocalState = NonLocalState;
        }

        public static bool IsNonLocalAccess(Expr n, IKernelArrayInfo NonLocalState)
        {
            if (n is NAryExpr)
            {
                NAryExpr node = n as NAryExpr;
                if (node.Fun is MapSelect)
                {
                    Expr temp = node;
                    while (temp is NAryExpr && (temp as NAryExpr).Fun is MapSelect)
                    {
                        temp = (temp as NAryExpr).Args[0];
                    }
                    Debug.Assert(temp is IdentifierExpr);

                    Variable v = (temp as IdentifierExpr).Decl;

                    return (NonLocalState.Contains(v));
                }
            }

            if (n is IdentifierExpr)
            {
                IdentifierExpr node = n as IdentifierExpr;
                return NonLocalState.Contains(node.Decl);
            }

            return false;
        }

        public static bool ContainsNonLocalAccess(AssignLhs lhs, IKernelArrayInfo NonLocalState)
        {
            NonLocalAccessCollector collector = new NonLocalAccessCollector(NonLocalState);
            if (lhs is SimpleAssignLhs)
            {
                collector.VisitSimpleAssignLhs(lhs as SimpleAssignLhs);
            }
            else
            {
                Debug.Assert(lhs is MapAssignLhs);
                collector.VisitMapAssignLhs(lhs as MapAssignLhs);
            }
            return collector.Accesses.Count > 0;
        }

        public static bool ContainsNonLocalAccess(Expr rhs, IKernelArrayInfo NonLocalState)
        {
            NonLocalAccessCollector collector = new NonLocalAccessCollector(NonLocalState);
            collector.VisitExpr(rhs);
            return collector.Accesses.Count > 0;
        }


        public override Expr VisitNAryExpr(NAryExpr node)
        {
            if (IsNonLocalAccess(node, NonLocalState))
            {
                Accesses.Add(node);
                return node;
            }
            return base.VisitNAryExpr(node);
        }

        public override Expr VisitIdentifierExpr(IdentifierExpr node)
        {
            if (IsNonLocalAccess(node, NonLocalState))
            {
                Accesses.Add(node);
                return node;
            }
            return base.VisitIdentifierExpr(node);
        }

    }
}