Skip to content
VirtRegMap.cpp 45.8 KiB
Newer Older
      // If the spill slot value is available, and this is a new definition of
      // the value, the value is not available anymore.
      if (MR & VirtRegMap::isMod) {
        // Notice that the value in this stack slot has been modified.
        
        // If this is *just* a mod of the value, check to see if this is just a
        // store to the spill slot (i.e. the spill got merged into the copy). If
        // so, realize that the vreg is available now, and add the store to the
        // MaybeDeadStore info.
        int StackSlot;
        if (!(MR & VirtRegMap::isRef)) {
          if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) {
            assert(MRegisterInfo::isPhysicalRegister(SrcReg) &&
                   "Src hasn't been allocated yet?");
            // Okay, this is certainly a store of SrcReg to [StackSlot].  Mark
            // this as a potentially dead store in case there is a subsequent
            // store into the stack slot without a read from it.
            MaybeDeadStores[StackSlot] = &MI;

            // If the stack slot value was previously available in some other
            // register, change it now.  Otherwise, make the register available,
            // in PhysReg.
            Spills.addAvailable(StackSlot, &MI, SrcReg, false/*don't clobber*/);
    // Process all of the spilled defs.
    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
      MachineOperand &MO = MI.getOperand(i);
      if (MO.isRegister() && MO.getReg() && MO.isDef()) {
        unsigned VirtReg = MO.getReg();

        if (!MRegisterInfo::isVirtualRegister(VirtReg)) {
          // Check to see if this is a noop copy.  If so, eliminate the
          // instruction before considering the dest reg to be changed.
          unsigned Src, Dst;
          if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
            ++NumDCE;
            DOUT << "Removing now-noop copy: " << MI;
            Spills.removeLastUse(Src, &MI);
            MBB.erase(&MI);
            VRM.RemoveFromFoldedVirtMap(&MI);
            Spills.disallowClobberPhysReg(VirtReg);
          
          // If it's not a no-op copy, it clobbers the value in the destreg.
          ReusedOperands.markClobbered(VirtReg);
 
          // Check to see if this instruction is a load from a stack slot into
          // a register.  If so, this provides the stack slot value in the reg.
          int FrameIdx;
          if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) {
            assert(DestReg == VirtReg && "Unknown load situation!");
            
            // Otherwise, if it wasn't available, remember that it is now!
            Spills.addAvailable(FrameIdx, &MI, DestReg);
Chris Lattner's avatar
Chris Lattner committed
        // The only vregs left are stack slot definitions.
        int StackSlot = VRM.getStackSlot(VirtReg);
        const TargetRegisterClass *RC =
          MBB.getParent()->getSSARegMap()->getRegClass(VirtReg);

        // If this def is part of a two-address operand, make sure to execute
        // the store from the correct physical register.
        unsigned PhysReg;
        int TiedOp = MI.getInstrDescriptor()->findTiedToSrcOperand(i);
        if (TiedOp != -1)
          PhysReg = MI.getOperand(TiedOp).getReg();
          if (ReusedOperands.isClobbered(PhysReg)) {
            // Another def has taken the assigned physreg. It must have been a
            // use&def which got it due to reuse. Undo the reuse!
            PhysReg = ReusedOperands.GetRegForReload(PhysReg, &MI, 
                                                     Spills, MaybeDeadStores);
          }
        }
Chris Lattner's avatar
Chris Lattner committed

        PhysRegsUsed[PhysReg] = true;
        ReusedOperands.markClobbered(PhysReg);
Chris Lattner's avatar
Chris Lattner committed
        MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC);
        DOUT << "Store:\t" << *next(MII);
        MI.getOperand(i).setReg(PhysReg);
Chris Lattner's avatar
Chris Lattner committed

        // If there is a dead store to this stack slot, nuke it now.
        MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
        if (LastStore) {
          DOUT << "Removed dead store:\t" << *LastStore;
Chris Lattner's avatar
Chris Lattner committed
          ++NumDSE;
          MBB.erase(LastStore);
          VRM.RemoveFromFoldedVirtMap(LastStore);
Chris Lattner's avatar
Chris Lattner committed
        LastStore = next(MII);

        // If the stack slot value was previously available in some other
        // register, change it now.  Otherwise, make the register available,
        // in PhysReg.
        Spills.ModifyStackSlot(StackSlot);
        Spills.ClobberPhysReg(PhysReg);
        Spills.addAvailable(StackSlot, LastStore, PhysReg);
Chris Lattner's avatar
Chris Lattner committed
        ++NumStores;

        // Check to see if this is a noop copy.  If so, eliminate the
        // instruction before considering the dest reg to be changed.
        {
          unsigned Src, Dst;
          if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
            ++NumDCE;
            DOUT << "Removing now-noop copy: " << MI;
            MBB.erase(&MI);
            VRM.RemoveFromFoldedVirtMap(&MI);
            goto ProcessNextInst;
          }
        }        
llvm::Spiller* llvm::createSpiller() {
  switch (SpillerOpt) {
  default: assert(0 && "Unreachable!");
  case local:
    return new LocalSpiller();
  case simple:
    return new SimpleSpiller();
  }