/** * Partition a congruence class. * * @param partition the class to partition */ private void partitionClass(GVCongruenceClass partition) { // store a reference to the first node in c, which will serve // as a representative for this class Iterator<ValueGraphVertex> i = partition.iterator(); ValueGraphVertex first = i.next(); ArrayList<GVCongruenceClass> newClasses = new ArrayList<GVCongruenceClass>(); // now check each other node in c, to see if it matches the // representative ArrayList<ValueGraphVertex> toRemove = new ArrayList<ValueGraphVertex>(); while (i.hasNext()) { ValueGraphVertex v = i.next(); if (!checkCongruence(first, v)) { // NOT CONGRUENT!! split the partition. first check if // v fits in any other newly created congruence classes int index = findCongruenceMatch(newClasses, v); if (index > -1) { // MATCH FOUND!! place v in newClasses[index] GVCongruenceClass match = B.get(index); match.addVertex(v); v.setValueNumber(match.getValueNumber()); } else { // NO MATCH FOUND!! create a new congruence class // find the appropriate label for the new congruence class // and create a new congruence class with this label GVCongruenceClass c = createCongruenceClass(v); newClasses.add(c); c.addVertex(v); v.setValueNumber(c.getValueNumber()); } // mark v as to be removed from partition // (Can't remove it yet while iterating over the set); toRemove.add(v); } } // remove necessary vertices for (ValueGraphVertex v : toRemove) { partition.removeVertex(v); } // if needed place the original partition back on the work list if ((!newClasses.isEmpty()) && (partition.size() > 1)) { workList.push(partition); } // place any new congruence classes with size > 1 on the worklist // also place any classes which might indirectly be affected for (GVCongruenceClass c : newClasses) { if (c.size() > 1) { workList.push(c); } addDependentClassesToWorklist(c); } }
void mergeClasses(ValueGraphVertex v1, ValueGraphVertex v2) { if (DEBUG) { System.out.println("@@@@ mergeClasses called with v1 = " + v1 + " ; v2 = " + v2); } int val1 = v1.getValueNumber(); int val2 = v2.getValueNumber(); if (val1 == val2) return; GVCongruenceClass class1 = B.get(val1); while (true) { GVCongruenceClass class2 = B.get(val2); Iterator<ValueGraphVertex> i = class2.iterator(); if (!i.hasNext()) break; ValueGraphVertex v = i.next(); if (DEBUG) { System.out.println("@@@@ moving vertex " + v + " from class " + val2 + " to class " + val1); } class1.addVertex(v); class2.removeVertex(v); v.setValueNumber(val1); } // Null out entry for val2 B.set(val2, null); }
/** * Initialize the congruence classes, assuming that all nodes with the same label are congruent. */ private void initialize() { // store a map from label -> congruenceClass HashMap<Object, GVCongruenceClass> labelMap = new HashMap<Object, GVCongruenceClass>(10); for (Enumeration<GraphNode> e = valueGraph.enumerateVertices(); e.hasMoreElements(); ) { ValueGraphVertex v = (ValueGraphVertex) e.nextElement(); Object label = v.getLabel(); GVCongruenceClass c = findOrCreateCongruenceClass(label, labelMap); // add this node to the congruence class c.addVertex(v); // set the value number for the node v.setValueNumber(c.getValueNumber()); } }