Пример #1
0
void LinearScan::allocRegs(Trace* trace) {
  if (RuntimeOption::EvalHHIREnableCoalescing) {
    // <coalesce> doesn't need instruction numbering.
    coalesce(trace);
  }

  numberInstructions(trace);

  collectNatives(trace);
  computePreColoringHint();
  initFreeList();
  allocRegsToTraceAux(trace);
  // Renumber instructions, because we added spills and reloads.
  numberInstructions(trace);

  if (RuntimeOption::EvalHHIREnableRematerialization && m_slots.size() > 0) {
    // Don't bother rematerializing the trace if it has no Spill/Reload.
    if (RuntimeOption::EvalDumpIR > 5) {
      std::cout << "--------- HHIR before rematerialization ---------\n";
      trace->print(std::cout, false);
      std::cout << "-------------------------------------------------\n";
    }
    rematerialize(trace);
  }

  // assignSpillLoc needs next natives in order to decide whether we
  // can use MMX registers.
  collectNatives(trace);
  // Make sure rsp is 16-aligned.
  uint32 numSpillLocs = assignSpillLoc(trace);
  if (numSpillLocs % 2) {
    ++numSpillLocs;
  }
  assert(NumPreAllocatedSpillLocs % 2 == 0);
  if (numSpillLocs > 0) {
    preAllocSpillLoc(trace, numSpillLocs);
    if (numSpillLocs > (uint32)NumPreAllocatedSpillLocs) {
      /*
       * We only insert AllocSpill and FreeSpill when the pre-allocated
       * spill locations are not enough.
       *
       * AllocSpill and FreeSpill take the number of extra spill locations
       * besides the pre-allocated ones.
       *
       * TODO(#2044051) AllocSpill/FreeSpill are currently disabled
       * due to bugs.
       */
      PUNT(LinearScan_AllocSpill);
      insertAllocFreeSpill(trace, numSpillLocs - NumPreAllocatedSpillLocs);
    }
  }
  numberInstructions(trace);

  // record the live out register set at each instruction
  LinearScan::computeLiveOutRegs(trace);
}
Пример #2
0
void LinearScan::allocRegsToTraceAux(Trace* trace) {
  IRInstruction::List& instructionList = trace->getInstructionList();
  IRInstruction::Iterator it;
  for (it = instructionList.begin();
       it != instructionList.end();
       it++) {
    IRInstruction* inst = *it;
    allocRegToInstruction(trace, it);
    if (RuntimeOption::EvalDumpIR > 3) {
      std::cout << "--- allocated to instruction: ";
      inst->print(std::cout);
      std::cout << "\n";
    }
    if (inst->isControlFlowInstruction()) {
      // This instruction may transfer control to another trace
      // If this is the last instruction in the trace that can branch
      // to this target trace, then allocate registers to the target
      // trace, effectively linearizing the target trace after inst.
      LabelInstruction* label = inst->getLabel();
      if (label != NULL && label->getId() == inst->getId() + 1) {
        allocRegsToTraceAux(label->getTrace());
      }
    }
  }

  // Insert spill instructions.
  // Reload instructions are already added in <allocRegsToTrace>.
  for (it = instructionList.begin(); it != instructionList.end(); ) {
    IRInstruction::Iterator next = it; ++next;
    IRInstruction* inst = *it;
    if (inst->getOpcode() != Reload) {
      // Reloaded SSATmps needn't be spilled again.
      if (SSATmp* dst = inst->getDst()) {
        int32 slotId = dst->getSpillSlot();
        if (slotId != -1) {
          // If this instruction is marked to be spilled,
          // add a spill right afterwards.
          IRInstruction* spillInst =
            m_slots[slotId].m_slotTmp->getInstruction();
          instructionList.insert(next, spillInst);
          spillInst->setParent(trace);
        }
      }
    }
    it = next;
  }
}