@Override public void replaceOperandWithSpillLocation(Instruction s, RegisterOperand symb) { // Get the spill location previously assigned to the symbolic // register. int location = regAllocState.getSpill(symb.getRegister()); // Create a memory operand M representing the spill location. int size; if (VM.BuildFor32Addr) { if (SSE2_FULL) { size = symb.getType().getMemoryBytes(); if (size < WORDSIZE) size = WORDSIZE; } else { int type = PhysicalRegisterSet.getPhysicalRegisterType(symb.getRegister()); size = getSpillSize(type); } } else { if (VM.BuildFor64Addr && symb.getType().getMemoryBytes() <= BYTES_IN_INT) { // Int-like types and floats need 32-bit locations size = BYTES_IN_INT; } else { size = WORDSIZE; } } StackLocationOperand M = new StackLocationOperand(true, -location, (byte) size); if (VERBOSE_DEBUG) { System.out.println("REPLACE_OP_WITH_SPILL_LOC: " + "Instruction before replacement: " + s); } // replace the register operand with the memory operand s.replaceOperand(symb, M); if (VERBOSE_DEBUG) { System.out.println("REPLACE_OP_WITH_SPILL_LOC: " + "Instruction after replacement: " + s); } }
/** * For each in a set of instructions, rewrite every def to use a new temporary register. If a * rewritten def is subsequently used, then use the new temporary register instead. */ private void rewriteWithTemporaries(Instruction[] set, IR ir) { // Maintain a mapping holding the new name for each register HashMap<Register, Register> map = new HashMap<Register, Register>(); for (Instruction s : set) { // rewrite the uses to use the new names for (Enumeration<Operand> e = s.getUses(); e.hasMoreElements(); ) { Operand use = e.nextElement(); if (use != null && use.isRegister()) { Register r = use.asRegister().getRegister(); Register temp = map.get(r); if (temp != null) { use.asRegister().setRegister(temp); } } } if (VM.VerifyAssertions) VM._assert(s.getNumberOfDefs() == 1); Operand def = s.getDefs().nextElement(); RegisterOperand rDef = def.asRegister(); RegisterOperand temp = ir.regpool.makeTemp(rDef); map.put(rDef.getRegister(), temp.getRegister()); s.replaceOperand(def, temp); } }
/** * Walks through the IR. For each StackLocationOperand, replace the operand with the appropriate * MemoryOperand. */ private void rewriteStackLocations() { // ESP is initially WORDSIZE above where the framepointer is going to be. ESPOffset = getFrameFixedSize() + WORDSIZE; Register ESP = ((PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet()).getESP(); boolean seenReturn = false; for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) { Instruction s = e.nextElement(); if (s.isReturn()) { seenReturn = true; continue; } if (s.isBranch()) { // restore ESP to home location at end of basic block. moveESPBefore(s, 0); continue; } if (s.operator() == BBEND) { if (seenReturn) { // at a return ESP will be at FrameFixedSize, seenReturn = false; ESPOffset = 0; } else { moveESPBefore(s, 0); } continue; } if (s.operator() == ADVISE_ESP) { ESPOffset = MIR_UnaryNoRes.getVal(s).asIntConstant().value; continue; } if (s.operator() == REQUIRE_ESP) { // ESP is required to be at the given offset from the bottom of the frame moveESPBefore(s, MIR_UnaryNoRes.getVal(s).asIntConstant().value); continue; } if (s.operator() == YIELDPOINT_PROLOGUE || s.operator() == YIELDPOINT_BACKEDGE || s.operator() == YIELDPOINT_EPILOGUE) { moveESPBefore(s, 0); continue; } if (s.operator() == IA32_MOV) { rewriteMoveInstruction(s); } // pop computes the effective address of its operand after ESP // is incremented. Therefore update ESPOffset before rewriting // stacklocation and memory operands. if (s.operator() == IA32_POP) { ESPOffset += WORDSIZE; } for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) { Operand op = ops.nextElement(); if (op instanceof StackLocationOperand) { StackLocationOperand sop = (StackLocationOperand) op; int offset = sop.getOffset(); if (sop.isFromTop()) { offset = FPOffset2SPOffset(offset); } offset -= ESPOffset; byte size = sop.getSize(); MemoryOperand M = MemoryOperand.BD( new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(offset), size, null, null); s.replaceOperand(op, M); } else if (op instanceof MemoryOperand) { MemoryOperand M = op.asMemory(); if ((M.base != null && M.base.getRegister() == ESP) || (M.index != null && M.index.getRegister() == ESP)) { M.disp = M.disp.minus(ESPOffset); } } } // push computes the effective address of its operand after ESP // is decremented. Therefore update ESPOffset after rewriting // stacklocation and memory operands. if (s.operator() == IA32_PUSH) { ESPOffset -= WORDSIZE; } } }