Exemplo n.º 1
0
  @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);
    }
  }
Exemplo n.º 3
0
  /**
   * 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;
      }
    }
  }