Statement (Statement stat, boolean forceall, HashMap<Integer, Set<Integer>> mapExtPost) { VBStyleCollection<Statement, Integer> stats = stat.getStats(); VBStyleCollection<List<Integer>, Integer> vbPost; if (mapExtPost.isEmpty()) { FastExtendedPostdominanceHelper extpost = new FastExtendedPostdominanceHelper(); mapExtPost.putAll(extpost.getExtendedPostdominators(stat)); } if (forceall) { vbPost = new VBStyleCollection<>(); List<Statement> lstAll = stat.getPostReversePostOrderList(); for (Statement st : lstAll) { Set<Integer> set = mapExtPost.get(st.id); if (set != null) { vbPost.addWithKey(new ArrayList<>(set), st.id); // FIXME: sort order!! } } // tail statements Set<Integer> setFirst = mapExtPost.get(stat.getFirst().id); if (setFirst != null) { for (Integer id : setFirst) { List<Integer> lst = vbPost.getWithKey(id); if (lst == null) { vbPost.addWithKey(lst = new ArrayList<>(), id); } lst.add(id); } } } else { vbPost = calcPostDominators(stat); } for (int k = 0; k < vbPost.size(); k++) { Integer headid = vbPost.getKey(k); List<Integer> posts = vbPost.get(k); if (!mapExtPost.containsKey(headid) && !(posts.size() == 1 && posts.get(0).equals(headid))) { continue; } Statement head = stats.getWithKey(headid); Set<Integer> setExtPosts = mapExtPost.get(headid); for (Integer postId : 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; } boolean same = (post == head); HashSet<Statement> setNodes = new HashSet<>(); HashSet<Statement> setPreds = new HashSet<>(); // collect statement nodes HashSet<Statement> setHandlers = new HashSet<>(); setHandlers.add(head); while (true) { boolean hdfound = false; for (Statement handler : setHandlers) { if (setNodes.contains(handler)) { continue; } boolean addhd = (setNodes.size() == 0); // first handler == head if (!addhd) { List<Statement> hdsupp = handler.getNeighbours(EdgeType.EXCEPTION, EdgeDirection.BACKWARD); addhd = (setNodes.containsAll(hdsupp) && (setNodes.size() > hdsupp.size() || setNodes.size() == 1)); // strict subset } if (addhd) { LinkedList<Statement> lstStack = new LinkedList<>(); lstStack.add(handler); while (!lstStack.isEmpty()) { Statement st = lstStack.remove(0); if (!(setNodes.contains(st) || (!same && st == post))) { setNodes.add(st); if (st != head) { // record predeccessors except for the head setPreds.addAll(st.getNeighbours(EdgeType.REGULAR, EdgeDirection.BACKWARD)); } // put successors on the stack lstStack.addAll(st.getNeighbours(EdgeType.REGULAR, EdgeDirection.FORWARD)); // exception edges setHandlers.addAll(st.getNeighbours(EdgeType.EXCEPTION, EdgeDirection.FORWARD)); } } hdfound = true; setHandlers.remove(handler); break; } } if (!hdfound) { break; } } // check exception handlers setHandlers.clear(); for (Statement st : setNodes) { setHandlers.addAll(st.getNeighbours(EdgeType.EXCEPTION, EdgeDirection.FORWARD)); } setHandlers.removeAll(setNodes); boolean excok = true; for (Statement handler : setHandlers) { if (!handler.getNeighbours(EdgeType.EXCEPTION, EdgeDirection.BACKWARD).containsAll(setNodes)) { excok = false; break; } } // build statement and return if (excok) { Statement res; setPreds.removeAll(setNodes); if (setPreds.size() == 0) { if ((setNodes.size() > 1 || head.getNeighbours(EdgeType.REGULAR, EdgeDirection.BACKWARD).contains(head)) && setNodes.size() < stats.size()) { if (checkSynchronizedCompleteness(setNodes)) { res = new GeneralStatement(head, setNodes, same ? null : post); stat.collapseNodesToStatement(res); return res; } } } } } } return null; }