//===- RegAllocBigBlock.cpp - A register allocator for large basic blocks -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the RABigBlock class
//
//===----------------------------------------------------------------------===//

// This register allocator is derived from RegAllocLocal.cpp. Like it, this
// allocator works on one basic block at a time, oblivious to others.
// However, the algorithm used here is suited for long blocks of
// instructions - registers are spilled by greedily choosing those holding
// values that will not be needed for the longest amount of time. This works
// particularly well for blocks with 10 or more times as many instructions
// as machine registers, but can be used for general code.
//
//===----------------------------------------------------------------------===//
//
// TODO: - automagically invoke linearscan for (groups of) small BBs?
//       - break ties when picking regs? (probably not worth it in a
//         JIT context)
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "regalloc"
#include "llvm/BasicBlock.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include <algorithm>
using namespace llvm;

STATISTIC(NumStores, "Number of stores added");
STATISTIC(NumLoads , "Number of loads added");
STATISTIC(NumFolded, "Number of loads/stores folded into instructions");

namespace {
  static RegisterRegAlloc
    bigBlockRegAlloc("bigblock", "  Big-block register allocator",
                  createBigBlockRegisterAllocator);

/// VRegKeyInfo - Defines magic values required to use VirtRegs as DenseMap
/// keys.
  struct VRegKeyInfo {
    static inline unsigned getEmptyKey() { return -1U; }
    static inline unsigned getTombstoneKey() { return -2U; }
    static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; }
    static unsigned getHashValue(const unsigned &Key) { return Key; }
  };


/// This register allocator is derived from RegAllocLocal.cpp. Like it, this
/// allocator works on one basic block at a time, oblivious to others.
/// However, the algorithm used here is suited for long blocks of
/// instructions - registers are spilled by greedily choosing those holding
/// values that will not be needed for the longest amount of time. This works
/// particularly well for blocks with 10 or more times as many instructions
/// as machine registers, but can be used for general code.
///
/// TODO: - automagically invoke linearscan for (groups of) small BBs?
///       - break ties when picking regs? (probably not worth it in a
///         JIT context)
///
  class VISIBILITY_HIDDEN RABigBlock : public MachineFunctionPass {
  public:
    static char ID;
    RABigBlock() : MachineFunctionPass((intptr_t)&ID) {}
  private:
    /// TM - For getting at TargetMachine info 
    ///
    const TargetMachine *TM;
    
    /// MF - Our generic MachineFunction pointer
    ///
    MachineFunction *MF;
    
    /// RegInfo - For dealing with machine register info (aliases, folds
    /// etc)
    const MRegisterInfo *RegInfo;

    /// LV - Our generic LiveVariables pointer
    ///
    LiveVariables *LV;

    typedef SmallVector<unsigned, 2> VRegTimes;

    /// VRegReadTable - maps VRegs in a BB to the set of times they are read
    ///
    DenseMap<unsigned, VRegTimes*, VRegKeyInfo> VRegReadTable;

    /// VRegReadIdx - keeps track of the "current time" in terms of
    /// positions in VRegReadTable
    DenseMap<unsigned, unsigned , VRegKeyInfo> VRegReadIdx;

    /// StackSlotForVirtReg - Maps virtual regs to the frame index where these
    /// values are spilled.
    IndexedMap<unsigned, VirtReg2IndexFunctor> StackSlotForVirtReg;

    /// Virt2PhysRegMap - This map contains entries for each virtual register
    /// that is currently available in a physical register.
    IndexedMap<unsigned, VirtReg2IndexFunctor> Virt2PhysRegMap;

    /// PhysRegsUsed - This array is effectively a map, containing entries for
    /// each physical register that currently has a value (ie, it is in
    /// Virt2PhysRegMap).  The value mapped to is the virtual register
    /// corresponding to the physical register (the inverse of the
    /// Virt2PhysRegMap), or 0.  The value is set to 0 if this register is pinned
    /// because it is used by a future instruction, and to -2 if it is not
    /// allocatable.  If the entry for a physical register is -1, then the
    /// physical register is "not in the map".
    ///
    std::vector<int> PhysRegsUsed;

    /// VirtRegModified - This bitset contains information about which virtual
    /// registers need to be spilled back to memory when their registers are
    /// scavenged.  If a virtual register has simply been rematerialized, there
    /// is no reason to spill it to memory when we need the register back.
    ///
    std::vector<int> VirtRegModified;

    /// MBBLastInsnTime - the number of the the last instruction in MBB
    ///
    int MBBLastInsnTime;

    /// MBBCurTime - the number of the the instruction being currently processed
    ///
    int MBBCurTime;

    unsigned &getVirt2PhysRegMapSlot(unsigned VirtReg) {
      return Virt2PhysRegMap[VirtReg];
    }

    unsigned &getVirt2StackSlot(unsigned VirtReg) {
      return StackSlotForVirtReg[VirtReg];
    }

    /// markVirtRegModified - Lets us flip bits in the VirtRegModified bitset
    ///
    void markVirtRegModified(unsigned Reg, bool Val = true) {
      assert(MRegisterInfo::isVirtualRegister(Reg) && "Illegal VirtReg!");
      Reg -= MRegisterInfo::FirstVirtualRegister;
      if (VirtRegModified.size() <= Reg)
        VirtRegModified.resize(Reg+1);
      VirtRegModified[Reg] = Val;
    }
    
    /// isVirtRegModified - Lets us query the VirtRegModified bitset
    ///
    bool isVirtRegModified(unsigned Reg) const {
      assert(MRegisterInfo::isVirtualRegister(Reg) && "Illegal VirtReg!");
      assert(Reg - MRegisterInfo::FirstVirtualRegister < VirtRegModified.size()
             && "Illegal virtual register!");
      return VirtRegModified[Reg - MRegisterInfo::FirstVirtualRegister];
    }

  public:
    /// getPassName - returns the BigBlock allocator's name
    ///
    virtual const char *getPassName() const {
      return "BigBlock Register Allocator";
    }

    /// getAnalaysisUsage - declares the required analyses
    ///
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequired<LiveVariables>();
      AU.addRequiredID(PHIEliminationID);
      AU.addRequiredID(TwoAddressInstructionPassID);
      MachineFunctionPass::getAnalysisUsage(AU);
    }

  private:
    /// runOnMachineFunction - Register allocate the whole function
    ///
    bool runOnMachineFunction(MachineFunction &Fn);

    /// AllocateBasicBlock - Register allocate the specified basic block.
    ///
    void AllocateBasicBlock(MachineBasicBlock &MBB);

    /// FillVRegReadTable - Fill out the table of vreg read times given a BB
    ///
    void FillVRegReadTable(MachineBasicBlock &MBB);
    
    /// areRegsEqual - This method returns true if the specified registers are
    /// related to each other.  To do this, it checks to see if they are equal
    /// or if the first register is in the alias set of the second register.
    ///
    bool areRegsEqual(unsigned R1, unsigned R2) const {
      if (R1 == R2) return true;
      for (const unsigned *AliasSet = RegInfo->getAliasSet(R2);
           *AliasSet; ++AliasSet) {
        if (*AliasSet == R1) return true;
      }
      return false;
    }

    /// getStackSpaceFor - This returns the frame index of the specified virtual
    /// register on the stack, allocating space if necessary.
    int getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC);

    /// removePhysReg - This method marks the specified physical register as no
    /// longer being in use.
    ///
    void removePhysReg(unsigned PhysReg);

    /// spillVirtReg - This method spills the value specified by PhysReg into
    /// the virtual register slot specified by VirtReg.  It then updates the RA
    /// data structures to indicate the fact that PhysReg is now available.
    ///
    void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                      unsigned VirtReg, unsigned PhysReg);

    /// spillPhysReg - This method spills the specified physical register into
    /// the virtual register slot associated with it.  If OnlyVirtRegs is set to
    /// true, then the request is ignored if the physical register does not
    /// contain a virtual register.
    ///
    void spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
                      unsigned PhysReg, bool OnlyVirtRegs = false);

    /// assignVirtToPhysReg - This method updates local state so that we know
    /// that PhysReg is the proper container for VirtReg now.  The physical
    /// register must not be used for anything else when this is called.
    ///
    void assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg);

    /// isPhysRegAvailable - Return true if the specified physical register is
    /// free and available for use.  This also includes checking to see if
    /// aliased registers are all free...
    ///
    bool isPhysRegAvailable(unsigned PhysReg) const;

    /// getFreeReg - Look to see if there is a free register available in the
    /// specified register class.  If not, return 0.
    ///
    unsigned getFreeReg(const TargetRegisterClass *RC);

    /// chooseReg - Pick a physical register to hold the specified
    /// virtual register by choosing the one which will be read furthest
    /// in the future.
    ///
    unsigned chooseReg(MachineBasicBlock &MBB, MachineInstr *MI,
                    unsigned VirtReg);

    /// reloadVirtReg - This method transforms the specified specified virtual
    /// register use to refer to a physical register.  This method may do this
    /// in one of several ways: if the register is available in a physical
    /// register already, it uses that physical register.  If the value is not
    /// in a physical register, and if there are physical registers available,
    /// it loads it into a register.  If register pressure is high, and it is
    /// possible, it tries to fold the load of the virtual register into the
    /// instruction itself.  It avoids doing this if register pressure is low to
    /// improve the chance that subsequent instructions can use the reloaded
    /// value.  This method returns the modified instruction.
    ///
    MachineInstr *reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
                                unsigned OpNum);

  };
  char RABigBlock::ID = 0;
}

/// getStackSpaceFor - This allocates space for the specified virtual register
/// to be held on the stack.
int RABigBlock::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
  // Find the location Reg would belong...
  int FrameIdx = getVirt2StackSlot(VirtReg);

  if (FrameIdx)
    return FrameIdx - 1;          // Already has space allocated?

  // Allocate a new stack object for this spill location...
  FrameIdx = MF->getFrameInfo()->CreateStackObject(RC->getSize(),
                                                       RC->getAlignment());

  // Assign the slot...
  getVirt2StackSlot(VirtReg) = FrameIdx + 1;
  return FrameIdx;
}


/// removePhysReg - This method marks the specified physical register as no
/// longer being in use.
///
void RABigBlock::removePhysReg(unsigned PhysReg) {
  PhysRegsUsed[PhysReg] = -1;      // PhyReg no longer used
}


/// spillVirtReg - This method spills the value specified by PhysReg into the
/// virtual register slot specified by VirtReg.  It then updates the RA data
/// structures to indicate the fact that PhysReg is now available.
///
void RABigBlock::spillVirtReg(MachineBasicBlock &MBB,
                           MachineBasicBlock::iterator I,
                           unsigned VirtReg, unsigned PhysReg) {
  assert(VirtReg && "Spilling a physical register is illegal!"
         " Must not have appropriate kill for the register or use exists beyond"
         " the intended one.");
  DOUT << "  Spilling register " << RegInfo->getName(PhysReg)
       << " containing %reg" << VirtReg;
  
  const TargetInstrInfo* TII = MBB.getParent()->getTarget().getInstrInfo();
  
  if (!isVirtRegModified(VirtReg))
    DOUT << " which has not been modified, so no store necessary!";

  // Otherwise, there is a virtual register corresponding to this physical
  // register.  We only need to spill it into its stack slot if it has been
  // modified.
  if (isVirtRegModified(VirtReg)) {
    const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
    int FrameIndex = getStackSpaceFor(VirtReg, RC);
    DOUT << " to stack slot #" << FrameIndex;
    TII->storeRegToStackSlot(MBB, I, PhysReg, true, FrameIndex, RC);
    ++NumStores;   // Update statistics
  }

  getVirt2PhysRegMapSlot(VirtReg) = 0;   // VirtReg no longer available

  DOUT << "\n";
  removePhysReg(PhysReg);
}


/// spillPhysReg - This method spills the specified physical register into the
/// virtual register slot associated with it.  If OnlyVirtRegs is set to true,
/// then the request is ignored if the physical register does not contain a
/// virtual register.
///
void RABigBlock::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
                           unsigned PhysReg, bool OnlyVirtRegs) {
  if (PhysRegsUsed[PhysReg] != -1) {            // Only spill it if it's used!
    assert(PhysRegsUsed[PhysReg] != -2 && "Non allocable reg used!");
    if (PhysRegsUsed[PhysReg] || !OnlyVirtRegs)
      spillVirtReg(MBB, I, PhysRegsUsed[PhysReg], PhysReg);
  } else {
    // If the selected register aliases any other registers, we must make
    // sure that one of the aliases isn't alive.
    for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg);
         *AliasSet; ++AliasSet)
      if (PhysRegsUsed[*AliasSet] != -1 &&     // Spill aliased register.
          PhysRegsUsed[*AliasSet] != -2)       // If allocatable.
        if (PhysRegsUsed[*AliasSet])
          spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
  }
}


/// assignVirtToPhysReg - This method updates local state so that we know
/// that PhysReg is the proper container for VirtReg now.  The physical
/// register must not be used for anything else when this is called.
///
void RABigBlock::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
  assert(PhysRegsUsed[PhysReg] == -1 && "Phys reg already assigned!");
  // Update information to note the fact that this register was just used, and
  // it holds VirtReg.
  PhysRegsUsed[PhysReg] = VirtReg;
  getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
}


/// isPhysRegAvailable - Return true if the specified physical register is free
/// and available for use.  This also includes checking to see if aliased
/// registers are all free...
///
bool RABigBlock::isPhysRegAvailable(unsigned PhysReg) const {
  if (PhysRegsUsed[PhysReg] != -1) return false;

  // If the selected register aliases any other allocated registers, it is
  // not free!
  for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg);
       *AliasSet; ++AliasSet)
    if (PhysRegsUsed[*AliasSet] != -1) // Aliased register in use?
      return false;                    // Can't use this reg then.
  return true;
}

  
/// getFreeReg - Look to see if there is a free register available in the
/// specified register class.  If not, return 0.
///
unsigned RABigBlock::getFreeReg(const TargetRegisterClass *RC) {
  // Get iterators defining the range of registers that are valid to allocate in
  // this class, which also specifies the preferred allocation order.
  TargetRegisterClass::iterator RI = RC->allocation_order_begin(*MF);
  TargetRegisterClass::iterator RE = RC->allocation_order_end(*MF);

  for (; RI != RE; ++RI)
    if (isPhysRegAvailable(*RI)) {       // Is reg unused?
      assert(*RI != 0 && "Cannot use register!");
      return *RI; // Found an unused register!
    }
  return 0;
}


/// chooseReg - Pick a physical register to hold the specified
/// virtual register by choosing the one whose value will be read
/// furthest in the future.
///
unsigned RABigBlock::chooseReg(MachineBasicBlock &MBB, MachineInstr *I,
                         unsigned VirtReg) {
  const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
  // First check to see if we have a free register of the requested type...
  unsigned PhysReg = getFreeReg(RC);

  // If we didn't find an unused register, find the one which will be
  // read at the most distant point in time.
  if (PhysReg == 0) {
    unsigned delay=0, longest_delay=0;
    VRegTimes* ReadTimes;

    unsigned curTime = MBBCurTime;

    // for all physical regs in the RC,
    for(TargetRegisterClass::iterator pReg = RC->begin(); 
                                      pReg != RC->end();  ++pReg) {
      // how long until they're read?
      if(PhysRegsUsed[*pReg]>0) { // ignore non-allocatable regs
        ReadTimes = VRegReadTable[PhysRegsUsed[*pReg]];
        if(ReadTimes && !ReadTimes->empty()) {
            unsigned& pt = VRegReadIdx[PhysRegsUsed[*pReg]];
            while(pt < ReadTimes->size() && (*ReadTimes)[pt] < curTime) {
                ++pt;
            }

            if(pt < ReadTimes->size())
                delay = (*ReadTimes)[pt] - curTime;
            else
                delay = MBBLastInsnTime + 1 - curTime;
        } else {
            // This register is only defined, but never
            // read in this MBB. Therefore the next read
            // happens after the end of this MBB
            delay = MBBLastInsnTime + 1 - curTime;
        }

        
        if(delay > longest_delay) {
          longest_delay = delay;
          PhysReg = *pReg;
        }
      }
    }

    if(PhysReg == 0) { // ok, now we're desperate. We couldn't choose
                       // a register to spill by looking through the
                       // read timetable, so now we just spill the
                       // first allocatable register we find.
                       
      // for all physical regs in the RC,
      for(TargetRegisterClass::iterator pReg = RC->begin(); 
                                        pReg != RC->end();  ++pReg) {
        // if we find a register we can spill
        if(PhysRegsUsed[*pReg]>=-1)
          PhysReg = *pReg; // choose it to be spilled
      }
    }
    
    assert(PhysReg && "couldn't choose a register to spill :( ");
    // TODO: assert that RC->contains(PhysReg) / handle aliased registers?

    // since we needed to look in the table we need to spill this register.
    spillPhysReg(MBB, I, PhysReg);
  }

  // assign the vreg to our chosen physical register
  assignVirtToPhysReg(VirtReg, PhysReg);
  return PhysReg; // and return it
}


/// reloadVirtReg - This method transforms an instruction with a virtual
/// register use to one that references a physical register. It does this as
/// follows:
///
///   1) If the register is already in a physical register, it uses it.
///   2) Otherwise, if there is a free physical register, it uses that.
///   3) Otherwise, it calls chooseReg() to get the physical register
///      holding the most distantly needed value, generating a spill in
///      the process.
///
/// This method returns the modified instruction.
MachineInstr *RABigBlock::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
                                     unsigned OpNum) {
  unsigned VirtReg = MI->getOperand(OpNum).getReg();
  const TargetInstrInfo* TII = MBB.getParent()->getTarget().getInstrInfo();

  // If the virtual register is already available in a physical register,
  // just update the instruction and return.
  if (unsigned PR = getVirt2PhysRegMapSlot(VirtReg)) {
    MI->getOperand(OpNum).setReg(PR);
    return MI;
  }

  // Otherwise, if we have free physical registers available to hold the
  // value, use them.
  const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
  unsigned PhysReg = getFreeReg(RC);
  int FrameIndex = getStackSpaceFor(VirtReg, RC);

  if (PhysReg) {   // we have a free register, so use it.
    assignVirtToPhysReg(VirtReg, PhysReg);
  } else {  // no free registers available.
    // try to fold the spill into the instruction
    SmallVector<unsigned, 2> Ops;
    Ops.push_back(OpNum);
    if(MachineInstr* FMI = TII->foldMemoryOperand(MI, Ops, FrameIndex)) {
      ++NumFolded;
      // Since we changed the address of MI, make sure to update live variables
      // to know that the new instruction has the properties of the old one.
      LV->instructionChanged(MI, FMI);
      return MBB.insert(MBB.erase(MI), FMI);
    }
    
    // determine which of the physical registers we'll kill off, since we
    // couldn't fold.
    PhysReg = chooseReg(MBB, MI, VirtReg);
  }

  // this virtual register is now unmodified (since we just reloaded it)
  markVirtRegModified(VirtReg, false);

  DOUT << "  Reloading %reg" << VirtReg << " into "
       << RegInfo->getName(PhysReg) << "\n";

  // Add move instruction(s)
  TII->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC);
  ++NumLoads;    // Update statistics

  MF->getRegInfo().setPhysRegUsed(PhysReg);
  MI->getOperand(OpNum).setReg(PhysReg);  // Assign the input register
  return MI;
}

/// Fill out the vreg read timetable. Since ReadTime increases
/// monotonically, the individual readtime sets will be sorted
/// in ascending order.
void RABigBlock::FillVRegReadTable(MachineBasicBlock &MBB) {
  // loop over each instruction
  MachineBasicBlock::iterator MII;
  unsigned ReadTime;
  
  for(ReadTime=0, MII = MBB.begin(); MII != MBB.end(); ++ReadTime, ++MII) {
    MachineInstr *MI = MII;
    
    for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
      MachineOperand& MO = MI->getOperand(i);
      // look for vreg reads..
      if (MO.isRegister() && !MO.isDef() && MO.getReg() &&
          MRegisterInfo::isVirtualRegister(MO.getReg())) {
          // ..and add them to the read table.
          VRegTimes* &Times = VRegReadTable[MO.getReg()];
          if(!VRegReadTable[MO.getReg()]) {
              Times = new VRegTimes;
              VRegReadIdx[MO.getReg()] = 0;
          }
        Times->push_back(ReadTime);
      }
    }

  }  

  MBBLastInsnTime = ReadTime;

  for(DenseMap<unsigned, VRegTimes*, VRegKeyInfo>::iterator Reads = VRegReadTable.begin();
      Reads != VRegReadTable.end(); ++Reads) {
      if(Reads->second) {
          DOUT << "Reads[" << Reads->first << "]=" << Reads->second->size() << "\n";
      }
  }
}

/// isReadModWriteImplicitKill - True if this is an implicit kill for a
/// read/mod/write register, i.e. update partial register.
static bool isReadModWriteImplicitKill(MachineInstr *MI, unsigned Reg) {
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    MachineOperand& MO = MI->getOperand(i);
    if (MO.isRegister() && MO.getReg() == Reg && MO.isImplicit() &&
        MO.isDef() && !MO.isDead())
      return true;
  }
  return false;
}

/// isReadModWriteImplicitDef - True if this is an implicit def for a
/// read/mod/write register, i.e. update partial register.
static bool isReadModWriteImplicitDef(MachineInstr *MI, unsigned Reg) {
  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    MachineOperand& MO = MI->getOperand(i);
    if (MO.isRegister() && MO.getReg() == Reg && MO.isImplicit() &&
        !MO.isDef() && MO.isKill())
      return true;
  }
  return false;
}


void RABigBlock::AllocateBasicBlock(MachineBasicBlock &MBB) {
  // loop over each instruction
  MachineBasicBlock::iterator MII = MBB.begin();
  const TargetInstrInfo &TII = *TM->getInstrInfo();
  
  DEBUG(const BasicBlock *LBB = MBB.getBasicBlock();
        if (LBB) DOUT << "\nStarting RegAlloc of BB: " << LBB->getName());

  // If this is the first basic block in the machine function, add live-in
  // registers as active.
  if (&MBB == &*MF->begin()) {
    for (MachineRegisterInfo::livein_iterator
         I = MF->getRegInfo().livein_begin(),
         E = MF->getRegInfo().livein_end(); I != E; ++I) {
      unsigned Reg = I->first;
      MF->getRegInfo().setPhysRegUsed(Reg);
      PhysRegsUsed[Reg] = 0;            // It is free and reserved now
      for (const unsigned *AliasSet = RegInfo->getSubRegisters(Reg);
           *AliasSet; ++AliasSet) {
        if (PhysRegsUsed[*AliasSet] != -2) {
          PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
          MF->getRegInfo().setPhysRegUsed(*AliasSet);
        }
      }
    }    
  }
  
  // Otherwise, sequentially allocate each instruction in the MBB.
  MBBCurTime = -1;
  while (MII != MBB.end()) {
    MachineInstr *MI = MII++;
    MBBCurTime++;
    const TargetInstrDesc &TID = MI->getDesc();
    DEBUG(DOUT << "\nTime=" << MBBCurTime << " Starting RegAlloc of: " << *MI;
          DOUT << "  Regs have values: ";
          for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i)
            if (PhysRegsUsed[i] != -1 && PhysRegsUsed[i] != -2)
               DOUT << "[" << RegInfo->getName(i)
                    << ",%reg" << PhysRegsUsed[i] << "] ";
          DOUT << "\n");

    SmallVector<unsigned, 8> Kills;
    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
      MachineOperand& MO = MI->getOperand(i);
      if (MO.isRegister() && MO.isKill()) {
        if (!MO.isImplicit())
          Kills.push_back(MO.getReg());
        else if (!isReadModWriteImplicitKill(MI, MO.getReg()))
          // These are extra physical register kills when a sub-register
          // is defined (def of a sub-register is a read/mod/write of the
          // larger registers). Ignore.
          Kills.push_back(MO.getReg());
      }
    }

    // Get the used operands into registers.  This has the potential to spill
    // incoming values if we are out of registers.  Note that we completely
    // ignore physical register uses here.  We assume that if an explicit
    // physical register is referenced by the instruction, that it is guaranteed
    // to be live-in, or the input is badly hosed.
    //
    for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
      MachineOperand& MO = MI->getOperand(i);
      // here we are looking for only used operands (never def&use)
      if (MO.isRegister() && !MO.isDef() && MO.getReg() && !MO.isImplicit() &&
          MRegisterInfo::isVirtualRegister(MO.getReg()))
        MI = reloadVirtReg(MBB, MI, i);
    }

    // If this instruction is the last user of this register, kill the
    // value, freeing the register being used, so it doesn't need to be
    // spilled to memory.
    //
    for (unsigned i = 0, e = Kills.size(); i != e; ++i) {
      unsigned VirtReg = Kills[i];
      unsigned PhysReg = VirtReg;
      if (MRegisterInfo::isVirtualRegister(VirtReg)) {
        // If the virtual register was never materialized into a register, it
        // might not be in the map, but it won't hurt to zero it out anyway.
        unsigned &PhysRegSlot = getVirt2PhysRegMapSlot(VirtReg);
        PhysReg = PhysRegSlot;
        PhysRegSlot = 0;
      } else if (PhysRegsUsed[PhysReg] == -2) {
        // Unallocatable register dead, ignore.
        continue;
      } else {
        assert(!PhysRegsUsed[PhysReg] || PhysRegsUsed[PhysReg] == -1 &&
               "Silently clearing a virtual register?");
      }

      if (PhysReg) {
        DOUT << "  Last use of " << RegInfo->getName(PhysReg)
             << "[%reg" << VirtReg <<"], removing it from live set\n";
        removePhysReg(PhysReg);
        for (const unsigned *AliasSet = RegInfo->getSubRegisters(PhysReg);
             *AliasSet; ++AliasSet) {
          if (PhysRegsUsed[*AliasSet] != -2) {
            DOUT  << "  Last use of "
                  << RegInfo->getName(*AliasSet)
                  << "[%reg" << VirtReg <<"], removing it from live set\n";
            removePhysReg(*AliasSet);
          }
        }
      }
    }

    // Loop over all of the operands of the instruction, spilling registers that
    // are defined, and marking explicit destinations in the PhysRegsUsed map.
    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
      MachineOperand& MO = MI->getOperand(i);
      if (MO.isRegister() && MO.isDef() && !MO.isImplicit() && MO.getReg() &&
          MRegisterInfo::isPhysicalRegister(MO.getReg())) {
        unsigned Reg = MO.getReg();
        if (PhysRegsUsed[Reg] == -2) continue;  // Something like ESP.
        // These are extra physical register defs when a sub-register
        // is defined (def of a sub-register is a read/mod/write of the
        // larger registers). Ignore.
        if (isReadModWriteImplicitDef(MI, MO.getReg())) continue;

        MF->getRegInfo().setPhysRegUsed(Reg);
        spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
        PhysRegsUsed[Reg] = 0;            // It is free and reserved now
        for (const unsigned *AliasSet = RegInfo->getSubRegisters(Reg);
             *AliasSet; ++AliasSet) {
          if (PhysRegsUsed[*AliasSet] != -2) {
            PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
            MF->getRegInfo().setPhysRegUsed(*AliasSet);
          }
        }
      }
    }

    // Loop over the implicit defs, spilling them as well.
    if (TID.getImplicitDefs()) {
      for (const unsigned *ImplicitDefs = TID.getImplicitDefs();
           *ImplicitDefs; ++ImplicitDefs) {
        unsigned Reg = *ImplicitDefs;
        if (PhysRegsUsed[Reg] != -2) {
          spillPhysReg(MBB, MI, Reg, true);
          PhysRegsUsed[Reg] = 0;            // It is free and reserved now
        }
        MF->getRegInfo().setPhysRegUsed(Reg);
        for (const unsigned *AliasSet = RegInfo->getSubRegisters(Reg);
             *AliasSet; ++AliasSet) {
          if (PhysRegsUsed[*AliasSet] != -2) {
            PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
            MF->getRegInfo().setPhysRegUsed(*AliasSet);
          }
        }
      }
    }

    SmallVector<unsigned, 8> DeadDefs;
    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
      MachineOperand& MO = MI->getOperand(i);
      if (MO.isRegister() && MO.isDead())
        DeadDefs.push_back(MO.getReg());
    }

    // Okay, we have allocated all of the source operands and spilled any values
    // that would be destroyed by defs of this instruction.  Loop over the
    // explicit defs and assign them to a register, spilling incoming values if
    // we need to scavenge a register.
    //
    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
      MachineOperand& MO = MI->getOperand(i);
      if (MO.isRegister() && MO.isDef() && MO.getReg() &&
          MRegisterInfo::isVirtualRegister(MO.getReg())) {
        unsigned DestVirtReg = MO.getReg();
        unsigned DestPhysReg;

        // If DestVirtReg already has a value, use it.
        if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg)))
          DestPhysReg = chooseReg(MBB, MI, DestVirtReg);
        MF->getRegInfo().setPhysRegUsed(DestPhysReg);
        markVirtRegModified(DestVirtReg);
        MI->getOperand(i).setReg(DestPhysReg);  // Assign the output register
      }
    }

    // If this instruction defines any registers that are immediately dead,
    // kill them now.
    //
    for (unsigned i = 0, e = DeadDefs.size(); i != e; ++i) {
      unsigned VirtReg = DeadDefs[i];
      unsigned PhysReg = VirtReg;
      if (MRegisterInfo::isVirtualRegister(VirtReg)) {
        unsigned &PhysRegSlot = getVirt2PhysRegMapSlot(VirtReg);
        PhysReg = PhysRegSlot;
        assert(PhysReg != 0);
        PhysRegSlot = 0;
      } else if (PhysRegsUsed[PhysReg] == -2) {
        // Unallocatable register dead, ignore.
        continue;
      }

      if (PhysReg) {
        DOUT  << "  Register " << RegInfo->getName(PhysReg)
              << " [%reg" << VirtReg
              << "] is never used, removing it frame live list\n";
        removePhysReg(PhysReg);
        for (const unsigned *AliasSet = RegInfo->getAliasSet(PhysReg);
             *AliasSet; ++AliasSet) {
          if (PhysRegsUsed[*AliasSet] != -2) {
            DOUT  << "  Register " << RegInfo->getName(*AliasSet)
                  << " [%reg" << *AliasSet
                  << "] is never used, removing it frame live list\n";
            removePhysReg(*AliasSet);
          }
        }
      }
    }
    
    // Finally, if this is a noop copy instruction, zap it.
    unsigned SrcReg, DstReg;
    if (TII.isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg) {
      LV->removeVirtualRegistersKilled(MI);
      LV->removeVirtualRegistersDead(MI);
      MBB.erase(MI);
    }
  }

  MachineBasicBlock::iterator MI = MBB.getFirstTerminator();

  // Spill all physical registers holding virtual registers now.
  for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
    if (PhysRegsUsed[i] != -1 && PhysRegsUsed[i] != -2)
      if (unsigned VirtReg = PhysRegsUsed[i])
        spillVirtReg(MBB, MI, VirtReg, i);
      else
        removePhysReg(i);
}

/// runOnMachineFunction - Register allocate the whole function
///
bool RABigBlock::runOnMachineFunction(MachineFunction &Fn) {
  DOUT << "Machine Function " << "\n";
  MF = &Fn;
  TM = &Fn.getTarget();
  RegInfo = TM->getRegisterInfo();
  LV = &getAnalysis<LiveVariables>();

  PhysRegsUsed.assign(RegInfo->getNumRegs(), -1);
  
  // At various places we want to efficiently check to see whether a register
  // is allocatable.  To handle this, we mark all unallocatable registers as
  // being pinned down, permanently.
  {
    BitVector Allocable = RegInfo->getAllocatableSet(Fn);
    for (unsigned i = 0, e = Allocable.size(); i != e; ++i)
      if (!Allocable[i])
        PhysRegsUsed[i] = -2;  // Mark the reg unallocable.
  }

  // initialize the virtual->physical register map to have a 'null'
  // mapping for all virtual registers
  Virt2PhysRegMap.grow(MF->getRegInfo().getLastVirtReg());
  StackSlotForVirtReg.grow(MF->getRegInfo().getLastVirtReg());
  VirtRegModified.resize(MF->getRegInfo().getLastVirtReg() - 
                         MRegisterInfo::FirstVirtualRegister + 1, 0);

  // Loop over all of the basic blocks, eliminating virtual register references
  for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
       MBB != MBBe; ++MBB) {
    // fill out the read timetable 
    FillVRegReadTable(*MBB);
    // use it to allocate the BB
    AllocateBasicBlock(*MBB);
    // clear it
    VRegReadTable.clear();
  }
  
  StackSlotForVirtReg.clear();
  PhysRegsUsed.clear();
  VirtRegModified.clear();
  Virt2PhysRegMap.clear();
  return true;
}

FunctionPass *llvm::createBigBlockRegisterAllocator() {
  return new RABigBlock();
}

