//===-- llvm/CodeGen/VirtRegMap.cpp - Virtual Register Map ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the VirtRegMap class.
//
// It also contains implementations of the the Spiller interface, which, given a
// virtual register map and a machine function, eliminates all virtual
// references by replacing them with physical register references - adding spill
// code as necessary.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "spiller"
#include "VirtRegMap.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
using namespace llvm;

namespace {
  Statistic<> NumSpills("spiller", "Number of register spills");
  Statistic<> NumStores("spiller", "Number of stores added");
  Statistic<> NumLoads ("spiller", "Number of loads added");
  Statistic<> NumReused("spiller", "Number of values reused");
  Statistic<> NumDSE   ("spiller", "Number of dead stores elided");

  enum SpillerName { simple, local };

  cl::opt<SpillerName>
  SpillerOpt("spiller",
             cl::desc("Spiller to use: (default: local)"),
             cl::Prefix,
             cl::values(clEnumVal(simple, "  simple spiller"),
                        clEnumVal(local,  "  local spiller"),
                        clEnumValEnd),
             cl::init(local));
}

//===----------------------------------------------------------------------===//
//  VirtRegMap implementation
//===----------------------------------------------------------------------===//

void VirtRegMap::grow() {
  Virt2PhysMap.grow(MF.getSSARegMap()->getLastVirtReg());
  Virt2StackSlotMap.grow(MF.getSSARegMap()->getLastVirtReg());
}

int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) {
  assert(MRegisterInfo::isVirtualRegister(virtReg));
  assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
         "attempt to assign stack slot to already spilled register");
  const TargetRegisterClass* RC = MF.getSSARegMap()->getRegClass(virtReg);
  int frameIndex = MF.getFrameInfo()->CreateStackObject(RC->getSize(),
                                                        RC->getAlignment());
  Virt2StackSlotMap[virtReg] = frameIndex;
  ++NumSpills;
  return frameIndex;
}

void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int frameIndex) {
  assert(MRegisterInfo::isVirtualRegister(virtReg));
  assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT &&
         "attempt to assign stack slot to already spilled register");
  Virt2StackSlotMap[virtReg] = frameIndex;
}

void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI,
                            unsigned OpNo, MachineInstr *NewMI) {
  // Move previous memory references folded to new instruction.
  MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(NewMI);
  for (MI2VirtMapTy::iterator I = MI2VirtMap.lower_bound(OldMI), 
         E = MI2VirtMap.end(); I != E && I->first == OldMI; ) {
    MI2VirtMap.insert(IP, std::make_pair(NewMI, I->second));
    MI2VirtMap.erase(I++);
  }

  ModRef MRInfo;
  if (!OldMI->getOperand(OpNo).isDef()) {
    assert(OldMI->getOperand(OpNo).isUse() && "Operand is not use or def?");
    MRInfo = isRef;
  } else {
    MRInfo = OldMI->getOperand(OpNo).isUse() ? isModRef : isMod;
  }

  // add new memory reference
  MI2VirtMap.insert(IP, std::make_pair(NewMI, std::make_pair(VirtReg, MRInfo)));
}

void VirtRegMap::print(std::ostream &OS) const {
  const MRegisterInfo* MRI = MF.getTarget().getRegisterInfo();

  OS << "********** REGISTER MAP **********\n";
  for (unsigned i = MRegisterInfo::FirstVirtualRegister,
         e = MF.getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
    if (Virt2PhysMap[i] != (unsigned)VirtRegMap::NO_PHYS_REG)
      OS << "[reg" << i << " -> " << MRI->getName(Virt2PhysMap[i]) << "]\n";
         
  }

  for (unsigned i = MRegisterInfo::FirstVirtualRegister,
         e = MF.getSSARegMap()->getLastVirtReg(); i <= e; ++i)
    if (Virt2StackSlotMap[i] != VirtRegMap::NO_STACK_SLOT)
      OS << "[reg" << i << " -> fi#" << Virt2StackSlotMap[i] << "]\n";
  OS << '\n';
}

void VirtRegMap::dump() const { print(std::cerr); }


//===----------------------------------------------------------------------===//
// Simple Spiller Implementation
//===----------------------------------------------------------------------===//

Spiller::~Spiller() {}

namespace {
  struct SimpleSpiller : public Spiller {
    bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap &VRM);
  };
}

bool SimpleSpiller::runOnMachineFunction(MachineFunction &MF,
                                         const VirtRegMap &VRM) {
  DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
  DEBUG(std::cerr << "********** Function: "
                  << MF.getFunction()->getName() << '\n');
  const TargetMachine &TM = MF.getTarget();
  const MRegisterInfo &MRI = *TM.getRegisterInfo();
  bool *PhysRegsUsed = MF.getUsedPhysregs();

  // LoadedRegs - Keep track of which vregs are loaded, so that we only load
  // each vreg once (in the case where a spilled vreg is used by multiple
  // operands).  This is always smaller than the number of operands to the
  // current machine instr, so it should be small.
  std::vector<unsigned> LoadedRegs;

  for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
       MBBI != E; ++MBBI) {
    DEBUG(std::cerr << MBBI->getBasicBlock()->getName() << ":\n");
    MachineBasicBlock &MBB = *MBBI;
    for (MachineBasicBlock::iterator MII = MBB.begin(),
           E = MBB.end(); MII != E; ++MII) {
      MachineInstr &MI = *MII;
      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
        MachineOperand &MO = MI.getOperand(i);
        if (MO.isRegister() && MO.getReg() &&
            MRegisterInfo::isVirtualRegister(MO.getReg())) {
          unsigned VirtReg = MO.getReg();
          unsigned PhysReg = VRM.getPhys(VirtReg);
          if (VRM.hasStackSlot(VirtReg)) {
            int StackSlot = VRM.getStackSlot(VirtReg);

            if (MO.isUse() &&
                std::find(LoadedRegs.begin(), LoadedRegs.end(), VirtReg)
                           == LoadedRegs.end()) {
              MRI.loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot);
              LoadedRegs.push_back(VirtReg);
              ++NumLoads;
              DEBUG(std::cerr << '\t' << *prior(MII));
            }

            if (MO.isDef()) {
              MRI.storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot);
              ++NumStores;
            }
          }
          PhysRegsUsed[PhysReg] = true;
          MI.SetMachineOperandReg(i, PhysReg);
        }
      }
      DEBUG(std::cerr << '\t' << MI);
      LoadedRegs.clear();
    }
  }
  return true;
}

//===----------------------------------------------------------------------===//
//  Local Spiller Implementation
//===----------------------------------------------------------------------===//

namespace {
  /// LocalSpiller - This spiller does a simple pass over the machine basic
  /// block to attempt to keep spills in registers as much as possible for
  /// blocks that have low register pressure (the vreg may be spilled due to
  /// register pressure in other blocks).
  class LocalSpiller : public Spiller {
    const MRegisterInfo *MRI;
    const TargetInstrInfo *TII;
  public:
    bool runOnMachineFunction(MachineFunction &MF, const VirtRegMap &VRM) {
      MRI = MF.getTarget().getRegisterInfo();
      TII = MF.getTarget().getInstrInfo();
      DEBUG(std::cerr << "\n**** Local spiller rewriting function '"
                      << MF.getFunction()->getName() << "':\n");

      for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
           MBB != E; ++MBB)
        RewriteMBB(*MBB, VRM);
      return true;
    }
  private:
    void RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM);
    void ClobberPhysReg(unsigned PR, std::map<int, unsigned> &SpillSlots,
                        std::map<unsigned, int> &PhysRegs);
    void ClobberPhysRegOnly(unsigned PR, std::map<int, unsigned> &SpillSlots,
                            std::map<unsigned, int> &PhysRegs);
  };
}

void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg,
                                      std::map<int, unsigned> &SpillSlots,
                                      std::map<unsigned, int> &PhysRegs) {
  std::map<unsigned, int>::iterator I = PhysRegs.find(PhysReg);
  if (I != PhysRegs.end()) {
    int Slot = I->second;
    PhysRegs.erase(I);
    assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!");
    SpillSlots.erase(Slot);
    DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg)
          << " clobbered, invalidating SS#" << Slot << "\n");

  }
}

void LocalSpiller::ClobberPhysReg(unsigned PhysReg,
                                  std::map<int, unsigned> &SpillSlots,
                                  std::map<unsigned, int> &PhysRegs) {
  for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS)
    ClobberPhysRegOnly(*AS, SpillSlots, PhysRegs);
  ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegs);
}


// ReusedOp - For each reused operand, we keep track of a bit of information, in
// case we need to rollback upon processing a new operand.  See comments below.
namespace {
  struct ReusedOp {
    // The MachineInstr operand that reused an available value.
    unsigned Operand;
    
    // StackSlot - The spill slot of the value being reused.
    unsigned StackSlot;
    
    // PhysRegReused - The physical register the value was available in.
    unsigned PhysRegReused;
    
    // AssignedPhysReg - The physreg that was assigned for use by the reload.
    unsigned AssignedPhysReg;
    
    ReusedOp(unsigned o, unsigned ss, unsigned prr, unsigned apr)
      : Operand(o), StackSlot(ss), PhysRegReused(prr), AssignedPhysReg(apr) {}
  };
}


/// rewriteMBB - Keep track of which spills are available even after the
/// register allocator is done with them.  If possible, avoid reloading vregs.
void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {

  // SpillSlotsAvailable - This map keeps track of all of the spilled virtual
  // register values that are still available, due to being loaded to stored to,
  // but not invalidated yet.
  std::map<int, unsigned> SpillSlotsAvailable;

  // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating
  // which physregs are in use holding a stack slot value.
  std::map<unsigned, int> PhysRegsAvailable;

  DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n");

  std::vector<ReusedOp> ReusedOperands;

  // DefAndUseVReg - When we see a def&use operand that is spilled, keep track
  // of it.  ".first" is the machine operand index (should always be 0 for now),
  // and ".second" is the virtual register that is spilled.
  std::vector<std::pair<unsigned, unsigned> > DefAndUseVReg;

  // MaybeDeadStores - When we need to write a value back into a stack slot,
  // keep track of the inserted store.  If the stack slot value is never read
  // (because the value was used from some available register, for example), and
  // subsequently stored to, the original store is dead.  This map keeps track
  // of inserted stores that are not used.  If we see a subsequent store to the
  // same stack slot, the original store is deleted.
  std::map<int, MachineInstr*> MaybeDeadStores;

  bool *PhysRegsUsed = MBB.getParent()->getUsedPhysregs();

  for (MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
       MII != E; ) {
    MachineInstr &MI = *MII;
    MachineBasicBlock::iterator NextMII = MII; ++NextMII;

    ReusedOperands.clear();
    DefAndUseVReg.clear();

    // Process all of the spilled uses and all non spilled reg references.
    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
      MachineOperand &MO = MI.getOperand(i);
      if (MO.isRegister() && MO.getReg() &&
          MRegisterInfo::isVirtualRegister(MO.getReg())) {
        unsigned VirtReg = MO.getReg();

        if (!VRM.hasStackSlot(VirtReg)) {
          // This virtual register was assigned a physreg!
          unsigned Phys = VRM.getPhys(VirtReg);
          PhysRegsUsed[Phys] = true;
          MI.SetMachineOperandReg(i, Phys);
        } else {
          // Is this virtual register a spilled value?
          if (MO.isUse()) {
            int StackSlot = VRM.getStackSlot(VirtReg);
            unsigned PhysReg;

            // Check to see if this stack slot is available.
            std::map<int, unsigned>::iterator SSI =
              SpillSlotsAvailable.find(StackSlot);
            if (SSI != SpillSlotsAvailable.end()) {
              DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg "
                              << MRI->getName(SSI->second) << " for vreg"
                              << VirtReg <<" instead of reloading into physreg "
                              << MRI->getName(VRM.getPhys(VirtReg)) << "\n");
              // If this stack slot value is already available, reuse it!
              PhysReg = SSI->second;
              MI.SetMachineOperandReg(i, PhysReg);

              // The only technical detail we have is that we don't know that
              // PhysReg won't be clobbered by a reloaded stack slot that occurs
              // later in the instruction.  In particular, consider 'op V1, V2'.
              // If V1 is available in physreg R0, we would choose to reuse it
              // here, instead of reloading it into the register the allocator
              // indicated (say R1).  However, V2 might have to be reloaded
              // later, and it might indicate that it needs to live in R0.  When
              // this occurs, we need to have information available that
              // indicates it is safe to use R1 for the reload instead of R0.
              //
              // To further complicate matters, we might conflict with an alias,
              // or R0 and R1 might not be compatible with each other.  In this
              // case, we actually insert a reload for V1 in R1, ensuring that
              // we can get at R0 or its alias.
              ReusedOperands.push_back(ReusedOp(i, StackSlot, PhysReg,
                                                VRM.getPhys(VirtReg)));
              ++NumReused;
            } else {
              // Otherwise, reload it and remember that we have it.
              PhysReg = VRM.getPhys(VirtReg);

            RecheckRegister:
              // Note that, if we reused a register for a previous operand, the
              // register we want to reload into might not actually be
              // available.  If this occurs, use the register indicated by the
              // reuser.
              if (!ReusedOperands.empty())   // This is most often empty.
                for (unsigned ro = 0, e = ReusedOperands.size(); ro != e; ++ro)
                  if (ReusedOperands[ro].PhysRegReused == PhysReg) {
                    // Yup, use the reload register that we didn't use before.
                    PhysReg = ReusedOperands[ro].AssignedPhysReg;
                    goto RecheckRegister;
                  } else {
                    ReusedOp &Op = ReusedOperands[ro];
                    unsigned PRRU = Op.PhysRegReused;
                    for (const unsigned *AS = MRI->getAliasSet(PRRU); *AS; ++AS)
                      if (*AS == PhysReg) {
                        // Okay, we found out that an alias of a reused register
                        // was used.  This isn't good because it means we have
                        // to undo a previous reuse.
                        MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, 
                                                  Op.StackSlot);
                        ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable,
                                       PhysRegsAvailable);

                        // Any stores to this stack slot are not dead anymore.
                        MaybeDeadStores.erase(Op.StackSlot);

                        MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg);
                        PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot;
                        SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg;
                        PhysRegsAvailable.erase(Op.PhysRegReused);
                        DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot
                              << " in physreg "
                              << MRI->getName(Op.AssignedPhysReg) << "\n");
                        ++NumLoads;
                        DEBUG(std::cerr << '\t' << *prior(MII));

                        DEBUG(std::cerr << "Reuse undone!\n");
                        ReusedOperands.erase(ReusedOperands.begin()+ro);
                        --NumReused;
                        goto ContinueReload;
                      }
                  }
            ContinueReload:
              PhysRegsUsed[PhysReg] = true;
              MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot);
              // This invalidates PhysReg.
              ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);

              // Any stores to this stack slot are not dead anymore.
              MaybeDeadStores.erase(StackSlot);

              MI.SetMachineOperandReg(i, PhysReg);
              PhysRegsAvailable[PhysReg] = StackSlot;
              SpillSlotsAvailable[StackSlot] = PhysReg;
              DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg "
                              << MRI->getName(PhysReg) << "\n");
              ++NumLoads;
              DEBUG(std::cerr << '\t' << *prior(MII));
            }

            // If this is both a def and a use, we need to emit a store to the
            // stack slot after the instruction.  Keep track of D&U operands
            // because we already changed it to a physreg here.
            if (MO.isDef()) {
              // Remember that this was a def-and-use operand, and that the
              // stack slot is live after this instruction executes.
              DefAndUseVReg.push_back(std::make_pair(i, VirtReg));
            }
          }
        }
      }
    }

    // Loop over all of the implicit defs, clearing them from our available
    // sets.
    for (const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode());
         *ImpDef; ++ImpDef) {
      PhysRegsUsed[*ImpDef] = true;
      ClobberPhysReg(*ImpDef, SpillSlotsAvailable, PhysRegsAvailable);
    }

    DEBUG(std::cerr << '\t' << MI);

    // If we have folded references to memory operands, make sure we clear all
    // physical registers that may contain the value of the spilled virtual
    // register
    VirtRegMap::MI2VirtMapTy::const_iterator I, End;
    for (tie(I, End) = VRM.getFoldedVirts(&MI); I != End; ++I) {
      DEBUG(std::cerr << "Folded vreg: " << I->second.first << "  MR: "
                      << I->second.second);
      unsigned VirtReg = I->second.first;
      VirtRegMap::ModRef MR = I->second.second;
      if (VRM.hasStackSlot(VirtReg)) {
        int SS = VRM.getStackSlot(VirtReg);
        DEBUG(std::cerr << " - StackSlot: " << SS << "\n");

        // If this reference is not a use, any previous store is now dead.
        // Otherwise, the store to this stack slot is not dead anymore.
        std::map<int, MachineInstr*>::iterator MDSI = MaybeDeadStores.find(SS);
        if (MDSI != MaybeDeadStores.end()) {
          if (MR & VirtRegMap::isRef)   // Previous store is not dead.
            MaybeDeadStores.erase(MDSI);
          else {
            // If we get here, the store is dead, nuke it now.
            assert(MR == VirtRegMap::isMod && "Can't be modref!");
            MBB.erase(MDSI->second);
            MaybeDeadStores.erase(MDSI);
            ++NumDSE;
          }
        }

        // 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) {
          std::map<int, unsigned>::iterator It = SpillSlotsAvailable.find(SS);
          if (It != SpillSlotsAvailable.end()) {
            PhysRegsAvailable.erase(It->second);
            SpillSlotsAvailable.erase(It);
          }
        }
      } else {
        DEBUG(std::cerr << ": No stack slot!\n");
      }
    }

    // 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();

        bool TakenCareOf = false;
        if (!MRegisterInfo::isVirtualRegister(VirtReg)) {
          // Check to see if this is a def-and-use vreg operand that we do need
          // to insert a store for.
          bool OpTakenCareOf = false;
          if (MO.isUse() && !DefAndUseVReg.empty()) {
            for (unsigned dau = 0, e = DefAndUseVReg.size(); dau != e; ++dau)
              if (DefAndUseVReg[dau].first == i) {
                VirtReg = DefAndUseVReg[dau].second;
                OpTakenCareOf = true;
                break;
              }
          }
          
          if (!OpTakenCareOf) {
            ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable);
            TakenCareOf = true;
          }
        }  

        if (!TakenCareOf) {
          // The only vregs left are stack slot definitions.
          int StackSlot    = VRM.getStackSlot(VirtReg);
          unsigned PhysReg;

          // If this is a def&use operand, and we used a different physreg for
          // it than the one assigned, make sure to execute the store from the
          // correct physical register.
          if (MO.getReg() == VirtReg)
            PhysReg = VRM.getPhys(VirtReg);
          else
            PhysReg = MO.getReg();

          PhysRegsUsed[PhysReg] = true;
          MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot);
          DEBUG(std::cerr << "Store:\t" << *next(MII));
          MI.SetMachineOperandReg(i, PhysReg);

          // If there is a dead store to this stack slot, nuke it now.
          MachineInstr *&LastStore = MaybeDeadStores[StackSlot];
          if (LastStore) {
            DEBUG(std::cerr << " Killed store:\t" << *LastStore);
            ++NumDSE;
            MBB.erase(LastStore);
          }
          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.
          std::map<int, unsigned>::iterator SSA =
            SpillSlotsAvailable.find(StackSlot);
          if (SSA != SpillSlotsAvailable.end()) {
            // Remove the record for physreg.
            PhysRegsAvailable.erase(SSA->second);
            SpillSlotsAvailable.erase(SSA);
          }
          ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable);

          PhysRegsAvailable[PhysReg] = StackSlot;
          SpillSlotsAvailable[StackSlot] = PhysReg;
          DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg "
                          << MRI->getName(PhysReg) << " for virtreg #"
                          << VirtReg << "\n");

          ++NumStores;
          VirtReg = PhysReg;
        }
      }
    }
    MII = NextMII;
  }
}



llvm::Spiller* llvm::createSpiller() {
  switch (SpillerOpt) {
  default: assert(0 && "Unreachable!");
  case local:
    return new LocalSpiller();
  case simple:
    return new SimpleSpiller();
  }
}
