Esempio n. 1
0
// Top-level driver to manage the queue of unassigned VirtRegs and call the
// selectOrSplit implementation.
void RegAllocBase::allocatePhysRegs() {
  seedLiveRegs();

  // Continue assigning vregs one at a time to available physical registers.
  while (LiveInterval *VirtReg = dequeue()) {
    assert(!VRM->hasPhys(VirtReg->reg) && "Register already assigned");

    // Unused registers can appear when the spiller coalesces snippets.
    if (MRI->reg_nodbg_empty(VirtReg->reg)) {
      DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n');
      LIS->removeInterval(VirtReg->reg);
      continue;
    }

    // Invalidate all interference queries, live ranges could have changed.
    invalidateVirtRegs();

    // selectOrSplit requests the allocator to return an available physical
    // register if possible and populate a list of new live intervals that
    // result from splitting.
    DEBUG(dbgs() << "\nselectOrSplit "
                 << MRI->getRegClass(VirtReg->reg)->getName()
                 << ':' << *VirtReg << '\n');
    typedef SmallVector<LiveInterval*, 4> VirtRegVec;
    VirtRegVec SplitVRegs;
    unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);

    if (AvailablePhysReg == ~0u) {
      // selectOrSplit failed to find a register!
      std::string msg;
      raw_string_ostream Msg(msg);
      Msg << "Ran out of registers during register allocation!"
             "\nCannot allocate: " << *VirtReg;
      for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(VirtReg->reg);
      MachineInstr *MI = I.skipInstruction();) {
        if (!MI->isInlineAsm())
          continue;
        Msg << "\nPlease check your inline asm statement for "
          "invalid constraints:\n";
        MI->print(Msg, &VRM->getMachineFunction().getTarget());
      }
      report_fatal_error(Msg.str());
    }

    if (AvailablePhysReg)
      assign(*VirtReg, AvailablePhysReg);

    for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
         I != E; ++I) {
      LiveInterval *SplitVirtReg = *I;
      assert(!VRM->hasPhys(SplitVirtReg->reg) && "Register already assigned");
      if (MRI->reg_nodbg_empty(SplitVirtReg->reg)) {
        DEBUG(dbgs() << "not queueing unused  " << *SplitVirtReg << '\n');
        LIS->removeInterval(SplitVirtReg->reg);
        continue;
      }
      DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
      assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
             "expect split value in virtual register");
      enqueue(SplitVirtReg);
      ++NumNewQueued;
    }
  }
}
Esempio n. 2
0
// Top-level driver to manage the queue of unassigned VirtRegs and call the
// selectOrSplit implementation.
void RegAllocBase::allocatePhysRegs() {
    seedLiveRegs();

    // Continue assigning vregs one at a time to available physical registers.
    while (LiveInterval *VirtReg = dequeue()) {
        assert(!VRM->hasPhys(VirtReg->reg) && "Register already assigned");

        // Unused registers can appear when the spiller coalesces snippets.
        if (MRI->reg_nodbg_empty(VirtReg->reg)) {
            DEBUG(dbgs() << "Dropping unused " << *VirtReg << '\n');
            LIS->removeInterval(VirtReg->reg);
            continue;
        }

        // Invalidate all interference queries, live ranges could have changed.
        invalidateVirtRegs();

        // selectOrSplit requests the allocator to return an available physical
        // register if possible and populate a list of new live intervals that
        // result from splitting.
        DEBUG(dbgs() << "\nselectOrSplit "
              << MRI->getRegClass(VirtReg->reg)->getName()
              << ':' << *VirtReg << '\n');
        typedef SmallVector<LiveInterval*, 4> VirtRegVec;
        VirtRegVec SplitVRegs;
        unsigned AvailablePhysReg = selectOrSplit(*VirtReg, SplitVRegs);

        if (AvailablePhysReg == ~0u) {
            // selectOrSplit failed to find a register!
            const char *Msg = "ran out of registers during register allocation";
            // Probably caused by an inline asm.
            MachineInstr *MI;
            for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(VirtReg->reg);
                    (MI = I.skipInstruction());)
                if (MI->isInlineAsm())
                    break;
            if (MI)
                MI->emitError(Msg);
            else
                report_fatal_error(Msg);
            // Keep going after reporting the error.
            VRM->assignVirt2Phys(VirtReg->reg,
                                 RegClassInfo.getOrder(MRI->getRegClass(VirtReg->reg)).front());
            continue;
        }

        if (AvailablePhysReg)
            assign(*VirtReg, AvailablePhysReg);

        for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
                I != E; ++I) {
            LiveInterval *SplitVirtReg = *I;
            assert(!VRM->hasPhys(SplitVirtReg->reg) && "Register already assigned");
            if (MRI->reg_nodbg_empty(SplitVirtReg->reg)) {
                DEBUG(dbgs() << "not queueing unused  " << *SplitVirtReg << '\n');
                LIS->removeInterval(SplitVirtReg->reg);
                continue;
            }
            DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
            assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
                   "expect split value in virtual register");
            enqueue(SplitVirtReg);
            ++NumNewQueued;
        }
    }
}