/** * Return the (integer) value number for a given variable * * @param name name of the variable to look up * @return its value number */ int getValueNumber(Object name) { ValueGraphVertex v = valueGraph.getVertex(name); if (v == null) { return UNKNOWN; } return v.getValueNumber(); }
/** Print the value numbers for each node in the value graph. */ void printValueNumbers() { for (Enumeration<GraphNode> e = valueGraph.enumerateVertices(); e.hasMoreElements(); ) { ValueGraphVertex v = (ValueGraphVertex) e.nextElement(); int valueNumber = v.getValueNumber(); GVCongruenceClass c = B.get(valueNumber); System.out.println(v.getName() + " " + valueNumber + " " + c.getLabel()); } }
/** * 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()); } }
/** * Compute node congruence over the value number graph. * * <p>Algorithm: Muchnick pp. 348-355 * * <p>Note: the Muchnick algorithm is buggy. In particular, it does not put all needed congruence * classes on the worklist. * * <p>Two nodes in the value graph are congruent if one of the following holds: * * <ul> * <li>they are the same node * <li>their labels are identical constants * <li>they have the same operators and their operands are congruent * </ul> * * <p>Optimistic algorithm: * * <ul> * <li>Initially assume all nodes with the same label are congruent * <li>start a work list with all congruence classes that have multiple operands * <li>choose a congruence class from the worklist. partition its elements into new congruence * classes if we can discover that they are not congruent. * <li>Add any newly created congruence classes to the work list. * <li>(Here's the step Muchnick omits:) For each class C which has a dependence on any of the * newly created congruence classes, add C to the work list * <li>repeat until work list is empty * </ul> * * <p>The following method breaks Muchnick's algorithm, which will assign m and n the same value * number. Muchnick's problem is that it does not put the congruence class for 'int_mul' back on * the worklist when we discover, for example, that i is not congruent to k * * <pre> * public int foo(int a, int b, int c, int d, int e, int f, int g, int h) { * int i = a+b; * int j = c+d; * int k = e+f; * int l = g+h; * int m = i * j; * int n = k * l; * int o = m/n; * return o; * } * </pre> */ private void globalValueNumber() { if (DEBUG) { VM.sysWrite(valueGraph.toString()); } // initialize the congurence classes initialize(); // initialize the work list initializeWorkList(); // drain the work list while (!workList.empty()) { GVCongruenceClass partition = workList.pop(); partitionClass(partition); } // all done if (DEBUG) { printValueNumbers(); } }
GVCongruenceClass congruenceClass(Object name) { ValueGraphVertex v = valueGraph.getVertex(name); return 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 */ boolean DD(Object name1, Object name2) { ValueGraphVertex v1 = valueGraph.getVertex(name1); 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 */ boolean DS(Object name1, Object name2) { ValueGraphVertex v1 = valueGraph.getVertex(name1); ValueGraphVertex v2 = valueGraph.getVertex(name2); return v1.getValueNumber() == v2.getValueNumber(); }