//===-- RegAllocIterativeScan.cpp - Iterative Scan register allocator -----===//
//
//                     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 an iterative scan register
// allocator. Iterative scan is a linear scan variant with the
// following difference:
//
// It performs linear scan and keeps a list of the registers it cannot
// allocate. It then spills all those registers and repeats the
// process until allocation succeeds.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "regalloc"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "LiveIntervalAnalysis.h"
#include "PhysRegTracker.h"
#include "VirtRegMap.h"
#include <algorithm>
#include <cmath>
#include <set>

using namespace llvm;

namespace {

  Statistic<double> efficiency
  ("regalloc", "Ratio of intervals processed over total intervals");

  static unsigned numIterations = 0;
  static unsigned numIntervals = 0;

  class RA : public MachineFunctionPass {
  private:
    MachineFunction* mf_;
    const TargetMachine* tm_;
    const MRegisterInfo* mri_;
    LiveIntervals* li_;
    typedef std::vector<LiveInterval*> IntervalPtrs;
    IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_;

    std::auto_ptr<PhysRegTracker> prt_;
    std::auto_ptr<VirtRegMap> vrm_;
    std::auto_ptr<Spiller> spiller_;

    typedef std::vector<float> SpillWeights;
    SpillWeights spillWeights_;

  public:
    virtual const char* getPassName() const {
      return "Iterative Scan Register Allocator";
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LiveIntervals>();
      MachineFunctionPass::getAnalysisUsage(AU);
    }

    /// runOnMachineFunction - register allocate the whole function
    bool runOnMachineFunction(MachineFunction&);

    void releaseMemory();

  private:
    /// linearScan - the linear scan algorithm. Returns a boolean
    /// indicating if there were any spills
    bool linearScan();

    /// initIntervalSets - initializes the four interval sets:
    /// unhandled, fixed, active and inactive
    void initIntervalSets();

    /// processActiveIntervals - expire old intervals and move
    /// non-overlapping ones to the incative list
    void processActiveIntervals(IntervalPtrs::value_type cur);

    /// processInactiveIntervals - expire old intervals and move
    /// overlapping ones to the active list
    void processInactiveIntervals(IntervalPtrs::value_type cur);

    /// updateSpillWeights - updates the spill weights of the
    /// specifed physical register and its weight
    void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);

    /// assignRegOrStackSlotAtInterval - assign a register if one
    /// is available, or spill.
    void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur);

    ///
    /// register handling helpers
    ///

    /// getFreePhysReg - return a free physical register for this
    /// virtual register interval if we have one, otherwise return
    /// 0
    unsigned getFreePhysReg(IntervalPtrs::value_type cur);

    /// assignVirt2StackSlot - assigns this virtual register to a
    /// stack slot. returns the stack slot
    int assignVirt2StackSlot(unsigned virtReg);

    void printIntervals(const char* const str,
                        RA::IntervalPtrs::const_iterator i,
                        RA::IntervalPtrs::const_iterator e) const {
      if (str) std::cerr << str << " intervals:\n";
      for (; i != e; ++i) {
        std::cerr << "\t" << **i << " -> ";
        unsigned reg = (*i)->reg;
        if (MRegisterInfo::isVirtualRegister(reg)) {
          reg = vrm_->getPhys(reg);
        }
        std::cerr << mri_->getName(reg) << '\n';
      }
    }
  };
}

void RA::releaseMemory()
{
  unhandled_.clear();
  fixed_.clear();
  active_.clear();
  inactive_.clear();
  handled_.clear();
  spilled_.clear();
}

bool RA::runOnMachineFunction(MachineFunction &fn) {
  mf_ = &fn;
  tm_ = &fn.getTarget();
  mri_ = tm_->getRegisterInfo();
  li_ = &getAnalysis<LiveIntervals>();
  if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
  vrm_.reset(new VirtRegMap(*mf_));
  if (!spiller_.get()) spiller_.reset(createSpiller());

  initIntervalSets();

  numIntervals += li_->getNumIntervals();

  while (linearScan()) {
    // we spilled some registers, so we need to add intervals for
    // the spill code and restart the algorithm
    std::set<unsigned> spilledRegs;
    for (IntervalPtrs::iterator
           i = spilled_.begin(); i != spilled_.end(); ++i) {
      int slot = vrm_->assignVirt2StackSlot((*i)->reg);
      std::vector<LiveInterval*> added =
        li_->addIntervalsForSpills(**i, *vrm_, slot);
      std::copy(added.begin(), added.end(), std::back_inserter(handled_));
      spilledRegs.insert((*i)->reg);
    }
    spilled_.clear();
    for (IntervalPtrs::iterator
           i = handled_.begin(); i != handled_.end(); )
      if (spilledRegs.count((*i)->reg))
        i = handled_.erase(i);
      else
        ++i;
    handled_.swap(unhandled_);
    vrm_->clearAllVirt();
  }

  efficiency = double(numIterations) / double(numIntervals);

  DEBUG(std::cerr << *vrm_);

  spiller_->runOnMachineFunction(*mf_, *vrm_);

  return true;
}

bool RA::linearScan()
{
  // linear scan algorithm
  DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
  DEBUG(std::cerr << "********** Function: "
        << mf_->getFunction()->getName() << '\n');


  std::sort(unhandled_.begin(), unhandled_.end(),
            greater_ptr<LiveInterval>());
  DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end()));
  DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
  DEBUG(printIntervals("active", active_.begin(), active_.end()));
  DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));

  while (!unhandled_.empty()) {
    // pick the interval with the earliest start point
    IntervalPtrs::value_type cur = unhandled_.back();
    unhandled_.pop_back();
    ++numIterations;
    DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');

    processActiveIntervals(cur);
    processInactiveIntervals(cur);

    // if this register is fixed we are done
    if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
      prt_->addRegUse(cur->reg);
      active_.push_back(cur);
      handled_.push_back(cur);
    }
    // otherwise we are allocating a virtual register. try to find
    // a free physical register or spill an interval in order to
    // assign it one (we could spill the current though).
    else {
      assignRegOrSpillAtInterval(cur);
    }

    DEBUG(printIntervals("active", active_.begin(), active_.end()));
    DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
  }

  // expire any remaining active intervals
  for (IntervalPtrs::reverse_iterator
         i = active_.rbegin(); i != active_.rend(); ) {
    unsigned reg = (*i)->reg;
    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
    if (MRegisterInfo::isVirtualRegister(reg))
      reg = vrm_->getPhys(reg);
    prt_->delRegUse(reg);
    i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
  }

  // expire any remaining inactive intervals
  for (IntervalPtrs::reverse_iterator
         i = inactive_.rbegin(); i != inactive_.rend(); ) {
    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
    i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
  }

  // return true if we spilled anything
  return !spilled_.empty();
}

void RA::initIntervalSets() {
  assert(unhandled_.empty() && fixed_.empty() &&
         active_.empty() && inactive_.empty() &&
         "interval sets should be empty on initialization");

  for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
    unhandled_.push_back(&i->second);
    if (MRegisterInfo::isPhysicalRegister(i->second.reg))
      fixed_.push_back(&i->second);
  }
}

void RA::processActiveIntervals(IntervalPtrs::value_type cur)
{
  DEBUG(std::cerr << "\tprocessing active intervals:\n");
  IntervalPtrs::iterator ii = active_.begin(), ie = active_.end();
  while (ii != ie) {
    LiveInterval* i = *ii;
    unsigned reg = i->reg;

    // remove expired intervals
    if (i->expiredAt(cur->beginNumber())) {
      DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
      if (MRegisterInfo::isVirtualRegister(reg))
        reg = vrm_->getPhys(reg);
      prt_->delRegUse(reg);
      // swap with last element and move end iterator back one position
      std::iter_swap(ii, --ie);
    }
    // move inactive intervals to inactive list
    else if (!i->liveAt(cur->beginNumber())) {
      DEBUG(std::cerr << "\t\tinterval " << *i << " inactive\n");
      if (MRegisterInfo::isVirtualRegister(reg))
        reg = vrm_->getPhys(reg);
      prt_->delRegUse(reg);
      // add to inactive
      inactive_.push_back(i);
      // swap with last element and move end iterator back one postion
      std::iter_swap(ii, --ie);
    }
    else {
      ++ii;
    }
  }
  active_.erase(ie, active_.end());
}

void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
{
  DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
  IntervalPtrs::iterator ii = inactive_.begin(), ie = inactive_.end();
  while (ii != ie) {
    LiveInterval* i = *ii;
    unsigned reg = i->reg;

    // remove expired intervals
    if (i->expiredAt(cur->beginNumber())) {
      DEBUG(std::cerr << "\t\tinterval " << *i << " expired\n");
      // swap with last element and move end iterator back one position
      std::iter_swap(ii, --ie);
    }
    // move re-activated intervals in active list
    else if (i->liveAt(cur->beginNumber())) {
      DEBUG(std::cerr << "\t\tinterval " << *i << " active\n");
      if (MRegisterInfo::isVirtualRegister(reg))
        reg = vrm_->getPhys(reg);
      prt_->addRegUse(reg);
      // add to active
      active_.push_back(i);
      // swap with last element and move end iterator back one position
      std::iter_swap(ii, --ie);
    }
    else {
      ++ii;
    }
  }
  inactive_.erase(ie, inactive_.end());
}

void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
{
  spillWeights_[reg] += weight;
  for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
    spillWeights_[*as] += weight;
}

void RA::assignRegOrSpillAtInterval(IntervalPtrs::value_type cur)
{
  DEBUG(std::cerr << "\tallocating current interval: ");

  PhysRegTracker backupPrt = *prt_;

  spillWeights_.assign(mri_->getNumRegs(), 0.0);

  // for each interval in active update spill weights
  for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
       i != e; ++i) {
    unsigned reg = (*i)->reg;
    if (MRegisterInfo::isVirtualRegister(reg))
      reg = vrm_->getPhys(reg);
    updateSpillWeights(reg, (*i)->weight);
  }

  // for every interval in inactive we overlap with, mark the
  // register as not free and update spill weights
  for (IntervalPtrs::const_iterator i = inactive_.begin(),
         e = inactive_.end(); i != e; ++i) {
    if (cur->overlaps(**i)) {
      unsigned reg = (*i)->reg;
      if (MRegisterInfo::isVirtualRegister(reg))
        reg = vrm_->getPhys(reg);
      prt_->addRegUse(reg);
      updateSpillWeights(reg, (*i)->weight);
    }
  }

  // for every interval in fixed we overlap with,
  // mark the register as not free and update spill weights
  for (IntervalPtrs::const_iterator i = fixed_.begin(),
         e = fixed_.end(); i != e; ++i) {
    if (cur->overlaps(**i)) {
      unsigned reg = (*i)->reg;
      prt_->addRegUse(reg);
      updateSpillWeights(reg, (*i)->weight);
    }
  }

  unsigned physReg = getFreePhysReg(cur);
  // restore the physical register tracker
  *prt_ = backupPrt;
  // if we find a free register, we are done: assign this virtual to
  // the free physical register and add this interval to the active
  // list.
  if (physReg) {
    DEBUG(std::cerr <<  mri_->getName(physReg) << '\n');
    vrm_->assignVirt2Phys(cur->reg, physReg);
    prt_->addRegUse(physReg);
    active_.push_back(cur);
    handled_.push_back(cur);
    return;
  }
  DEBUG(std::cerr << "no free registers\n");

  DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");

  float minWeight = HUGE_VAL;
  unsigned minReg = 0;
  const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
       i != rc->allocation_order_end(*mf_); ++i) {
    unsigned reg = *i;
    if (minWeight > spillWeights_[reg]) {
      minWeight = spillWeights_[reg];
      minReg = reg;
    }
  }
  DEBUG(std::cerr << "\t\tregister with min weight: "
        << mri_->getName(minReg) << " (" << minWeight << ")\n");

  // if the current has the minimum weight, we spill it and move on
  if (cur->weight <= minWeight) {
    DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n');
    spilled_.push_back(cur);
    return;
  }

  // otherwise we spill all intervals aliasing the register with
  // minimum weight, assigned the newly cleared register to the
  // current interval and continue
  assert(MRegisterInfo::isPhysicalRegister(minReg) &&
         "did not choose a register to spill?");
  std::vector<bool> toSpill(mri_->getNumRegs(), false);
  toSpill[minReg] = true;
  for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
    toSpill[*as] = true;
  unsigned earliestStart = cur->beginNumber();

  std::set<unsigned> spilled;

  for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) {
    unsigned reg = (*i)->reg;
    if (MRegisterInfo::isVirtualRegister(reg) &&
        toSpill[vrm_->getPhys(reg)] &&
        cur->overlaps(**i)) {
      DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
      spilled_.push_back(*i);
      prt_->delRegUse(vrm_->getPhys(reg));
      vrm_->clearVirt(reg);
      i = active_.erase(i);
    }
    else
      ++i;
  }
  for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) {
    unsigned reg = (*i)->reg;
    if (MRegisterInfo::isVirtualRegister(reg) &&
        toSpill[vrm_->getPhys(reg)] &&
        cur->overlaps(**i)) {
      DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
      spilled_.push_back(*i);
      vrm_->clearVirt(reg);
      i = inactive_.erase(i);
    }
    else
      ++i;
  }

  vrm_->assignVirt2Phys(cur->reg, minReg);
  prt_->addRegUse(minReg);
  active_.push_back(cur);
  handled_.push_back(cur);

}

unsigned RA::getFreePhysReg(LiveInterval* cur)
{
  std::vector<unsigned> inactiveCounts(mri_->getNumRegs(), 0);
  for (IntervalPtrs::iterator i = inactive_.begin(), e = inactive_.end();
       i != e; ++i) {
    unsigned reg = (*i)->reg;
    if (MRegisterInfo::isVirtualRegister(reg))
      reg = vrm_->getPhys(reg);
    ++inactiveCounts[reg];
  }

  const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);

  unsigned freeReg = 0;
  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
       i != rc->allocation_order_end(*mf_); ++i) {
    unsigned reg = *i;
    if (prt_->isRegAvail(reg) &&
        (!freeReg || inactiveCounts[freeReg] < inactiveCounts[reg]))
        freeReg = reg;
  }
  return freeReg;
}

FunctionPass* llvm::createIterativeScanRegisterAllocator() {
  return new RA();
}
