/** * Perform scalar replacement actions for a Def of a heap variable. NOTE: Even loads can def a * heap variable. * * @param UseRepSet stores the uses(loads) that have been eliminated * @param registers mapping from valueNumber -> temporary register */ static void replaceDefs(IR ir, UseRecordSet UseRepSet, HashMap<UseRecord, Register> registers) { SSADictionary ssa = ir.HIRInfo.dictionary; for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) { Instruction s = e.nextElement(); if (!GetField.conforms(s) && !GetStatic.conforms(s) && !PutField.conforms(s) && !PutStatic.conforms(s) && !ALoad.conforms(s) && !AStore.conforms(s)) { continue; } if (!ssa.defsHeapVariable(s)) { continue; } // this instruction is a DEF of heap variable H. // Check if UseRepSet needs the scalar assigned by this def HeapOperand<?>[] H = ssa.getHeapDefs(s); if (H.length != 1) { throw new OptimizingCompilerException( "LoadElimination: encountered a store with more than one def? " + s); } int valueNumber = -1; Object index = null; if (AStore.conforms(s)) { Object address = AStore.getArray(s); index = AStore.getIndex(s); valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address); } else if (GetField.conforms(s)) { Object address = GetField.getRef(s); valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address); } else if (PutField.conforms(s)) { Object address = PutField.getRef(s); valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address); } else if (GetStatic.conforms(s)) { valueNumber = 0; } else if (PutStatic.conforms(s)) { valueNumber = 0; } else if (ALoad.conforms(s)) { Object address = ALoad.getArray(s); valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address); index = ALoad.getIndex(s); } if (index == null) { // Load/Store if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), valueNumber)) { Operand value = null; if (PutField.conforms(s)) { value = PutField.getValue(s); } else if (PutStatic.conforms(s)) { value = PutStatic.getValue(s); } else if (GetField.conforms(s) || GetStatic.conforms(s)) { value = ResultCarrier.getResult(s); } TypeReference type = value.getType(); Register r = findOrCreateRegister(H[0].getHeapType(), valueNumber, registers, ir.regpool, type); appendMove(r, value, s); } } else { // ALoad / AStore int v1 = valueNumber; int v2 = ir.HIRInfo.valueNumbers.getValueNumber(index); if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), v1, v2)) { Operand value = null; if (AStore.conforms(s)) { value = AStore.getValue(s); } else if (ALoad.conforms(s)) { value = ALoad.getResult(s); } TypeReference type = value.getType(); Register r = findOrCreateRegister(H[0].getHeapType(), v1, v2, registers, ir.regpool, type); appendMove(r, value, s); } } } }
/** * Update the value graph to account for a given PUTFIELD instruction. * * <p><b>PRECONDITION:</b> <code> PutField.conforms(s); </code> Make sure we have value graph * nodes for a constant value * * @param s the instruction in question */ private void processPutField(Instruction s) { Operand value = PutField.getValue(s); if (value.isConstant()) { findOrCreateVertex((ConstantOperand) value); } }