private void removeRedundantCopies( Program program, List<MutableGraphNode> interferenceGraph, DisjointSet congruenceClasses) { for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (int j = 0; j < block.getInstructions().size(); ++j) { Instruction insn = block.getInstructions().get(j); if (!(insn instanceof AssignInstruction)) { continue; } AssignInstruction assignment = (AssignInstruction) insn; boolean interfere = false; int copyClass = congruenceClasses.find(assignment.getReceiver().getIndex()); int origClass = congruenceClasses.find(assignment.getAssignee().getIndex()); for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges()) { if (edge.getFirst() == edge.getSecond()) { continue; } int neighbour = congruenceClasses.find(edge.getSecond().getTag()); if (neighbour == copyClass || neighbour == origClass) { interfere = true; break; } } if (!interfere) { int newClass = congruenceClasses.union(copyClass, origClass); block.getInstructions().set(j, new EmptyInstruction()); if (newClass == interferenceGraph.size()) { MutableGraphNode newNode = new MutableGraphNode(interferenceGraph.size()); interferenceGraph.add(newNode); } for (MutableGraphEdge edge : interferenceGraph.get(origClass).getEdges().toArray(new MutableGraphEdge[0])) { if (edge.getFirst() == interferenceGraph.get(origClass)) { edge.setFirst(interferenceGraph.get(newClass)); } if (edge.getSecond() == interferenceGraph.get(origClass)) { edge.setSecond(interferenceGraph.get(newClass)); } } for (MutableGraphEdge edge : interferenceGraph.get(copyClass).getEdges().toArray(new MutableGraphEdge[0])) { if (edge.getFirst() == interferenceGraph.get(copyClass)) { edge.setFirst(interferenceGraph.get(newClass)); } if (edge.getSecond() == interferenceGraph.get(copyClass)) { edge.setSecond(interferenceGraph.get(newClass)); } } interferenceGraph.set(copyClass, interferenceGraph.get(newClass)); interferenceGraph.set(origClass, interferenceGraph.get(newClass)); } } } }
private static void joinClassNodes(List<MutableGraphNode> graph, DisjointSet classes) { int sz = graph.size(); for (int i = 0; i < sz; ++i) { int cls = classes.find(i); while (cls >= graph.size()) { graph.add(new MutableGraphNode(graph.size())); } if (cls != i) { for (MutableGraphEdge edge : graph.get(i).getEdges().toArray(new MutableGraphEdge[0])) { if (edge.getFirst() == graph.get(i)) { edge.setFirst(graph.get(cls)); } if (edge.getSecond() == graph.get(i)) { edge.setSecond(graph.get(cls)); } } graph.set(i, graph.get(cls)); } } }