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); }
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)); }