Esempio n. 1
0
        private static Statement FindGeneralStatement(Statement stat, bool forceall, Dictionary
                                                      <int, HashSet <int> > mapExtPost)
        {
            VBStyleCollection <Statement, int>  stats = stat.GetStats();
            VBStyleCollection <List <int>, int> vbPost;

            if ((mapExtPost.Count == 0))
            {
                FastExtendedPostdominanceHelper extpost = new FastExtendedPostdominanceHelper();
                Sharpen.Collections.PutAll(mapExtPost, extpost.GetExtendedPostdominators(stat));
            }
            if (forceall)
            {
                vbPost = new VBStyleCollection <List <int>, int>();
                List <Statement> lstAll = stat.GetPostReversePostOrderList();
                foreach (Statement st in lstAll)
                {
                    HashSet <int> set = mapExtPost.GetOrNull(st.id);
                    if (set != null)
                    {
                        vbPost.AddWithKey(new List <int>(set), st.id);
                    }
                }
                // FIXME: sort order!!
                // tail statements
                HashSet <int> setFirst = mapExtPost.GetOrNull(stat.GetFirst().id);
                if (setFirst != null)
                {
                    foreach (int id in setFirst)
                    {
                        List <int> lst = vbPost.GetWithKey(id);
                        if (lst == null)
                        {
                            vbPost.AddWithKey(lst = new List <int>(), id);
                        }
                        lst.Add(id);
                    }
                }
            }
            else
            {
                vbPost = CalcPostDominators(stat);
            }
            for (int k = 0; k < vbPost.Count; k++)
            {
                int        headid = vbPost.GetKey(k);
                List <int> posts  = vbPost[k];
                if (!mapExtPost.ContainsKey(headid) && !(posts.Count == 1 && posts[0].Equals(headid
                                                                                             )))
                {
                    continue;
                }
                Statement     head        = stats.GetWithKey(headid);
                HashSet <int> setExtPosts = mapExtPost.GetOrNull(headid);
                foreach (int postId in posts)
                {
                    if (!postId.Equals(headid) && !setExtPosts.Contains(postId))
                    {
                        continue;
                    }
                    Statement post = stats.GetWithKey(postId);
                    if (post == null)
                    {
                        // possible in case of an inherited postdominance set
                        continue;
                    }
                    bool same = (post == head);
                    HashSet <Statement> setNodes = new HashSet <Statement>();
                    HashSet <Statement> setPreds = new HashSet <Statement>();
                    // collect statement nodes
                    HashSet <Statement> setHandlers = new HashSet <Statement>();
                    setHandlers.Add(head);
                    while (true)
                    {
                        bool hdfound = false;
                        foreach (Statement handler in setHandlers)
                        {
                            if (setNodes.Contains(handler))
                            {
                                continue;
                            }
                            bool addhd = (setNodes.Count == 0);
                            // first handler == head
                            if (!addhd)
                            {
                                List <Statement> hdsupp = handler.GetNeighbours(StatEdge.Type_Exception, Statement
                                                                                .Direction_Backward);
                                addhd = (setNodes.ContainsAll(hdsupp) && (setNodes.Count > hdsupp.Count || setNodes
                                                                          .Count == 1));
                            }
                            // strict subset
                            if (addhd)
                            {
                                LinkedList <Statement> lstStack = new LinkedList <Statement>();
                                lstStack.AddLast(handler);
                                while (!(lstStack.Count == 0))
                                {
                                    Statement st = lstStack.RemoveAtReturningValue(0);
                                    if (!(setNodes.Contains(st) || (!same && st == post)))
                                    {
                                        setNodes.Add(st);
                                        if (st != head)
                                        {
                                            // record predeccessors except for the head
                                            Sharpen.Collections.AddAll(setPreds, st.GetNeighbours(StatEdge.Type_Regular, Statement
                                                                                                  .Direction_Backward));
                                        }
                                        // put successors on the stack
                                        Sharpen.Collections.AddAll(lstStack, st.GetNeighbours(StatEdge.Type_Regular, Statement
                                                                                              .Direction_Forward));
                                        // exception edges
                                        Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception,
                                                                                                 Statement.Direction_Forward));
                                    }
                                }
                                hdfound = true;
                                setHandlers.Remove(handler);
                                break;
                            }
                        }
                        if (!hdfound)
                        {
                            break;
                        }
                    }
                    // check exception handlers
                    setHandlers.Clear();
                    foreach (Statement st in setNodes)
                    {
                        Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception,
                                                                                 Statement.Direction_Forward));
                    }
                    setHandlers.RemoveAll(setNodes);
                    bool excok = true;
                    foreach (Statement handler in setHandlers)
                    {
                        if (!handler.GetNeighbours(StatEdge.Type_Exception, Statement.Direction_Backward)
                            .ContainsAll(setNodes))
                        {
                            excok = false;
                            break;
                        }
                    }
                    // build statement and return
                    if (excok)
                    {
                        Statement res;
                        setPreds.RemoveAll(setNodes);
                        if (setPreds.Count == 0)
                        {
                            if ((setNodes.Count > 1 || head.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward
                                                                          ).Contains(head)) && setNodes.Count < stats.Count)
                            {
                                if (CheckSynchronizedCompleteness(setNodes))
                                {
                                    res = new GeneralStatement(head, setNodes, same ? null : post);
                                    stat.CollapseNodesToStatement(res);
                                    return(res);
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
Esempio n. 2
0
        private static RootStatement GraphToStatement(ControlFlowGraph graph)
        {
            VBStyleCollection <Statement, int>  stats  = new VBStyleCollection <Statement, int>();
            VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks();

            foreach (BasicBlock block in blocks)
            {
                stats.AddWithKey(new BasicBlockStatement(block), block.id);
            }
            BasicBlock firstblock = graph.GetFirst();
            // head statement
            Statement firstst = stats.GetWithKey(firstblock.id);
            // dummy exit statement
            DummyExitStatement dummyexit = new DummyExitStatement();
            Statement          general;

            if (stats.Count > 1 || firstblock.IsSuccessor(firstblock))
            {
                // multiple basic blocks or an infinite loop of one block
                general = new GeneralStatement(firstst, stats, null);
            }
            else
            {
                // one straightforward basic block
                RootStatement root = new RootStatement(firstst, dummyexit);
                firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root));
                return(root);
            }
            foreach (BasicBlock block in blocks)
            {
                Statement stat = stats.GetWithKey(block.id);
                foreach (BasicBlock succ in block.GetSuccs())
                {
                    Statement stsucc = stats.GetWithKey(succ.id);
                    int       type;
                    if (stsucc == firstst)
                    {
                        type = StatEdge.Type_Continue;
                    }
                    else if (graph.GetFinallyExits().Contains(block))
                    {
                        type   = StatEdge.Type_Finallyexit;
                        stsucc = dummyexit;
                    }
                    else if (succ.id == graph.GetLast().id)
                    {
                        type   = StatEdge.Type_Break;
                        stsucc = dummyexit;
                    }
                    else
                    {
                        type = StatEdge.Type_Regular;
                    }
                    stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general
                                                 : stsucc, (type == StatEdge.Type_Regular) ? null : general));
                }
                // exceptions edges
                foreach (BasicBlock succex in block.GetSuccExceptions())
                {
                    Statement         stsuccex = stats.GetWithKey(succex.id);
                    ExceptionRangeCFG range    = graph.GetExceptionRange(succex, block);
                    if (!range.IsCircular())
                    {
                        stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes()));
                    }
                }
            }
            general.BuildContinueSet();
            general.BuildMonitorFlags();
            return(new RootStatement(general, dummyexit));
        }