/** * Partition a congruence class. * * @param partition the class to partition */ private void partitionClass(OPT_GVCongruenceClass partition) { // store a reference to the first node in c, which will serve // as a representative for this class Iterator i = partition.iterator(); OPT_ValueGraphVertex first = (OPT_ValueGraphVertex) i.next(); ArrayList newClasses = new ArrayList(); // now check each other node in c, to see if it matches the // representative ArrayList toRemove = new ArrayList(); for (; i.hasNext(); ) { OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) 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] OPT_GVCongruenceClass match = (OPT_GVCongruenceClass) 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 OPT_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 (Iterator it = toRemove.iterator(); it.hasNext(); ) { OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) it.next(); partition.removeVertex(v); } // if needed place the original partition back on the work list if ((newClasses.size() > 0) && (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 (int j = 0; j < newClasses.size(); j++) { OPT_GVCongruenceClass c = (OPT_GVCongruenceClass) newClasses.get(j); if (c.size() > 1) workList.push(c); addDependentClassesToWorklist(c); } }
/** * Assuming congruence class c has changed: find all other classes that might be affected, and add * them to the worklist * * @param c the congruence class that has changed */ private void addDependentClassesToWorklist(OPT_GVCongruenceClass c) { // for each element of this congruence class: for (Iterator elements = c.iterator(); elements.hasNext(); ) { OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) elements.next(); // for each vertex which points to v in the value graph for (Enumeration e = v.inNodes(); e.hasMoreElements(); ) { OPT_ValueGraphVertex in = (OPT_ValueGraphVertex) e.nextElement(); int vn = in.getValueNumber(); OPT_GVCongruenceClass x = (OPT_GVCongruenceClass) B.get(vn); workList.push(x); } } }
/** * Initialize the work list. A congruence class gets put on the work list if any two nodes in the * class point to corresponding targets in separate partitions. */ private void initializeWorkList() { for (Iterator it = B.iterator(); it.hasNext(); ) { OPT_GVCongruenceClass c = (OPT_GVCongruenceClass) it.next(); if (c.size() == 1) continue; // store a reference to the first node in c Iterator i = c.iterator(); OPT_ValueGraphVertex first = (OPT_ValueGraphVertex) i.next(); // now check that each other target matches the first element // if not, add this class to the work list congruenceClass: for (; i.hasNext(); ) { OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) i.next(); if (!checkCongruence(first, v)) { workList.push(c); break congruenceClass; } } } }