protected void eliminateDeadCode(JilMethod method) { HashMap<String, Integer> labels = new HashMap(); List<JilStmt> body = method.body(); Stack<Integer> worklist = new Stack(); HashSet<Integer> visited = new HashSet(); // first, initialiser label map int pos = 0; for (JilStmt s : body) { if (s instanceof JilStmt.Label) { JilStmt.Label lab = (JilStmt.Label) s; labels.put(lab.label(), pos); } pos++; } worklist.push(0); visited.add(0); while (!worklist.isEmpty()) { int idx = worklist.pop(); if (idx != body.size()) { JilStmt stmt = body.get(idx); addSuccessors(worklist, visited, labels, stmt, idx); } } // Ok, now eliminate any dead statements (if there are any) if (visited.size() <= body.size()) { pos = 0; int size = body.size(); for (int i = 0; i != size; ++i) { if (!visited.contains(i)) { body.remove(pos); } else { pos = pos + 1; } } } }
protected void addSuccessors( Stack<Integer> worklist, HashSet<Integer> visited, HashMap<String, Integer> labels, JilStmt stmt, int offset) { // First, add sequential exit if there is one. if (stmt instanceof JilStmt.Goto) { JilStmt.Goto gto = (JilStmt.Goto) stmt; int target = labels.get(gto.label()); if (!visited.contains(target)) { worklist.add(target); visited.add(target); } } else if (stmt instanceof JilStmt.Switch) { JilStmt.Switch swt = (JilStmt.Switch) stmt; for (Pair<JilExpr.Number, String> c : swt.cases()) { int target = labels.get(c.second()); if (!visited.contains(target)) { worklist.add(target); visited.add(target); } } // And, don't forget the default label! int deftarget = labels.get(swt.defaultLabel()); if (!visited.contains(deftarget)) { worklist.add(deftarget); visited.add(deftarget); } } else if (!(stmt instanceof JilStmt.Return || stmt instanceof JilStmt.Throw)) { // this is a statement with a sequential exit if (!visited.contains(offset + 1)) { worklist.add(offset + 1); visited.add(offset + 1); } } // Second, check for conditional branch if (stmt instanceof JilStmt.IfGoto) { JilStmt.IfGoto gto = (JilStmt.IfGoto) stmt; int target = labels.get(gto.label()); if (!visited.contains(target)) { worklist.add(target); visited.add(target); } } // Third, add any exceptional edges for (Pair<Type.Clazz, String> ex : stmt.exceptions()) { int target = labels.get(ex.second()); if (!visited.contains(target)) { worklist.add(target); visited.add(target); } } }