예제 #1
0
 public override CallGraphNode Visit(CallGraphNode node)
 {
     foreach (var child in node.Callees)
     {
         Console.WriteLine(node.Name + " -> " + child.Name);
     }
     return(base.Visit(node));
 }
예제 #2
0
 public WorklistNode(CallGraphNode fst, CallGraphNode snd)
 {
     if (fst == null || snd == null)
     {
         Log.Out(Log.Urgent, "Constructing worklist node with null members");
     }
     this.fst      = fst;
     this.snd      = snd;
     this.children = new List <WorklistNode>();
     equiv         = EqState.UNK;
 }
예제 #3
0
        public bool AddProcedure(Procedure p)
        {
            if (p == null)
            {
                return(false);
            }

            CallGraphNode node = NodeOfName(p.Name);

            return(node.UseProcedure(p));
        }
예제 #4
0
        public bool AddImplementation(Implementation i)
        {
            if (i == null)
            {
                return(false);
            }

            CallGraphNode node = NodeOfName(i.Name);

            return(node.UseImplementation(this, i));
        }
예제 #5
0
        public CallGraphNode NodeOfName(string name)
        {
            CallGraphNode node;

            nodes.TryGetValue(name, out node);
            if (node == null)
            {
                nodes.Add(name, node = new CallGraphNode(name));
            }
            return(node);
        }
예제 #6
0
 public void Visit(CallGraphNode node)
 {
     if (visited.Contains(node))
     {
         HasCycle = true;
     }
     foreach (var child in node.Callees)
     {
         if (child != node)
         {
             Visit(child);
         }
     }
 }
예제 #7
0
        //base visit does a DFS
        public virtual CallGraphNode Visit(CallGraphNode node)
        {
            Visited.Add(node);

            for (int i = 0; node.Callees != null && i < node.Callees.Count; i++)
            {
                if (!Visited.Contains(node.Callees[i]))
                {
                    node.Callees[i] = Visit(node.Callees[i]);
                }
            }

            return(node);
        }
예제 #8
0
 public override CallGraphNode Visit(CallGraphNode node)
 {
     if (node.WriteSet != null && node.Impl != null)
     {
         foreach (Variable v in node.Impl.OutParams)
         {
             if (!node.WriteSet.Contains(v))
             {
                 node.IgnoreSet.Add(v);
             }
         }
     }
     return(base.Visit(node));
 }
예제 #9
0
        public void Visit(CallGraphNode node)
        {
            if (!Visited.Contains(node))
            {
                Indices.Replace(node, CurIndex);
                Levels.Replace(node, CurIndex);
                CurIndex++;
                Visited.Push(node);

                foreach (var child in node.Callees)
                {
                    if (!Visited.Contains(child))
                    {
                        Visit(child);
                        Levels.Replace(node, Math.Min(Levels.Get(child), Levels.Get(node)));
                    }
                    else
                    {
                        Levels.Replace(node, Math.Min(Levels.Get(node), Indices.Get(child)));
                    }
                }

                if (Levels.Get(node) == Indices.Get(node))
                {
                    var           scc  = new List <CallGraphNode>();
                    CallGraphNode next = Visited.Pop();
                    scc.Add(node);
                    while (next != node)
                    {
                        scc.Add(next);
                        next = Visited.Pop();
                    }
                    SCCs.Add(scc);
                }
            }
        }
예제 #10
0
        public override CallGraphNode Visit(CallGraphNode node)
        {
            if (node.Impl == null && node.Proc == null)
            {
                Log.Out(Log.Error, "RWSetDecorator hit incomplete callgraph");
                return(node);
            }

            base.Visit(node);

            node.ReadSet  = new HashSet <Variable>();
            node.WriteSet = new HashSet <Variable>();

            //if there's a node with only a signature, we'll use the signature's modifies set to determine the read/write set
            //changed to eliminate the existing modifies set instead.
            if (node.Impl == null && node.Proc != null)
            {
                //DEBUG
                foreach (IdentifierExpr ie in node.Proc.Modifies)
                {
                    node.WriteSet.Add(ie.Decl);
                    node.ReadSet.Add(ie.Decl);
                }
                return(node);
            }

            var writes = new VariableCollector();
            var reads  = new VariableCollector();

            foreach (Block b in node.Impl.Blocks)
            {
                foreach (Cmd c in b.Cmds)
                {
                    //if it's been written to already, the read is of a new value
                    //and hence shouldn't be counted
                    reads.Exempt = new HashSet <Variable>(writes.Vars);

                    var assgn = c as AssignCmd;
                    if (assgn != null)
                    {
                        for (int i = 0; i < assgn.Rhss.Count; i++)
                        {
                            reads.VisitExpr(assgn.Rhss[i]);
                        }
                        for (int i = 0; i < assgn.Lhss.Count; i++)
                        {
                            //map write operations are also implicit reads
                            //(since one of the update parameters is the current map)
                            if (assgn.Lhss[i] is MapAssignLhs)
                            {
                                reads.VisitExpr(assgn.Lhss[i].AsExpr);
                            }
                            //BUG:the write should only collect the top-level expr
                            //writes.VisitExpr(assgn.Lhss[i].AsExpr);
                            writes.Vars.Add(assgn.Lhss[i].DeepAssignedVariable);
                        }
                    }

                    var call = c as CallCmd;
                    if (call != null)
                    {
                        call.Ins.Iterate(x => reads.Visit(x));
                        call.Outs.Iterate(x => writes.Visit(x));

                        var calleeNode = CGraph.NodeOfName(call.Proc.Name);
                        if (calleeNode != node)
                        {
                            //if (calleeNode.ReadSetGlobals.Count == 0)
                            //  Log.Out(Log.Warning, "Child node " + call.Proc.Name + " of " + node.Name + " has null Read set");
                            //else
                            reads.Vars.AddRange(CGraph.NodeOfName(call.Proc.Name).ReadSetGlobals);
                            //if (calleeNode.WriteSetGlobals.Count == 0)
                            //  Log.Out(Log.Warning, "Child node " + call.Proc.Name + " of " + node.Name + " has null Write set");
                            //else
                            writes.Vars.AddRange(CGraph.NodeOfName(call.Proc.Name).WriteSetGlobals);
                        }
                    }

                    var assrt = c as AssertCmd;
                    if (assrt != null)
                    {
                        reads.Visit(assrt.Expr);
                    }

                    var assme = c as AssumeCmd;
                    if (assme != null)
                    {
                        reads.Visit(assme.Expr);
                    }
                }
            }

            node.ReadSet.UnionWith(reads.Vars); //|| x is Constant)); this is sound as long as the constant sets are the same
            node.WriteSet.UnionWith(writes.Vars);

            return(node);
        }
예제 #11
0
 public override CallGraphNode Visit(CallGraphNode node)
 {
     base.Visit(node);
     ordering.Add(node);
     return(node);
 }