/** Merge the congruence classes containing vertices v1 and v2.; */ public void mergeClasses(OPT_ValueGraphVertex v1, OPT_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; OPT_GVCongruenceClass class1 = (OPT_GVCongruenceClass) B.get(val1); while (true) { OPT_GVCongruenceClass class2 = (OPT_GVCongruenceClass) B.get(val2); Iterator i = class2.iterator(); if (!i.hasNext()) break; OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) 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); }
/** * Does the current state of the algorithm optimistically assume that two nodes are congruent? * Note: this can return false even if the value numbers are currently the same. * * @param v1 first vertex * @param v2 second vertex */ private boolean checkCongruence(OPT_ValueGraphVertex v1, OPT_ValueGraphVertex v2) { if (v1 == v2) return true; // make sure the two nodes have the same label if (v1.getLabel() != v2.getLabel()) return false; // make sure that the operands match int arity = v1.getArity(); for (int i = 0; i < arity; i++) { OPT_ValueGraphVertex target1 = v1.getTarget(i); OPT_ValueGraphVertex target2 = v2.getTarget(i); // if either target is null, then that particular control // flow path is never realized, so assume TOP if ((target1 == null) || (target2 == null)) continue; if (target1.getValueNumber() != target2.getValueNumber()) return false; } return true; }
/** Print the value numbers for each node in the value graph. */ public void printValueNumbers() { for (Enumeration e = valueGraph.enumerateVertices(); e.hasMoreElements(); ) { OPT_ValueGraphVertex v = (OPT_ValueGraphVertex) e.nextElement(); int valueNumber = v.getValueNumber(); OPT_GVCongruenceClass c = (OPT_GVCongruenceClass) B.get(valueNumber); System.out.println(v.name + " " + valueNumber + " " + c.getLabel()); } }
/** * 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); } } }
/** * Return the (integer) value number for a given variable * * @param name name of the variable to look up * @return its value number */ public int getValueNumber(Object name) { OPT_ValueGraphVertex v = valueGraph.getVertex(name); if (v == null) return UNKNOWN; return v.getValueNumber(); }
public OPT_GVCongruenceClass congruenceClass(Object name) { OPT_ValueGraphVertex v = valueGraph.getVertex(name); return ((OPT_GVCongruenceClass) B.get(v.getValueNumber())); }
/** * Definitely-different relation. Returns true for the following cases: * * <ul> * <li>name1 and name2 are both constants, but don't match * <li>name1 and name2 both result from NEW statements, but don't match * <li>one of name1 and name2 is a parameter, and the other results from a new statement * </ul> * * <p>TODO: add more smarts * * @param name1 name of first object to compare * @param name2 name of second object to compare * @return true iff the value numbers for two variables are definitely different */ public boolean DD(Object name1, Object name2) { OPT_ValueGraphVertex v1 = valueGraph.getVertex(name1); OPT_ValueGraphVertex v2 = valueGraph.getVertex(name2); return DD(v1.getValueNumber(), v2.getValueNumber()); }
/** * Definitely-same relation. * * @param name1 first variable * @param name2 second variable * @return true iff the value numbers for two variables are equal */ public boolean DS(Object name1, Object name2) { OPT_ValueGraphVertex v1 = valueGraph.getVertex(name1); OPT_ValueGraphVertex v2 = valueGraph.getVertex(name2); if (v1.getValueNumber() == v2.getValueNumber()) return true; else return false; }