use.instruction.putOperand(index, rhs);
use.instruction.putOperand(index, rhs.copy());
  static void copyPropagation (OPT_IR ir) {    // Use register list to enumerate register objects     OPT_Register elemNext;    boolean reiterate = true;    while (reiterate) {         // /MT/ better think about proper ordering.      reiterate = false;      instructions:       for (OPT_Register reg = ir.regpool.getFirstSymbolicRegister();            reg != null; reg = elemNext) {        elemNext = reg.getNext(); // we may remove reg, so get elemNext up front        if (reg.useList == null ||   // Copy propagation not possible if reg                                      // has no uses            reg.defList == null ||   // Copy propagation not possible if reg                                      // has no defs            !reg.isSSA())            // Flow-insensitive copy prop only possible                                      // for SSA registers.          continue;        // isSSA => reg has exactly one definition, reg.defList.        OPT_RegisterOperand lhs = reg.defList;        OPT_Instruction defInstr = lhs.instruction;        OPT_Operand rhs;        // Copy/constant propagation only possible when defInstr is a move        if (defInstr.isMove()) {          rhs = Move.getVal(defInstr);        } else if (defInstr.operator() == PHI) {          OPT_Operand phiVal = equivalentValforPHI (defInstr);          if (phiVal == null)  continue  instructions;          rhs = phiVal;        } else {          continue  instructions;        }        if (rhs.isRegister()) {          OPT_Register rrhs = rhs.asRegister().register;          // If rhs is a non-SSA register, then we can't propagate it          // because we can't be sure that the same definition reaches           // all uses.          if (!rrhs.isSSA()) continue;          // If rhs is a physical register, then we can't safely propagate          // it to uses of lhs because we don't understand the implicit          // uses/defs of physical registers well enough to do so safely.          if (rrhs.isPhysical()) continue;        }                reiterate = ir.options.getOptLevel() > 1;        // Now substitute rhs for all uses of lhs, updating the         // register list as we go.        if (rhs.isRegister()) {          OPT_RegisterOperand nextUse;          OPT_RegisterOperand rhsRegOp = rhs.asRegister();          for (OPT_RegisterOperand use = reg.useList; use != null; use = nextUse) {            nextUse = use.getNext(); // get early before reg's useList is updated.             if (VM.VerifyAssertions) VM._assert(rhsRegOp.register.getType() == use.register.getType());            OPT_DefUse.transferUse(use, rhsRegOp);          }        } else if (rhs.isConstant()) {          // NOTE: no need to incrementally update use's register list since we are going          //       to blow it all away as soon as this loop is done.          for (OPT_RegisterOperand use = reg.useList; use != null; use = use.getNext()) {            int index = use.getIndexInInstruction();            use.instruction.putOperand(index, rhs);          }        } else {          throw new OPT_OptimizingCompilerException("OPT_Simple.copyPropagation: unexpected operand type");        }        // defInstr is now dead. Remove it.        defInstr.remove();        if (rhs.isRegister())          OPT_DefUse.removeUse(rhs.asRegister());        ir.regpool.removeRegister(lhs.register);      }    }  }