/** * Attempt to coalesce register r2 into register r1. If this is legal, * * <ul> * <li>rewrite all defs and uses of r2 as defs and uses of r1 * <li>update the liveness information * <li>update the def-use chains * </ul> * * <strong>PRECONDITION </strong> def-use chains must be computed and valid. <strong>PRECONDITION * </strong> instructions are numbered, with numbers stored in OPT_Instruction.scratch * * @param ir the governing IR * @param live liveness information for the IR * @param r1 * @param r2 * @return true if the transformation succeeded, false otherwise. */ public static boolean attempt( OPT_IR ir, OPT_LiveAnalysis live, OPT_Register r1, OPT_Register r2) { // make sure r1 and r2 are not simultaneously live if (isLiveAtDef(r2, r1, live)) return false; if (isLiveAtDef(r1, r2, live)) return false; // Liveness is OK. Check for SPLIT operations if (split(r1, r2)) return false; // Don't merge a register with itself if (r1 == r2) return false; // Update liveness information to reflect the merge. live.merge(r1, r2); // Merge the defs. for (OPT_RegisterOperandEnumeration e = OPT_DefUse.defs(r2); e.hasMoreElements(); ) { OPT_RegisterOperand def = (OPT_RegisterOperand) e.nextElement(); OPT_DefUse.removeDef(def); def.register = r1; OPT_DefUse.recordDef(def); } // Merge the uses. for (OPT_RegisterOperandEnumeration e = OPT_DefUse.uses(r2); e.hasMoreElements(); ) { OPT_RegisterOperand use = (OPT_RegisterOperand) e.nextElement(); OPT_DefUse.removeUse(use); use.register = r1; OPT_DefUse.recordUse(use); } return true; }