[llvm-commits] [parallel] CVS: llvm/lib/CodeGen/MachineBasicBlock.cpp PhysRegTracker.h VirtRegMap.cpp VirtRegMap.h LiveIntervals.cpp LiveIntervals.h LiveVariables.cpp MachineCodeEmitter.cpp MachineCodeForInstruction.cpp MachineFunction.cpp MachineInstr.cpp MachineInstrAnnot.cpp PHIElimination.cpp Passes.cpp PrologEpilogInserter.cpp RegAllocLinearScan.cpp RegAllocLocal.cpp RegAllocSimple.cpp TwoAddressInstructionPass.cpp

Misha Brukman brukman at cs.uiuc.edu
Mon Mar 1 18:06:33 PST 2004


Changes in directory llvm/lib/CodeGen:

MachineBasicBlock.cpp added (r1.9.2.1)
PhysRegTracker.h added (r1.4.2.1)
VirtRegMap.cpp added (r1.8.2.1)
VirtRegMap.h added (r1.9.2.1)
LiveIntervals.cpp updated: 1.28 -> 1.28.2.1
LiveIntervals.h updated: 1.11 -> 1.11.2.1
LiveVariables.cpp updated: 1.15 -> 1.15.2.1
MachineCodeEmitter.cpp updated: 1.14 -> 1.14.4.1
MachineCodeForInstruction.cpp updated: 1.11 -> 1.11.2.1
MachineFunction.cpp updated: 1.46 -> 1.46.2.1
MachineInstr.cpp updated: 1.82 -> 1.82.2.1
MachineInstrAnnot.cpp updated: 1.10 -> 1.10.4.1
PHIElimination.cpp updated: 1.14 -> 1.14.2.1
Passes.cpp updated: 1.5 -> 1.5.2.1
PrologEpilogInserter.cpp updated: 1.16 -> 1.16.2.1
RegAllocLinearScan.cpp updated: 1.31 -> 1.31.2.1
RegAllocLocal.cpp updated: 1.37 -> 1.37.2.1
RegAllocSimple.cpp updated: 1.47 -> 1.47.2.1
TwoAddressInstructionPass.cpp updated: 1.6 -> 1.6.2.1

---
Log message:

Merge from trunk

---
Diffs of the changes:  (+2022 -1250)

Index: llvm/lib/CodeGen/MachineBasicBlock.cpp
diff -c /dev/null llvm/lib/CodeGen/MachineBasicBlock.cpp:1.9.2.1
*** /dev/null	Mon Mar  1 17:58:27 2004
--- llvm/lib/CodeGen/MachineBasicBlock.cpp	Mon Mar  1 17:58:13 2004
***************
*** 0 ****
--- 1,83 ----
+ //===-- llvm/CodeGen/MachineBasicBlock.cpp ----------------------*- C++ -*-===//
+ //
+ //                     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.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // Collect the sequence of machine instructions for a basic block.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "llvm/CodeGen/MachineBasicBlock.h"
+ #include "llvm/BasicBlock.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "llvm/Target/TargetInstrInfo.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "Support/LeakDetector.h"
+ using namespace llvm;
+ 
+ const MachineFunction *MachineBasicBlock::getParent() const {
+   // Get the parent by getting the Function parent of the basic block, and
+   // getting the MachineFunction from it.
+   return &MachineFunction::get(getBasicBlock()->getParent());
+ }
+ 
+ 
+ MachineInstr* ilist_traits<MachineInstr>::createNode()
+ {
+     MachineInstr* dummy = new MachineInstr(0, 0);
+     LeakDetector::removeGarbageObject(dummy);
+     return dummy;
+ }
+ 
+ void ilist_traits<MachineInstr>::addNodeToList(MachineInstr* N)
+ {
+     assert(N->parent == 0 && "machine instruction already in a basic block");
+     N->parent = parent;
+     LeakDetector::removeGarbageObject(N);
+ }
+ 
+ void ilist_traits<MachineInstr>::removeNodeFromList(MachineInstr* N)
+ {
+     assert(N->parent != 0 && "machine instruction not in a basic block");
+     N->parent = 0;
+     LeakDetector::addGarbageObject(N);
+ }
+ 
+ void ilist_traits<MachineInstr>::transferNodesFromList(
+     iplist<MachineInstr, ilist_traits<MachineInstr> >& toList,
+     ilist_iterator<MachineInstr> first,
+     ilist_iterator<MachineInstr> last)
+ {
+     if (parent != toList.parent)
+         for (; first != last; ++first)
+             first->parent = toList.parent;
+ }
+ 
+ MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator()
+ {
+   const TargetInstrInfo& TII = getParent()->getTarget().getInstrInfo();
+   iterator I = end();
+   while (I != begin() && TII.isTerminatorInstr((--I)->getOpcode()));
+   if (I != end() && !TII.isTerminatorInstr(I->getOpcode())) ++I;
+   return I;
+ }
+ 
+ void MachineBasicBlock::dump() const
+ {
+     print(std::cerr);
+ }
+ 
+ void MachineBasicBlock::print(std::ostream &OS) const
+ {
+     const BasicBlock *LBB = getBasicBlock();
+     OS << "\n" << LBB->getName() << " (" << (const void*)LBB << "):\n";
+     for (const_iterator I = begin(); I != end(); ++I) {
+         OS << "\t";
+         I->print(OS, MachineFunction::get(LBB->getParent()).getTarget());
+     }
+ }


Index: llvm/lib/CodeGen/PhysRegTracker.h
diff -c /dev/null llvm/lib/CodeGen/PhysRegTracker.h:1.4.2.1
*** /dev/null	Mon Mar  1 17:58:27 2004
--- llvm/lib/CodeGen/PhysRegTracker.h	Mon Mar  1 17:58:13 2004
***************
*** 0 ****
--- 1,73 ----
+ //===-- llvm/CodeGen/PhysRegTracker.h - Physical Register Tracker -*- C++ -*-=//
+ //
+ //                     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 a physical register tracker. The tracker
+ // tracks physical register usage through addRegUse and
+ // delRegUse. isRegAvail checks if a physical register is available or
+ // not taking into consideration register aliases.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_CODEGEN_PHYSREGTRACKER_H
+ #define LLVM_CODEGEN_PHYSREGTRACKER_H
+ 
+ #include "llvm/Target/MRegisterInfo.h"
+ 
+ namespace llvm {
+ 
+     class PhysRegTracker {
+         const MRegisterInfo* mri_;
+         std::vector<unsigned> regUse_;
+ 
+     public:
+         PhysRegTracker(const MRegisterInfo& mri)
+             : mri_(&mri),
+               regUse_(mri_->getNumRegs(), 0) {
+         }
+ 
+         PhysRegTracker(const PhysRegTracker& rhs)
+             : mri_(rhs.mri_),
+               regUse_(rhs.regUse_) {
+         }
+ 
+         const PhysRegTracker& operator=(const PhysRegTracker& rhs) {
+             mri_ = rhs.mri_;
+             regUse_ = rhs.regUse_;
+             return *this;
+         }
+ 
+         void addRegUse(unsigned physReg) {
+             assert(MRegisterInfo::isPhysicalRegister(physReg) &&
+                    "should be physical register!");
+             ++regUse_[physReg];
+             for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as)
+                 ++regUse_[*as];
+         }
+ 
+         void delRegUse(unsigned physReg) {
+             assert(MRegisterInfo::isPhysicalRegister(physReg) &&
+                    "should be physical register!");
+             assert(regUse_[physReg] != 0);
+             --regUse_[physReg];
+             for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
+                 assert(regUse_[*as] != 0);
+                 --regUse_[*as];
+             }
+         }
+ 
+         bool isRegAvail(unsigned physReg) const {
+             assert(MRegisterInfo::isPhysicalRegister(physReg) &&
+                    "should be physical register!");
+             return regUse_[physReg] == 0;
+         }
+     };
+ 
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/lib/CodeGen/VirtRegMap.cpp
diff -c /dev/null llvm/lib/CodeGen/VirtRegMap.cpp:1.8.2.1
*** /dev/null	Mon Mar  1 17:58:28 2004
--- llvm/lib/CodeGen/VirtRegMap.cpp	Mon Mar  1 17:58:13 2004
***************
*** 0 ****
--- 1,285 ----
+ //===-- 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 virtual register map. It also implements
+ // the eliminateVirtRegs() function that given a virtual register map
+ // and a machine function it eliminates all virtual references by
+ // replacing them with physical register references and adds spill
+ // code as necessary.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "regalloc"
+ #include "VirtRegMap.h"
+ #include "llvm/Function.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Target/TargetInstrInfo.h"
+ #include "Support/CommandLine.h"
+ #include "Support/Debug.h"
+ #include "Support/DenseMap.h"
+ #include "Support/Statistic.h"
+ #include "Support/STLExtras.h"
+ #include <iostream>
+ 
+ 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");
+ 
+     enum SpillerName { local };
+ 
+     cl::opt<SpillerName>
+     SpillerOpt("spiller",
+                cl::desc("Spiller to use: (default: local)"),
+                cl::Prefix,
+                cl::values(clEnumVal(local, "  local spiller"),
+                           0),
+                cl::init(local));
+ }
+ 
+ int VirtRegMap::assignVirt2StackSlot(unsigned virtReg)
+ {
+     assert(MRegisterInfo::isVirtualRegister(virtReg));
+     assert(v2ssMap_[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);
+     v2ssMap_[virtReg] = frameIndex;
+     ++numSpills;
+     return frameIndex;
+ }
+ 
+ void VirtRegMap::virtFolded(unsigned virtReg,
+                             MachineInstr* oldMI,
+                             MachineInstr* newMI)
+ {
+     // move previous memory references folded to new instruction
+     MI2VirtMap::iterator i, e;
+     std::vector<MI2VirtMap::mapped_type> regs;
+     for (tie(i, e) = mi2vMap_.equal_range(oldMI); i != e; ) {
+         regs.push_back(i->second);
+         mi2vMap_.erase(i++);
+     }
+     for (unsigned i = 0, e = regs.size(); i != e; ++i)
+         mi2vMap_.insert(std::make_pair(newMI, i));
+ 
+     // add new memory reference
+     mi2vMap_.insert(std::make_pair(newMI, virtReg));
+ }
+ 
+ std::ostream& llvm::operator<<(std::ostream& os, const VirtRegMap& vrm)
+ {
+     const MRegisterInfo* mri = vrm.mf_->getTarget().getRegisterInfo();
+ 
+     std::cerr << "********** REGISTER MAP **********\n";
+     for (unsigned i = MRegisterInfo::FirstVirtualRegister,
+              e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
+         if (vrm.v2pMap_[i] != VirtRegMap::NO_PHYS_REG)
+             std::cerr << "[reg" << i << " -> "
+                       << mri->getName(vrm.v2pMap_[i]) << "]\n";
+     }
+     for (unsigned i = MRegisterInfo::FirstVirtualRegister,
+              e = vrm.mf_->getSSARegMap()->getLastVirtReg(); i <= e; ++i) {
+         if (vrm.v2ssMap_[i] != VirtRegMap::NO_STACK_SLOT)
+             std::cerr << "[reg" << i << " -> fi#"
+                       << vrm.v2ssMap_[i] << "]\n";
+     }
+     return std::cerr << '\n';
+ }
+ 
+ Spiller::~Spiller()
+ {
+ 
+ }
+ 
+ namespace {
+ 
+     class LocalSpiller : public Spiller {
+         typedef std::vector<unsigned> Phys2VirtMap;
+         typedef std::vector<bool> PhysFlag;
+         typedef DenseMap<MachineInstr*, VirtReg2IndexFunctor> Virt2MI;
+ 
+         MachineFunction* mf_;
+         const TargetMachine* tm_;
+         const TargetInstrInfo* tii_;
+         const MRegisterInfo* mri_;
+         const VirtRegMap* vrm_;
+         Phys2VirtMap p2vMap_;
+         PhysFlag dirty_;
+         Virt2MI lastDef_;
+ 
+     public:
+         bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) {
+             mf_ = &mf;
+             tm_ = &mf_->getTarget();
+             tii_ = &tm_->getInstrInfo();
+             mri_ = tm_->getRegisterInfo();
+             vrm_ = &vrm;
+             p2vMap_.assign(mri_->getNumRegs(), 0);
+             dirty_.assign(mri_->getNumRegs(), false);
+ 
+             DEBUG(std::cerr << "********** REWRITE MACHINE CODE **********\n");
+             DEBUG(std::cerr << "********** Function: "
+                   << mf_->getFunction()->getName() << '\n');
+ 
+             for (MachineFunction::iterator mbbi = mf_->begin(),
+                      mbbe = mf_->end(); mbbi != mbbe; ++mbbi) {
+                 lastDef_.grow(mf_->getSSARegMap()->getLastVirtReg());
+                 DEBUG(std::cerr << mbbi->getBasicBlock()->getName() << ":\n");
+                 eliminateVirtRegsInMbb(*mbbi);
+                 // clear map, dirty flag and last ref
+                 p2vMap_.assign(p2vMap_.size(), 0);
+                 dirty_.assign(dirty_.size(), false);
+                 lastDef_.clear();
+             }
+             return true;
+         }
+ 
+     private:
+         void vacateJustPhysReg(MachineBasicBlock& mbb,
+                                MachineBasicBlock::iterator mii,
+                                unsigned physReg) {
+             unsigned virtReg = p2vMap_[physReg];
+             if (dirty_[physReg] && vrm_->hasStackSlot(virtReg)) {
+                 assert(lastDef_[virtReg] && "virtual register is mapped "
+                        "to a register and but was not defined!");
+                 MachineBasicBlock::iterator lastDef = lastDef_[virtReg];
+                 MachineBasicBlock::iterator nextLastRef = next(lastDef);
+                 mri_->storeRegToStackSlot(*lastDef->getParent(),
+                                          nextLastRef,
+                                          physReg,
+                                          vrm_->getStackSlot(virtReg),
+                                          mri_->getRegClass(physReg));
+                 ++numStores;
+                 DEBUG(std::cerr << "added: ";
+                       prior(nextLastRef)->print(std::cerr, *tm_);
+                       std::cerr << "after: ";
+                       lastDef->print(std::cerr, *tm_));
+                 lastDef_[virtReg] = 0;
+             }
+             p2vMap_[physReg] = 0;
+             dirty_[physReg] = false;
+         }
+ 
+         void vacatePhysReg(MachineBasicBlock& mbb,
+                            MachineBasicBlock::iterator mii,
+                            unsigned physReg) {
+             vacateJustPhysReg(mbb, mii, physReg);
+             for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as)
+                 vacateJustPhysReg(mbb, mii, *as);
+         }
+ 
+         void handleUse(MachineBasicBlock& mbb,
+                        MachineBasicBlock::iterator mii,
+                        unsigned virtReg,
+                        unsigned physReg) {
+             // check if we are replacing a previous mapping
+             if (p2vMap_[physReg] != virtReg) {
+                 vacatePhysReg(mbb, mii, physReg);
+                 p2vMap_[physReg] = virtReg;
+                 // load if necessary
+                 if (vrm_->hasStackSlot(virtReg)) {
+                     mri_->loadRegFromStackSlot(mbb, mii, physReg,
+                                               vrm_->getStackSlot(virtReg),
+                                               mri_->getRegClass(physReg));
+                     ++numLoads;
+                     DEBUG(std::cerr << "added: ";
+                           prior(mii)->print(std::cerr, *tm_));
+                     lastDef_[virtReg] = mii;
+                 }
+             }
+         }
+ 
+         void handleDef(MachineBasicBlock& mbb,
+                        MachineBasicBlock::iterator mii,
+                        unsigned virtReg,
+                        unsigned physReg) {
+             // check if we are replacing a previous mapping
+             if (p2vMap_[physReg] != virtReg)
+                 vacatePhysReg(mbb, mii, physReg);
+ 
+             p2vMap_[physReg] = virtReg;
+             dirty_[physReg] = true;
+             lastDef_[virtReg] = mii;
+         }
+ 
+         void eliminateVirtRegsInMbb(MachineBasicBlock& mbb) {
+             for (MachineBasicBlock::iterator mii = mbb.begin(),
+                      mie = mbb.end(); mii != mie; ++mii) {
+ 
+                 // if we have references to memory operands make sure
+                 // we clear all physical registers that may contain
+                 // the value of the spilled virtual register
+                 VirtRegMap::MI2VirtMap::const_iterator i, e;
+                 for (tie(i, e) = vrm_->getFoldedVirts(mii); i != e; ++i) {
+                     unsigned physReg = vrm_->getPhys(i->second);
+                     if (physReg) vacateJustPhysReg(mbb, mii, physReg);
+                 }
+ 
+                 // rewrite all used operands
+                 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
+                     MachineOperand& op = mii->getOperand(i);
+                     if (op.isRegister() && op.getReg() && op.isUse() &&
+                         MRegisterInfo::isVirtualRegister(op.getReg())) {
+                         unsigned virtReg = op.getReg();
+                         unsigned physReg = vrm_->getPhys(virtReg);
+                         handleUse(mbb, mii, virtReg, physReg);
+                         mii->SetMachineOperandReg(i, physReg);
+                         // mark as dirty if this is def&use
+                         if (op.isDef()) {
+                             dirty_[physReg] = true;
+                             lastDef_[virtReg] = mii;
+                         }
+                     }
+                 }
+ 
+                 // spill implicit defs
+                 const TargetInstrDescriptor& tid = tii_->get(mii->getOpcode());
+                 for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
+                     vacatePhysReg(mbb, mii, *id);
+ 
+                 // rewrite def operands (def&use was handled with the
+                 // uses so don't check for those here)
+                 for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
+                     MachineOperand& op = mii->getOperand(i);
+                     if (op.isRegister() && op.getReg() && !op.isUse())
+                         if (MRegisterInfo::isPhysicalRegister(op.getReg()))
+                             vacatePhysReg(mbb, mii, op.getReg());
+                         else {
+                             unsigned physReg = vrm_->getPhys(op.getReg());
+                             handleDef(mbb, mii, op.getReg(), physReg);
+                             mii->SetMachineOperandReg(i, physReg);
+                         }
+                 }
+ 
+                 DEBUG(std::cerr << '\t'; mii->print(std::cerr, *tm_));
+             }
+ 
+             for (unsigned i = 1, e = p2vMap_.size(); i != e; ++i)
+                 vacateJustPhysReg(mbb, mbb.getFirstTerminator(), i);
+ 
+         }
+     };
+ }
+ 
+ llvm::Spiller* llvm::createSpiller()
+ {
+     switch (SpillerOpt) {
+     default:
+         std::cerr << "no spiller selected";
+         abort();
+     case local:
+         return new LocalSpiller();
+     }
+ }


Index: llvm/lib/CodeGen/VirtRegMap.h
diff -c /dev/null llvm/lib/CodeGen/VirtRegMap.h:1.9.2.1
*** /dev/null	Mon Mar  1 17:58:28 2004
--- llvm/lib/CodeGen/VirtRegMap.h	Mon Mar  1 17:58:13 2004
***************
*** 0 ****
--- 1,122 ----
+ //===-- llvm/CodeGen/VirtRegMap.h - Virtual Register Map -*- C++ -*--------===//
+ //
+ //                     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 a virtual register map. This maps virtual
+ // registers to physical registers and virtual registers to stack
+ // slots. It is created and updated by a register allocator and then
+ // used by a machine code rewriter that adds spill code and rewrites
+ // virtual into physical register references.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_CODEGEN_VIRTREGMAP_H
+ #define LLVM_CODEGEN_VIRTREGMAP_H
+ 
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/SSARegMap.h"
+ #include "Support/DenseMap.h"
+ #include <climits>
+ #include <map>
+ 
+ namespace llvm {
+ 
+     class MachineInstr;
+ 
+     class VirtRegMap {
+     public:
+         typedef DenseMap<unsigned, VirtReg2IndexFunctor> Virt2PhysMap;
+         typedef DenseMap<int, VirtReg2IndexFunctor> Virt2StackSlotMap;
+         typedef std::multimap<MachineInstr*, unsigned> MI2VirtMap;
+ 
+     private:
+         MachineFunction* mf_;
+         Virt2PhysMap v2pMap_;
+         Virt2StackSlotMap v2ssMap_;
+         MI2VirtMap mi2vMap_;
+ 
+         // do not implement
+         VirtRegMap(const VirtRegMap& rhs);
+         const VirtRegMap& operator=(const VirtRegMap& rhs);
+ 
+         enum {
+             NO_PHYS_REG   = 0,
+             NO_STACK_SLOT = INT_MAX
+         };
+ 
+     public:
+         VirtRegMap(MachineFunction& mf)
+             : mf_(&mf),
+               v2pMap_(NO_PHYS_REG),
+               v2ssMap_(NO_STACK_SLOT) {
+             v2pMap_.grow(mf.getSSARegMap()->getLastVirtReg());
+             v2ssMap_.grow(mf.getSSARegMap()->getLastVirtReg());
+         }
+ 
+         bool hasPhys(unsigned virtReg) const {
+             return getPhys(virtReg) != NO_PHYS_REG;
+         }
+ 
+         unsigned getPhys(unsigned virtReg) const {
+             assert(MRegisterInfo::isVirtualRegister(virtReg));
+             return v2pMap_[virtReg];
+         }
+ 
+         void assignVirt2Phys(unsigned virtReg, unsigned physReg) {
+             assert(MRegisterInfo::isVirtualRegister(virtReg) &&
+                    MRegisterInfo::isPhysicalRegister(physReg));
+             assert(v2pMap_[virtReg] == NO_PHYS_REG &&
+                    "attempt to assign physical register to already mapped "
+                    "virtual register");
+             v2pMap_[virtReg] = physReg;
+         }
+ 
+         void clearVirt(unsigned virtReg) {
+             assert(MRegisterInfo::isVirtualRegister(virtReg));
+             assert(v2pMap_[virtReg] != NO_PHYS_REG &&
+                    "attempt to clear a not assigned virtual register");
+             v2pMap_[virtReg] = NO_PHYS_REG;
+         }
+ 
+         bool hasStackSlot(unsigned virtReg) const {
+             return getStackSlot(virtReg) != NO_STACK_SLOT;
+         }
+ 
+         int getStackSlot(unsigned virtReg) const {
+             assert(MRegisterInfo::isVirtualRegister(virtReg));
+             return v2ssMap_[virtReg];
+         }
+ 
+         int assignVirt2StackSlot(unsigned virtReg);
+ 
+         void virtFolded(unsigned virtReg,
+                         MachineInstr* oldMI,
+                         MachineInstr* newMI);
+ 
+         std::pair<MI2VirtMap::const_iterator, MI2VirtMap::const_iterator>
+         getFoldedVirts(MachineInstr* MI) const {
+             return mi2vMap_.equal_range(MI);
+         }
+ 
+         friend std::ostream& operator<<(std::ostream& os, const VirtRegMap& li);
+     };
+ 
+     std::ostream& operator<<(std::ostream& os, const VirtRegMap& li);
+ 
+     struct Spiller {
+         virtual ~Spiller();
+ 
+         virtual bool runOnMachineFunction(MachineFunction& mf, const VirtRegMap& vrm) = 0;
+ 
+     };
+ 
+     Spiller* createSpiller();
+ 
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/lib/CodeGen/LiveIntervals.cpp
diff -u llvm/lib/CodeGen/LiveIntervals.cpp:1.28 llvm/lib/CodeGen/LiveIntervals.cpp:1.28.2.1
--- llvm/lib/CodeGen/LiveIntervals.cpp:1.28	Fri Jan 16 10:23:23 2004
+++ llvm/lib/CodeGen/LiveIntervals.cpp	Mon Mar  1 17:58:13 2004
@@ -16,23 +16,22 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "liveintervals"
-#include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/Function.h"
+#include "LiveIntervals.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineFrameInfo.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/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegInfo.h"
 #include "llvm/Support/CFG.h"
+#include "Support/CommandLine.h"
 #include "Support/Debug.h"
-#include "Support/DepthFirstIterator.h"
 #include "Support/Statistic.h"
+#include "Support/STLExtras.h"
+#include "VirtRegMap.h"
 #include <cmath>
 #include <iostream>
 #include <limits>
@@ -43,7 +42,25 @@
     RegisterAnalysis<LiveIntervals> X("liveintervals",
                                       "Live Interval Analysis");
 
-    Statistic<> numIntervals("liveintervals", "Number of intervals");
+    Statistic<> numIntervals
+    ("liveintervals", "Number of original intervals");
+
+    Statistic<> numIntervalsAfter
+    ("liveintervals", "Number of intervals after coalescing");
+
+    Statistic<> numJoins
+    ("liveintervals", "Number of interval joins performed");
+
+    Statistic<> numPeep
+    ("liveintervals", "Number of identity moves eliminated after coalescing");
+
+    Statistic<> numFolded
+    ("liveintervals", "Number of loads/stores folded into instructions");
+
+    cl::opt<bool>
+    join("join-liveintervals",
+         cl::desc("Join compatible live intervals"),
+         cl::init(true));
 };
 
 void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const
@@ -57,128 +74,241 @@
     MachineFunctionPass::getAnalysisUsage(AU);
 }
 
+void LiveIntervals::releaseMemory()
+{
+    mbbi2mbbMap_.clear();
+    mi2iMap_.clear();
+    i2miMap_.clear();
+    r2iMap_.clear();
+    r2rMap_.clear();
+    intervals_.clear();
+}
+
+
 /// runOnMachineFunction - Register allocate the whole function
 ///
 bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
-    DEBUG(std::cerr << "Machine Function\n");
     mf_ = &fn;
     tm_ = &fn.getTarget();
     mri_ = tm_->getRegisterInfo();
     lv_ = &getAnalysis<LiveVariables>();
-    mbbi2mbbMap_.clear();
-    mi2iMap_.clear();
-    r2iMap_.clear();
-    r2iMap_.clear();
-    intervals_.clear();
 
     // number MachineInstrs
     unsigned miIndex = 0;
     for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end();
          mbb != mbbEnd; ++mbb) {
         const std::pair<MachineBasicBlock*, unsigned>& entry =
-            lv_->getMachineBasicBlockInfo(&*mbb);
+            lv_->getMachineBasicBlockInfo(mbb);
         bool inserted = mbbi2mbbMap_.insert(std::make_pair(entry.second,
                                                            entry.first)).second;
         assert(inserted && "multiple index -> MachineBasicBlock");
 
         for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
              mi != miEnd; ++mi) {
-            inserted = mi2iMap_.insert(std::make_pair(*mi, miIndex)).second;
+            inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second;
             assert(inserted && "multiple MachineInstr -> index mappings");
-            ++miIndex;
+            i2miMap_.push_back(mi);
+            miIndex += InstrSlots::NUM;
         }
     }
 
     computeIntervals();
 
-    // compute spill weights
+    numIntervals += intervals_.size();
+
+    // join intervals if requested
+    if (join) joinIntervals();
+
+    numIntervalsAfter += intervals_.size();
+
+    // perform a final pass over the instructions and compute spill
+    // weights, coalesce virtual registers and remove identity moves
     const LoopInfo& loopInfo = getAnalysis<LoopInfo>();
     const TargetInstrInfo& tii = tm_->getInstrInfo();
 
-    for (MbbIndex2MbbMap::iterator
-             it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
-         it != itEnd; ++it) {
-        MachineBasicBlock* mbb = it->second;
-
+    for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+         mbbi != mbbe; ++mbbi) {
+        MachineBasicBlock* mbb = mbbi;
         unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock());
 
-        for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
-             mi != miEnd; ++mi) {
-            MachineInstr* instr = *mi;
-            for (int i = instr->getNumOperands() - 1; i >= 0; --i) {
-                MachineOperand& mop = instr->getOperand(i);
-
-                if (!mop.isVirtualRegister())
-                    continue;
+        for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
+             mii != mie; ) {
+            for (unsigned i = 0; i < mii->getNumOperands(); ++i) {
+                const MachineOperand& mop = mii->getOperand(i);
+                if (mop.isRegister() && mop.getReg()) {
+                    // replace register with representative register
+                    unsigned reg = rep(mop.getReg());
+                    mii->SetMachineOperandReg(i, reg);
+
+                    if (MRegisterInfo::isVirtualRegister(reg)) {
+                        Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
+                        assert(r2iit != r2iMap_.end());
+                        r2iit->second->weight += pow(10.0F, loopDepth);
+                    }
+                }
+            }
 
-                unsigned reg = mop.getAllocatedRegNum();
-                Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
-                assert(r2iit != r2iMap_.end());
-                r2iit->second->weight += pow(10.0F, loopDepth);
+            // if the move is now an identity move delete it
+            unsigned srcReg, dstReg;
+            if (tii.isMoveInstr(*mii, srcReg, dstReg) && srcReg == dstReg) {
+                // remove index -> MachineInstr and
+                // MachineInstr -> index mappings
+                Mi2IndexMap::iterator mi2i = mi2iMap_.find(mii);
+                if (mi2i != mi2iMap_.end()) {
+                    i2miMap_[mi2i->second/InstrSlots::NUM] = 0;
+                    mi2iMap_.erase(mi2i);
+                }
+                mii = mbbi->erase(mii);
+                ++numPeep;
             }
+            else
+                ++mii;
         }
     }
 
-    numIntervals += intervals_.size();
+    intervals_.sort(StartPointComp());
+    DEBUG(std::cerr << "********** INTERVALS **********\n");
+    DEBUG(std::copy(intervals_.begin(), intervals_.end(),
+                    std::ostream_iterator<Interval>(std::cerr, "\n")));
+    DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
+    DEBUG(
+        for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+             mbbi != mbbe; ++mbbi) {
+            std::cerr << mbbi->getBasicBlock()->getName() << ":\n";
+            for (MachineBasicBlock::iterator mii = mbbi->begin(),
+                     mie = mbbi->end(); mii != mie; ++mii) {
+                std::cerr << getInstructionIndex(mii) << '\t';
+                mii->print(std::cerr, *tm_);
+            }
+        });
 
     return true;
 }
 
+void LiveIntervals::updateSpilledInterval(Interval& li,
+                                          VirtRegMap& vrm,
+                                          int slot)
+{
+    assert(li.weight != std::numeric_limits<float>::infinity() &&
+           "attempt to spill already spilled interval!");
+    Interval::Ranges oldRanges;
+    swap(oldRanges, li.ranges);
+
+    DEBUG(std::cerr << "\t\t\t\tupdating interval: " << li);
+
+    for (Interval::Ranges::iterator i = oldRanges.begin(), e = oldRanges.end();
+         i != e; ++i) {
+        unsigned index = getBaseIndex(i->first);
+        unsigned end = getBaseIndex(i->second-1) + InstrSlots::NUM;
+        for (; index < end; index += InstrSlots::NUM) {
+            // skip deleted instructions
+            while (!getInstructionFromIndex(index)) index += InstrSlots::NUM;
+            MachineBasicBlock::iterator mi = getInstructionFromIndex(index);
+
+        for_operand:
+            for (unsigned i = 0; i < mi->getNumOperands(); ++i) {
+                MachineOperand& mop = mi->getOperand(i);
+                if (mop.isRegister() && mop.getReg() == li.reg) {
+                    MachineInstr* old = mi;
+                    if (mri_->foldMemoryOperand(mi, i, slot)) {
+                        lv_->instructionChanged(old, mi);
+                        vrm.virtFolded(li.reg, old, mi);
+                        mi2iMap_.erase(old);
+                        i2miMap_[index/InstrSlots::NUM] = mi;
+                        mi2iMap_[mi] = index;
+                        ++numFolded;
+                        goto for_operand;
+                    }
+                    else {
+                        // This is tricky. We need to add information in
+                        // the interval about the spill code so we have to
+                        // use our extra load/store slots.
+                        //
+                        // If we have a use we are going to have a load so
+                        // we start the interval from the load slot
+                        // onwards. Otherwise we start from the def slot.
+                        unsigned start = (mop.isUse() ?
+                                          getLoadIndex(index) :
+                                          getDefIndex(index));
+                        // If we have a def we are going to have a store
+                        // right after it so we end the interval after the
+                        // use of the next instruction. Otherwise we end
+                        // after the use of this instruction.
+                        unsigned end = 1 + (mop.isDef() ?
+                                            getUseIndex(index+InstrSlots::NUM) :
+                                            getUseIndex(index));
+                        li.addRange(start, end);
+                    }
+                }
+            }
+        }
+    }
+    // the new spill weight is now infinity as it cannot be spilled again
+    li.weight = std::numeric_limits<float>::infinity();
+    DEBUG(std::cerr << '\n');
+    DEBUG(std::cerr << "\t\t\t\tupdated interval: " << li << '\n');
+}
+
 void LiveIntervals::printRegName(unsigned reg) const
 {
-    if (reg < MRegisterInfo::FirstVirtualRegister)
+    if (MRegisterInfo::isPhysicalRegister(reg))
         std::cerr << mri_->getName(reg);
     else
-        std::cerr << '%' << reg;
+        std::cerr << "%reg" << reg;
 }
 
 void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
                                              MachineBasicBlock::iterator mi,
                                              unsigned reg)
 {
-    DEBUG(std::cerr << "\t\tregister: ";printRegName(reg); std::cerr << '\n');
-
-    unsigned instrIndex = getInstructionIndex(*mi);
-
+    DEBUG(std::cerr << "\t\tregister: "; printRegName(reg));
     LiveVariables::VarInfo& vi = lv_->getVarInfo(reg);
 
     Interval* interval = 0;
-    Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
-    if (r2iit == r2iMap_.end()) {
+    Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg);
+    if (r2iit == r2iMap_.end() || r2iit->first != reg) {
         // add new interval
         intervals_.push_back(Interval(reg));
         // update interval index for this register
-        bool inserted =
-            r2iMap_.insert(std::make_pair(reg, --intervals_.end())).second;
-        assert(inserted);
+        r2iMap_.insert(r2iit, std::make_pair(reg, --intervals_.end()));
         interval = &intervals_.back();
+
+        // iterate over all of the blocks that the variable is
+        // completely live in, adding them to the live
+        // interval. obviously we only need to do this once.
+        for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) {
+            if (vi.AliveBlocks[i]) {
+                MachineBasicBlock* mbb = lv_->getIndexMachineBasicBlock(i);
+                if (!mbb->empty()) {
+                    interval->addRange(
+                        getInstructionIndex(&mbb->front()),
+                        getInstructionIndex(&mbb->back()) + InstrSlots::NUM);
+                }
+            }
+        }
     }
     else {
         interval = &*r2iit->second;
     }
 
-    for (MbbIndex2MbbMap::iterator
-             it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
-         it != itEnd; ++it) {
-        unsigned liveBlockIndex = it->first;
-        MachineBasicBlock* liveBlock = it->second;
-        if (liveBlockIndex < vi.AliveBlocks.size() &&
-            vi.AliveBlocks[liveBlockIndex] &&
-            !liveBlock->empty()) {
-            unsigned start =  getInstructionIndex(liveBlock->front());
-            unsigned end = getInstructionIndex(liveBlock->back()) + 1;
-            interval->addRange(start, end);
-        }
-    }
+    unsigned baseIndex = getInstructionIndex(mi);
 
     bool killedInDefiningBasicBlock = false;
     for (int i = 0, e = vi.Kills.size(); i != e; ++i) {
         MachineBasicBlock* killerBlock = vi.Kills[i].first;
         MachineInstr* killerInstr = vi.Kills[i].second;
         unsigned start = (mbb == killerBlock ?
-                          instrIndex :
-                          getInstructionIndex(killerBlock->front()));
-        unsigned end = getInstructionIndex(killerInstr) + 1;
+                          getDefIndex(baseIndex) :
+                          getInstructionIndex(&killerBlock->front()));
+        unsigned end = (killerInstr == mi ?
+                         // dead
+                        start + 1 :
+                        // killed
+                        getUseIndex(getInstructionIndex(killerInstr))+1);
+        // we do not want to add invalid ranges. these can happen when
+        // a variable has its latest use and is redefined later on in
+        // the same basic block (common with variables introduced by
+        // PHI elimination)
         if (start < end) {
             killedInDefiningBasicBlock |= mbb == killerBlock;
             interval->addRange(start, end);
@@ -186,9 +316,10 @@
     }
 
     if (!killedInDefiningBasicBlock) {
-        unsigned end = getInstructionIndex(mbb->back()) + 1;
-        interval->addRange(instrIndex, end);
+        unsigned end = getInstructionIndex(&mbb->back()) + InstrSlots::NUM;
+        interval->addRange(getDefIndex(baseIndex), end);
     }
+    DEBUG(std::cerr << '\n');
 }
 
 void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock* mbb,
@@ -196,72 +327,58 @@
                                               unsigned reg)
 {
     DEBUG(std::cerr << "\t\tregister: "; printRegName(reg));
+    typedef LiveVariables::killed_iterator KillIter;
 
-    unsigned start = getInstructionIndex(*mi);
+    MachineBasicBlock::iterator e = mbb->end();
+    unsigned baseIndex = getInstructionIndex(mi);
+    unsigned start = getDefIndex(baseIndex);
     unsigned end = start;
 
-    // register can be dead by the instruction defining it but it can
-    // only be killed by subsequent instructions
-
-    for (LiveVariables::killed_iterator
-             ki = lv_->dead_begin(*mi),
-             ke = lv_->dead_end(*mi);
+    // a variable can be dead by the instruction defining it
+    for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi);
          ki != ke; ++ki) {
         if (reg == ki->second) {
-            end = getInstructionIndex(ki->first) + 1;
-            DEBUG(std::cerr << " dead\n");
+            DEBUG(std::cerr << " dead");
+            end = getDefIndex(start) + 1;
             goto exit;
         }
     }
-    ++mi;
 
-    for (MachineBasicBlock::iterator e = mbb->end(); mi != e; ++mi) {
-        for (LiveVariables::killed_iterator
-                 ki = lv_->dead_begin(*mi),
-                 ke = lv_->dead_end(*mi);
+    // a variable can only be killed by subsequent instructions
+    do {
+        ++mi;
+        baseIndex += InstrSlots::NUM;
+        for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi);
              ki != ke; ++ki) {
             if (reg == ki->second) {
-                end = getInstructionIndex(ki->first) + 1;
-                DEBUG(std::cerr << " dead\n");
+                DEBUG(std::cerr << " killed");
+                end = getUseIndex(baseIndex) + 1;
                 goto exit;
             }
         }
+    } while (mi != e);
 
-        for (LiveVariables::killed_iterator
-                 ki = lv_->killed_begin(*mi),
-                 ke = lv_->killed_end(*mi);
-             ki != ke; ++ki) {
-            if (reg == ki->second) {
-                end = getInstructionIndex(ki->first) + 1;
-                DEBUG(std::cerr << " killed\n");
-                goto exit;
-            }
-        }
-    }
 exit:
     assert(start < end && "did not find end of interval?");
 
-    Reg2IntervalMap::iterator r2iit = r2iMap_.find(reg);
-    if (r2iit != r2iMap_.end()) {
-        Interval& interval = *r2iit->second;
-        interval.addRange(start, end);
+    Reg2IntervalMap::iterator r2iit = r2iMap_.lower_bound(reg);
+    if (r2iit != r2iMap_.end() && r2iit->first == reg) {
+        r2iit->second->addRange(start, end);
     }
     else {
         intervals_.push_back(Interval(reg));
-        Interval& interval = intervals_.back();
         // update interval index for this register
-        bool inserted =
-            r2iMap_.insert(std::make_pair(reg, --intervals_.end())).second;
-        assert(inserted);
-        interval.addRange(start, end);
+        r2iMap_.insert(r2iit, std::make_pair(reg, --intervals_.end()));
+        intervals_.back().addRange(start, end);
     }
+    DEBUG(std::cerr << '\n');
 }
 
 void LiveIntervals::handleRegisterDef(MachineBasicBlock* mbb,
                                       MachineBasicBlock::iterator mi,
                                       unsigned reg)
 {
-    if (reg < MRegisterInfo::FirstVirtualRegister) {
+    if (MRegisterInfo::isPhysicalRegister(reg)) {
         if (lv_->getAllocatablePhysicalRegisters()[reg]) {
             handlePhysicalRegisterDef(mbb, mi, reg);
             for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
@@ -275,144 +392,318 @@
 
 unsigned LiveIntervals::getInstructionIndex(MachineInstr* instr) const
 {
-    assert(mi2iMap_.find(instr) != mi2iMap_.end() &&
-           "instruction not assigned a number");
-    return mi2iMap_.find(instr)->second;
+    Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
+    return (it == mi2iMap_.end() ?
+            std::numeric_limits<unsigned>::max() :
+            it->second);
+}
+
+MachineInstr* LiveIntervals::getInstructionFromIndex(unsigned index) const
+{
+    index /= InstrSlots::NUM; // convert index to vector index
+    assert(index < i2miMap_.size() &&
+           "index does not correspond to an instruction");
+    return i2miMap_[index];
 }
 
 /// computeIntervals - computes the live intervals for virtual
 /// registers. for some ordering of the machine instructions [1,N] a
-/// live interval is an interval [i, j] where 1 <= i <= j <= N for
+/// live interval is an interval [i, j) where 1 <= i <= j < N for
 /// which a variable is live
 void LiveIntervals::computeIntervals()
 {
-    DEBUG(std::cerr << "computing live intervals:\n");
+    DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n");
+    DEBUG(std::cerr << "********** Function: "
+          << mf_->getFunction()->getName() << '\n');
 
     for (MbbIndex2MbbMap::iterator
              it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
          it != itEnd; ++it) {
         MachineBasicBlock* mbb = it->second;
-        DEBUG(std::cerr << "machine basic block: "
-              << mbb->getBasicBlock()->getName() << "\n");
+        DEBUG(std::cerr << mbb->getBasicBlock()->getName() << ":\n");
 
         for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
              mi != miEnd; ++mi) {
-            MachineInstr* instr = *mi;
             const TargetInstrDescriptor& tid =
-                tm_->getInstrInfo().get(instr->getOpcode());
-            DEBUG(std::cerr << "\t[" << getInstructionIndex(instr) << "] ";
-                  instr->print(std::cerr, *tm_););
+                tm_->getInstrInfo().get(mi->getOpcode());
+            DEBUG(std::cerr << getInstructionIndex(mi) << "\t";
+                  mi->print(std::cerr, *tm_));
 
             // handle implicit defs
             for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
                 handleRegisterDef(mbb, mi, *id);
 
             // handle explicit defs
-            for (int i = instr->getNumOperands() - 1; i >= 0; --i) {
-                MachineOperand& mop = instr->getOperand(i);
+            for (int i = mi->getNumOperands() - 1; i >= 0; --i) {
+                MachineOperand& mop = mi->getOperand(i);
+                // handle register defs - build intervals
+                if (mop.isRegister() && mop.getReg() && mop.isDef())
+                    handleRegisterDef(mbb, mi, mop.getReg());
+            }
+        }
+    }
+}
+
+unsigned LiveIntervals::rep(unsigned reg)
+{
+    Reg2RegMap::iterator it = r2rMap_.find(reg);
+    if (it != r2rMap_.end())
+        return it->second = rep(it->second);
+    return reg;
+}
+
+void LiveIntervals::joinIntervals()
+{
+    DEBUG(std::cerr << "********** JOINING INTERVALS ***********\n");
+
+    const TargetInstrInfo& tii = tm_->getInstrInfo();
 
-                if (!mop.isRegister())
+    for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+         mbbi != mbbe; ++mbbi) {
+        MachineBasicBlock* mbb = mbbi;
+        DEBUG(std::cerr << mbb->getBasicBlock()->getName() << ":\n");
+
+        for (MachineBasicBlock::iterator mi = mbb->begin(), mie = mbb->end();
+             mi != mie; ++mi) {
+            const TargetInstrDescriptor& tid =
+                tm_->getInstrInfo().get(mi->getOpcode());
+            DEBUG(std::cerr << getInstructionIndex(mi) << '\t';
+                  mi->print(std::cerr, *tm_););
+
+            // we only join virtual registers with allocatable
+            // physical registers since we do not have liveness information
+            // on not allocatable physical registers
+            unsigned regA, regB;
+            if (tii.isMoveInstr(*mi, regA, regB) &&
+                (MRegisterInfo::isVirtualRegister(regA) ||
+                 lv_->getAllocatablePhysicalRegisters()[regA]) &&
+                (MRegisterInfo::isVirtualRegister(regB) ||
+                 lv_->getAllocatablePhysicalRegisters()[regB])) {
+
+                // get representative registers
+                regA = rep(regA);
+                regB = rep(regB);
+
+                // if they are already joined we continue
+                if (regA == regB)
                     continue;
 
-                // handle defs - build intervals
-                if (mop.isDef())
-                    handleRegisterDef(mbb, mi, mop.getAllocatedRegNum());
+                Reg2IntervalMap::iterator r2iA = r2iMap_.find(regA);
+                assert(r2iA != r2iMap_.end());
+                Reg2IntervalMap::iterator r2iB = r2iMap_.find(regB);
+                assert(r2iB != r2iMap_.end());
+
+                Intervals::iterator intA = r2iA->second;
+                Intervals::iterator intB = r2iB->second;
+
+                // both A and B are virtual registers
+                if (MRegisterInfo::isVirtualRegister(intA->reg) &&
+                    MRegisterInfo::isVirtualRegister(intB->reg)) {
+
+                    const TargetRegisterClass *rcA, *rcB;
+                    rcA = mf_->getSSARegMap()->getRegClass(intA->reg);
+                    rcB = mf_->getSSARegMap()->getRegClass(intB->reg);
+                    assert(rcA == rcB && "registers must be of the same class");
+
+                    // if their intervals do not overlap we join them
+                    if (!intB->overlaps(*intA)) {
+                        intA->join(*intB);
+                        r2iB->second = r2iA->second;
+                        r2rMap_.insert(std::make_pair(intB->reg, intA->reg));
+                        intervals_.erase(intB);
+                    }
+                }
+                else if (MRegisterInfo::isPhysicalRegister(intA->reg) ^
+                         MRegisterInfo::isPhysicalRegister(intB->reg)) {
+                    if (MRegisterInfo::isPhysicalRegister(intB->reg)) {
+                        std::swap(regA, regB);
+                        std::swap(intA, intB);
+                        std::swap(r2iA, r2iB);
+                    }
+
+                    assert(MRegisterInfo::isPhysicalRegister(intA->reg) &&
+                           MRegisterInfo::isVirtualRegister(intB->reg) &&
+                           "A must be physical and B must be virtual");
+
+                    if (!intA->overlaps(*intB) &&
+                         !overlapsAliases(*intA, *intB)) {
+                        intA->join(*intB);
+                        r2iB->second = r2iA->second;
+                        r2rMap_.insert(std::make_pair(intB->reg, intA->reg));
+                        intervals_.erase(intB);
+                    }
+                }
             }
         }
     }
+}
+
+bool LiveIntervals::overlapsAliases(const Interval& lhs,
+                                    const Interval& rhs) const
+{
+    assert(MRegisterInfo::isPhysicalRegister(lhs.reg) &&
+           "first interval must describe a physical register");
+
+    for (const unsigned* as = mri_->getAliasSet(lhs.reg); *as; ++as) {
+        Reg2IntervalMap::const_iterator r2i = r2iMap_.find(*as);
+        assert(r2i != r2iMap_.end() && "alias does not have interval?");
+        if (rhs.overlaps(*r2i->second))
+            return true;
+    }
 
-    intervals_.sort(StartPointComp());
-    DEBUG(std::copy(intervals_.begin(), intervals_.end(),
-                    std::ostream_iterator<Interval>(std::cerr, "\n")));
+    return false;
 }
 
 LiveIntervals::Interval::Interval(unsigned r)
-    : reg(r), hint(0),
-      weight((r < MRegisterInfo::FirstVirtualRegister ?
-              std::numeric_limits<float>::max() : 0.0F))
+    : reg(r),
+      weight((MRegisterInfo::isPhysicalRegister(r) ?
+              std::numeric_limits<float>::infinity() : 0.0F))
 {
 
 }
 
+bool LiveIntervals::Interval::spilled() const
+{
+    return (weight == std::numeric_limits<float>::infinity() &&
+            MRegisterInfo::isVirtualRegister(reg));
+}
+
+// An example for liveAt():
+//
+// this = [1,4), liveAt(0) will return false. The instruction defining
+// this spans slots [0,3]. The interval belongs to an spilled
+// definition of the variable it represents. This is because slot 1 is
+// used (def slot) and spans up to slot 3 (store slot).
+//
+bool LiveIntervals::Interval::liveAt(unsigned index) const
+{
+    Range dummy(index, index+1);
+    Ranges::const_iterator r = std::upper_bound(ranges.begin(),
+                                                ranges.end(),
+                                                dummy);
+    if (r == ranges.begin())
+        return false;
+
+    --r;
+    return index >= r->first && index < r->second;
+}
+
+// An example for overlaps():
+//
+// 0: A = ...
+// 4: B = ...
+// 8: C = A + B ;; last use of A
+//
+// The live intervals should look like:
+//
+// A = [3, 11)
+// B = [7, x)
+// C = [11, y)
+//
+// A->overlaps(C) should return false since we want to be able to join
+// A and C.
+bool LiveIntervals::Interval::overlaps(const Interval& other) const
+{
+    Ranges::const_iterator i = ranges.begin();
+    Ranges::const_iterator ie = ranges.end();
+    Ranges::const_iterator j = other.ranges.begin();
+    Ranges::const_iterator je = other.ranges.end();
+    if (i->first < j->first) {
+        i = std::upper_bound(i, ie, *j);
+        if (i != ranges.begin()) --i;
+    }
+    else if (j->first < i->first) {
+        j = std::upper_bound(j, je, *i);
+        if (j != other.ranges.begin()) --j;
+    }
+
+    while (i != ie && j != je) {
+        if (i->first == j->first) {
+            return true;
+        }
+        else {
+            if (i->first > j->first) {
+                swap(i, j);
+                swap(ie, je);
+            }
+            assert(i->first < j->first);
+
+            if (i->second > j->first) {
+                return true;
+            }
+            else {
+                ++i;
+            }
+        }
+    }
+
+    return false;
+}
+
 void LiveIntervals::Interval::addRange(unsigned start, unsigned end)
 {
-    DEBUG(std::cerr << "\t\t\tadding range: [" << start <<','<< end << ") -> ");
+    assert(start < end && "Invalid range to add!");
+    DEBUG(std::cerr << " +[" << start << ',' << end << ")");
     //assert(start < end && "invalid range?");
     Range range = std::make_pair(start, end);
     Ranges::iterator it =
         ranges.insert(std::upper_bound(ranges.begin(), ranges.end(), range),
                       range);
 
-    mergeRangesForward(it);
-    mergeRangesBackward(it);
-    DEBUG(std::cerr << *this << '\n');
+    it = mergeRangesForward(it);
+    it = mergeRangesBackward(it);
 }
 
-void LiveIntervals::Interval::mergeRangesForward(Ranges::iterator it)
+void LiveIntervals::Interval::join(const LiveIntervals::Interval& other)
 {
-    for (Ranges::iterator next = it + 1;
-         next != ranges.end() && it->second >= next->first; ) {
-        it->second = std::max(it->second, next->second);
-        next = ranges.erase(next);
-    }
-}
+    DEBUG(std::cerr << "\t\tjoining " << *this << " with " << other << '\n');
+    Ranges::iterator cur = ranges.begin();
 
-void LiveIntervals::Interval::mergeRangesBackward(Ranges::iterator it)
-{
-    for (Ranges::iterator prev = it - 1;
-         it != ranges.begin() && it->first <= prev->second; ) {
-        it->first = std::min(it->first, prev->first);
-        it->second = std::max(it->second, prev->second);
-        it = ranges.erase(prev);
-        prev = it - 1;
+    for (Ranges::const_iterator i = other.ranges.begin(),
+             e = other.ranges.end(); i != e; ++i) {
+        cur = ranges.insert(std::upper_bound(cur, ranges.end(), *i), *i);
+        cur = mergeRangesForward(cur);
+        cur = mergeRangesBackward(cur);
     }
+    weight += other.weight;
+    ++numJoins;
 }
 
-bool LiveIntervals::Interval::liveAt(unsigned index) const
+LiveIntervals::Interval::Ranges::iterator
+LiveIntervals::Interval::mergeRangesForward(Ranges::iterator it)
 {
-    Ranges::const_iterator r = ranges.begin();
-    while (r != ranges.end() && index < (r->second - 1)) {
-        if (index >= r->first)
-            return true;
-        ++r;
+    Ranges::iterator n;
+    while ((n = next(it)) != ranges.end()) {
+        if (n->first > it->second)
+            break;
+        it->second = std::max(it->second, n->second);
+        n = ranges.erase(n);
     }
-    return false;
+    return it;
 }
 
-bool LiveIntervals::Interval::overlaps(const Interval& other) const
+LiveIntervals::Interval::Ranges::iterator
+LiveIntervals::Interval::mergeRangesBackward(Ranges::iterator it)
 {
-    Ranges::const_iterator i = ranges.begin();
-    Ranges::const_iterator j = other.ranges.begin();
+    while (it != ranges.begin()) {
+        Ranges::iterator p = prior(it);
+        if (it->first > p->second)
+            break;
 
-    while (i != ranges.end() && j != other.ranges.end()) {
-        if (i->first < j->first) {
-            if ((i->second - 1) > j->first) {
-                return true;
-            }
-            else {
-                ++i;
-            }
-        }
-        else if (j->first < i->first) {
-            if ((j->second - 1) > i->first) {
-                return true;
-            }
-            else {
-                ++j;
-            }
-        }
-        else {
-            return true;
-        }
+        it->first = std::min(it->first, p->first);
+        it->second = std::max(it->second, p->second);
+        it = ranges.erase(p);
     }
 
-    return false;
+    return it;
 }
 
 std::ostream& llvm::operator<<(std::ostream& os,
                                const LiveIntervals::Interval& li)
 {
     os << "%reg" << li.reg << ',' << li.weight << " = ";
+    if (li.empty())
+        return os << "EMPTY";
     for (LiveIntervals::Interval::Ranges::const_iterator
              i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
         os << "[" << i->first << "," << i->second << ")";


Index: llvm/lib/CodeGen/LiveIntervals.h
diff -u llvm/lib/CodeGen/LiveIntervals.h:1.11 llvm/lib/CodeGen/LiveIntervals.h:1.11.2.1
--- llvm/lib/CodeGen/LiveIntervals.h:1.11	Fri Jan 16 14:17:05 2004
+++ llvm/lib/CodeGen/LiveIntervals.h	Mon Mar  1 17:58:13 2004
@@ -9,12 +9,12 @@
 //
 // This file implements the LiveInterval analysis pass.  Given some
 // numbering of each the machine instructions (in this implemention
-// depth-first order) an interval [i, j] is said to be a live interval
+// depth-first order) an interval [i, j) is said to be a live interval
 // for register v if there is no instruction with number j' > j such
 // that v is live at j' abd there is no instruction with number i' < i
 // such that v is live at i'. In this implementation intervals can
-// have holes, i.e. an interval might look like [1,20], [50,65],
-// [1000,1001]
+// have holes, i.e. an interval might look like [1,20), [50,65),
+// [1000,1001)
 //
 //===----------------------------------------------------------------------===//
 
@@ -22,15 +22,13 @@
 #define LLVM_CODEGEN_LIVEINTERVALS_H
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include <iostream>
 #include <list>
-#include <map>
 
 namespace llvm {
 
     class LiveVariables;
     class MRegisterInfo;
+    class VirtRegMap;
 
     class LiveIntervals : public MachineFunctionPass
     {
@@ -39,20 +37,23 @@
             typedef std::pair<unsigned, unsigned> Range;
             typedef std::vector<Range> Ranges;
             unsigned reg;   // the register of this interval
-            unsigned hint;
             float weight;   // weight of this interval (number of uses
                             // * 10^loopDepth)
-            Ranges ranges;  // the ranges this register is valid
+            Ranges ranges;  // the ranges in which this register is live
 
             Interval(unsigned r);
 
+            bool empty() const { return ranges.empty(); }
+
+            bool spilled() const;
+
             unsigned start() const {
-                assert(!ranges.empty() && "empty interval for register");
+                assert(!empty() && "empty interval for register");
                 return ranges.front().first;
             }
 
             unsigned end() const {
-                assert(!ranges.empty() && "empty interval for register");
+                assert(!empty() && "empty interval for register");
                 return ranges.back().second;
             }
 
@@ -66,10 +67,12 @@
 
             void addRange(unsigned start, unsigned end);
 
+            void join(const Interval& other);
+
         private:
-            void mergeRangesForward(Ranges::iterator it);
+            Ranges::iterator mergeRangesForward(Ranges::iterator it);
 
-            void mergeRangesBackward(Ranges::iterator it);
+            Ranges::iterator mergeRangesBackward(Ranges::iterator it);
         };
 
         struct StartPointComp {
@@ -85,7 +88,6 @@
         };
 
         typedef std::list<Interval> Intervals;
-        typedef std::vector<MachineBasicBlock*> MachineBasicBlockPtrs;
 
     private:
         MachineFunction* mf_;
@@ -101,31 +103,76 @@
         typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
         Mi2IndexMap mi2iMap_;
 
+        typedef std::vector<MachineInstr*> Index2MiMap;
+        Index2MiMap i2miMap_;
+
         typedef std::map<unsigned, Intervals::iterator> Reg2IntervalMap;
         Reg2IntervalMap r2iMap_;
 
+        typedef std::map<unsigned, unsigned> Reg2RegMap;
+        Reg2RegMap r2rMap_;
+
         Intervals intervals_;
 
     public:
-        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-        Intervals& getIntervals() { return intervals_; }
-        MachineBasicBlockPtrs getOrderedMachineBasicBlockPtrs() const {
-            MachineBasicBlockPtrs result;
-            for (MbbIndex2MbbMap::const_iterator
-                     it = mbbi2mbbMap_.begin(), itEnd = mbbi2mbbMap_.end();
-                 it != itEnd; ++it) {
-                result.push_back(it->second);
-            }
-            return result;
+        struct InstrSlots
+        {
+            enum {
+                LOAD  = 0,
+                USE   = 1,
+                DEF   = 2,
+                STORE = 3,
+                NUM   = 4,
+            };
+        };
+
+        static unsigned getBaseIndex(unsigned index) {
+            return index - (index % InstrSlots::NUM);
+        }
+        static unsigned getBoundaryIndex(unsigned index) {
+            return getBaseIndex(index + InstrSlots::NUM - 1);
+        }
+        static unsigned getLoadIndex(unsigned index) {
+            return getBaseIndex(index) + InstrSlots::LOAD;
+        }
+        static unsigned getUseIndex(unsigned index) {
+            return getBaseIndex(index) + InstrSlots::USE;
+        }
+        static unsigned getDefIndex(unsigned index) {
+            return getBaseIndex(index) + InstrSlots::DEF;
+        }
+        static unsigned getStoreIndex(unsigned index) {
+            return getBaseIndex(index) + InstrSlots::STORE;
         }
 
-    private:
+        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+        virtual void releaseMemory();
+
         /// runOnMachineFunction - pass entry point
-        bool runOnMachineFunction(MachineFunction&);
+        virtual bool runOnMachineFunction(MachineFunction&);
+
+        Interval& getInterval(unsigned reg) {
+            assert(r2iMap_.count(reg)&& "Interval does not exist for register");
+            return *r2iMap_.find(reg)->second;
+        }
+
+        /// getInstructionIndex - returns the base index of instr
+        unsigned getInstructionIndex(MachineInstr* instr) const;
 
+        /// getInstructionFromIndex - given an index in any slot of an
+        /// instruction return a pointer the instruction
+        MachineInstr* getInstructionFromIndex(unsigned index) const;
+
+        Intervals& getIntervals() { return intervals_; }
+
+        void updateSpilledInterval(Interval& i, VirtRegMap& vrm, int slot);
+
+    private:
         /// computeIntervals - compute live intervals
         void computeIntervals();
 
+        /// joinIntervals - join compatible live intervals
+        void joinIntervals();
 
         /// handleRegisterDef - update intervals for a register def
         /// (calls handlePhysicalRegisterDef and
@@ -146,7 +193,10 @@
                                        MachineBasicBlock::iterator mi,
                                        unsigned reg);
 
-        unsigned getInstructionIndex(MachineInstr* instr) const;
+        bool overlapsAliases(const Interval& lhs, const Interval& rhs) const;
+
+        /// rep - returns the representative of this register
+        unsigned rep(unsigned reg);
 
         void printRegName(unsigned reg) const;
     };


Index: llvm/lib/CodeGen/LiveVariables.cpp
diff -u llvm/lib/CodeGen/LiveVariables.cpp:1.15 llvm/lib/CodeGen/LiveVariables.cpp:1.15.2.1
--- llvm/lib/CodeGen/LiveVariables.cpp:1.15	Tue Jan 13 15:16:25 2004
+++ llvm/lib/CodeGen/LiveVariables.cpp	Mon Mar  1 17:58:13 2004
@@ -28,12 +28,13 @@
 
 #include "llvm/CodeGen/LiveVariables.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/CFG.h"
 #include "Support/DepthFirstIterator.h"
-
-namespace llvm {
+#include "Support/STLExtras.h"
+using namespace llvm;
 
 static RegisterAnalysis<LiveVariables> X("livevars", "Live Variable Analysis");
 
@@ -41,9 +42,25 @@
 LiveVariables::getMachineBasicBlockInfo(MachineBasicBlock *MBB) const{
   return BBMap.find(MBB->getBasicBlock())->second;
 }
+  
+/// getIndexMachineBasicBlock() - Given a block index, return the
+/// MachineBasicBlock corresponding to it.
+MachineBasicBlock *LiveVariables::getIndexMachineBasicBlock(unsigned Idx) {
+  if (BBIdxMap.empty()) {
+    BBIdxMap.resize(BBMap.size());
+    for (std::map<const BasicBlock*, std::pair<MachineBasicBlock*, unsigned> >
+           ::iterator I = BBMap.begin(), E = BBMap.end(); I != E; ++I) {
+      assert(BBIdxMap.size() > I->second.second &&"Indices are not sequential");
+      assert(BBIdxMap[I->second.second] == 0 && "Multiple idx collision!");
+      BBIdxMap[I->second.second] = I->second.first;
+    }
+  }
+  assert(Idx < BBIdxMap.size() && "BB Index out of range!");
+  return BBIdxMap[Idx];
+}
 
 LiveVariables::VarInfo &LiveVariables::getVarInfo(unsigned RegIdx) {
-  assert(RegIdx >= MRegisterInfo::FirstVirtualRegister &&
+  assert(MRegisterInfo::isVirtualRegister(RegIdx) &&
          "getVarInfo: not a virtual register!");
   RegIdx -= MRegisterInfo::FirstVirtualRegister;
   if (RegIdx >= VirtRegInfo.size()) {
@@ -131,29 +148,31 @@
 
   for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
        *AliasSet; ++AliasSet) {
-    if (MachineInstr *LastUse = PhysRegInfo[*AliasSet]) {
-      if (PhysRegUsed[*AliasSet])
-	RegistersKilled.insert(std::make_pair(LastUse, *AliasSet));
+    unsigned Alias = *AliasSet;
+    if (MachineInstr *LastUse = PhysRegInfo[Alias]) {
+      if (PhysRegUsed[Alias])
+	RegistersKilled.insert(std::make_pair(LastUse, Alias));
       else
-	RegistersDead.insert(std::make_pair(LastUse, *AliasSet));
+	RegistersDead.insert(std::make_pair(LastUse, Alias));
     }
-    PhysRegInfo[*AliasSet] = MI;
-    PhysRegUsed[*AliasSet] = false;
+    PhysRegInfo[Alias] = MI;
+    PhysRegUsed[Alias] = false;
   }
 }
 
 bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
+  const TargetInstrInfo &TII = MF.getTarget().getInstrInfo();
+  RegInfo = MF.getTarget().getRegisterInfo();
+  assert(RegInfo && "Target doesn't have register information?");
+
   // First time though, initialize AllocatablePhysicalRegisters for the target
   if (AllocatablePhysicalRegisters.empty()) {
-    const MRegisterInfo &MRI = *MF.getTarget().getRegisterInfo();
-    assert(&MRI && "Target doesn't have register information?");
-
     // Make space, initializing to false...
-    AllocatablePhysicalRegisters.resize(MRegisterInfo::FirstVirtualRegister);
+    AllocatablePhysicalRegisters.resize(RegInfo->getNumRegs());
 
     // Loop over all of the register classes...
-    for (MRegisterInfo::regclass_iterator RCI = MRI.regclass_begin(),
-           E = MRI.regclass_end(); RCI != E; ++RCI)
+    for (MRegisterInfo::regclass_iterator RCI = RegInfo->regclass_begin(),
+           E = RegInfo->regclass_end(); RCI != E; ++RCI)
       // Loop over all of the allocatable registers in the function...
       for (TargetRegisterClass::iterator I = (*RCI)->allocation_order_begin(MF),
              E = (*RCI)->allocation_order_end(MF); I != E; ++I)
@@ -169,16 +188,12 @@
   // physical register.  This is a purely local property, because all physical
   // register references as presumed dead across basic blocks.
   //
-  MachineInstr *PhysRegInfoA[MRegisterInfo::FirstVirtualRegister];
-  bool          PhysRegUsedA[MRegisterInfo::FirstVirtualRegister];
-  std::fill(PhysRegInfoA, PhysRegInfoA+MRegisterInfo::FirstVirtualRegister,
-	    (MachineInstr*)0);
+  MachineInstr *PhysRegInfoA[RegInfo->getNumRegs()];
+  bool          PhysRegUsedA[RegInfo->getNumRegs()];
+  std::fill(PhysRegInfoA, PhysRegInfoA+RegInfo->getNumRegs(), (MachineInstr*)0);
   PhysRegInfo = PhysRegInfoA;
   PhysRegUsed = PhysRegUsedA;
 
-  const TargetInstrInfo &TII = MF.getTarget().getInstrInfo();
-  RegInfo = MF.getTarget().getRegisterInfo();
-
   /// Get some space for a respectable number of registers...
   VirtRegInfo.resize(64);
   
@@ -198,7 +213,7 @@
     // Loop over all of the instructions, processing them.
     for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
 	 I != E; ++I) {
-      MachineInstr *MI = *I;
+      MachineInstr *MI = I;
       const TargetInstrDescriptor &MID = TII.get(MI->getOpcode());
 
       // Process all of the operands of the instruction...
@@ -217,10 +232,10 @@
       // Process all explicit uses...
       for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
 	MachineOperand &MO = MI->getOperand(i);
-	if (MO.isUse()) {
-	  if (MO.isVirtualRegister() && !MO.getVRegValueOrNull()) {
+	if (MO.isUse() && MO.isRegister() && MO.getReg()) {
+	  if (MRegisterInfo::isVirtualRegister(MO.getReg())){
 	    HandleVirtRegUse(getVarInfo(MO.getReg()), MBB, MI);
-	  } else if (MO.isPhysicalRegister() && 
+	  } else if (MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
                      AllocatablePhysicalRegisters[MO.getReg()]) {
 	    HandlePhysRegUse(MO.getReg(), MI);
 	  }
@@ -235,15 +250,15 @@
       // Process all explicit defs...
       for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
 	MachineOperand &MO = MI->getOperand(i);
-	if (MO.isDef()) {
-	  if (MO.isVirtualRegister()) {
+	if (MO.isDef() && MO.isRegister() && MO.getReg()) {
+	  if (MRegisterInfo::isVirtualRegister(MO.getReg())) {
 	    VarInfo &VRInfo = getVarInfo(MO.getReg());
 
 	    assert(VRInfo.DefBlock == 0 && "Variable multiply defined!");
 	    VRInfo.DefBlock = MBB;                           // Created here...
 	    VRInfo.DefInst = MI;
 	    VRInfo.Kills.push_back(std::make_pair(MBB, MI)); // Defaults to dead
-	  } else if (MO.isPhysicalRegister() &&
+	  } else if (MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
                      AllocatablePhysicalRegisters[MO.getReg()]) {
 	    HandlePhysRegDef(MO.getReg(), MI);
 	  }
@@ -260,10 +275,11 @@
       MachineBasicBlock *Succ = BBMap.find(*SI)->second.first;
       
       // PHI nodes are guaranteed to be at the top of the block...
-      for (MachineBasicBlock::iterator I = Succ->begin(), E = Succ->end();
-	   I != E && (*I)->getOpcode() == TargetInstrInfo::PHI; ++I) {
-        MachineInstr *MI = *I;
-	for (unsigned i = 1; ; i += 2)
+      for (MachineBasicBlock::iterator MI = Succ->begin(), ME = Succ->end();
+	   MI != ME && MI->getOpcode() == TargetInstrInfo::PHI; ++MI) {
+	for (unsigned i = 1; ; i += 2) {
+          assert(MI->getNumOperands() > i+1 &&
+                 "Didn't find an entry for our predecessor??");
 	  if (MI->getOperand(i+1).getMachineBasicBlock() == MBB) {
 	    MachineOperand &MO = MI->getOperand(i);
 	    if (!MO.getVRegValueOrNull()) {
@@ -274,12 +290,13 @@
 	      break;   // Found the PHI entry for this block...
 	    }
 	  }
+        }
       }
     }
     
     // Loop over PhysRegInfo, killing any registers that are available at the
     // end of the basic block.  This also resets the PhysRegInfo map.
-    for (unsigned i = 0, e = MRegisterInfo::FirstVirtualRegister; i != e; ++i)
+    for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
       if (PhysRegInfo[i])
 	HandlePhysRegDef(i, 0);
   }
@@ -301,4 +318,44 @@
   return false;
 }
 
-} // End llvm namespace
+/// instructionChanged - When the address of an instruction changes, this
+/// method should be called so that live variables can update its internal
+/// data structures.  This removes the records for OldMI, transfering them to
+/// the records for NewMI.
+void LiveVariables::instructionChanged(MachineInstr *OldMI,
+                                       MachineInstr *NewMI) {
+  // If the instruction defines any virtual registers, update the VarInfo for
+  // the instruction.
+  for (unsigned i = 0, e = NewMI->getNumOperands(); i != e; ++i) {
+    MachineOperand &MO = NewMI->getOperand(i);
+    if (MO.isRegister() && MO.isDef() && MO.getReg() &&
+        MRegisterInfo::isVirtualRegister(MO.getReg())) {
+      unsigned Reg = MO.getReg();
+      VarInfo &VI = getVarInfo(Reg);
+      if (VI.DefInst == OldMI)
+        VI.DefInst = NewMI; 
+    }
+  }
+
+  // Move the killed information over...
+  killed_iterator I, E;
+  tie(I, E) = killed_range(OldMI);
+  std::vector<unsigned> Regs;
+  for (killed_iterator A = I; A != E; ++A)
+    Regs.push_back(A->second);
+  RegistersKilled.erase(I, E);
+
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i)
+    RegistersKilled.insert(std::make_pair(NewMI, Regs[i]));
+  Regs.clear();
+
+
+  // Move the dead information over...
+  tie(I, E) = dead_range(OldMI);
+  for (killed_iterator A = I; A != E; ++A)
+    Regs.push_back(A->second);
+  RegistersDead.erase(I, E);
+
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i)
+    RegistersDead.insert(std::make_pair(NewMI, Regs[i]));
+}


Index: llvm/lib/CodeGen/MachineCodeEmitter.cpp
diff -u llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.14 llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.14.4.1
--- llvm/lib/CodeGen/MachineCodeEmitter.cpp:1.14	Tue Nov 11 16:41:32 2003
+++ llvm/lib/CodeGen/MachineCodeEmitter.cpp	Mon Mar  1 17:58:13 2004
@@ -15,8 +15,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/Function.h"
 #include <fstream>
-
-namespace llvm {
+using namespace llvm;
 
 namespace {
   struct DebugMachineCodeEmitter : public MachineCodeEmitter {
@@ -173,5 +172,3 @@
 MachineCodeEmitter::createFilePrinterEmitter(MachineCodeEmitter &MCE) {
   return new FilePrinterEmitter(MCE, std::cerr);
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/MachineCodeForInstruction.cpp
diff -u llvm/lib/CodeGen/MachineCodeForInstruction.cpp:1.11 llvm/lib/CodeGen/MachineCodeForInstruction.cpp:1.11.2.1
--- llvm/lib/CodeGen/MachineCodeForInstruction.cpp:1.11	Sat Jan 10 13:16:26 2004
+++ llvm/lib/CodeGen/MachineCodeForInstruction.cpp	Mon Mar  1 17:58:13 2004
@@ -24,10 +24,19 @@
 
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineInstrAnnot.h"
+#include "../Target/SparcV9/MachineInstrAnnot.h"
 #include "llvm/Instruction.h"
 using namespace llvm;
 
+MachineCodeForInstruction &MachineCodeForInstruction::get(const Instruction *I){
+  return *(MachineCodeForInstruction*)I->getOrCreateAnnotation(MCFI_AID);
+}
+void MachineCodeForInstruction::destroy(const Instruction *I) {
+  I->deleteAnnotation(MCFI_AID);
+}
+
+
+
 AnnotationID llvm::MCFI_AID(
              AnnotationManager::getID("CodeGen::MachineCodeForInstruction"));
 
@@ -60,9 +69,8 @@
   for (unsigned i=0, N=tempVec.size(); i < N; i++)
     delete tempVec[i];
   
-  // Free the MachineInstr objects allocated, if any.
-  for (unsigned i=0, N = size(); i < N; i++)
-    delete (*this)[i];
+  // do not free the MachineInstr objects allocated. they are managed
+  // by the ilist in MachineBasicBlock
 
   // Free the CallArgsDescriptor if it exists.
   delete callArgsDesc;


Index: llvm/lib/CodeGen/MachineFunction.cpp
diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.46 llvm/lib/CodeGen/MachineFunction.cpp:1.46.2.1
--- llvm/lib/CodeGen/MachineFunction.cpp:1.46	Sat Dec 20 04:20:58 2003
+++ llvm/lib/CodeGen/MachineFunction.cpp	Mon Mar  1 17:58:13 2004
@@ -15,7 +15,6 @@
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -23,7 +22,6 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetCacheInfo.h"
 #include "llvm/Function.h"
 #include "llvm/iOther.h"
 using namespace llvm;
@@ -34,6 +32,12 @@
 
 namespace {
   struct Printer : public MachineFunctionPass {
+    std::ostream *OS;
+    const std::string Banner;
+
+    Printer (std::ostream *_OS, const std::string &_Banner) :
+      OS (_OS), Banner (_Banner) { }
+
     const char *getPassName() const { return "MachineFunction Printer"; }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -41,14 +45,19 @@
     }
 
     bool runOnMachineFunction(MachineFunction &MF) {
-      MF.dump();
+      (*OS) << Banner;
+      MF.print (*OS);
       return false;
     }
   };
 }
 
-FunctionPass *llvm::createMachineFunctionPrinterPass() {
-  return new Printer();
+/// Returns a newly-created MachineFunction Printer pass. The default output
+/// stream is std::cerr; the default banner is empty.
+///
+FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
+                                                     const std::string &Banner) {
+  return new Printer(OS, Banner);
 }
 
 namespace {
@@ -56,14 +65,6 @@
     const char *getPassName() const { return "Machine Code Deleter"; }
 
     bool runOnMachineFunction(MachineFunction &MF) {
-      // Delete all of the MachineInstrs out of the function.  When the sparc
-      // backend gets fixed, this can be dramatically simpler, but actually
-      // putting this stuff into the MachineBasicBlock destructor!
-      for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E;
-           ++BB)
-        while (!BB->empty())
-          delete BB->pop_back();
-
       // Delete the annotation from the function now.
       MachineFunction::destruct(MF.getFunction());
       return true;
@@ -79,6 +80,7 @@
 }
 
 
+
 //===---------------------------------------------------------------------===//
 // MachineFunction implementation
 //===---------------------------------------------------------------------===//
@@ -111,18 +113,11 @@
   // Print Constant Pool
   getConstantPool()->print(OS);
   
-  for (const_iterator BB = begin(); BB != end(); ++BB) {
-    const BasicBlock *LBB = BB->getBasicBlock();
-    OS << "\n" << LBB->getName() << " (" << (const void*)LBB << "):\n";
-    for (MachineBasicBlock::const_iterator I = BB->begin(); I != BB->end();++I){
-      OS << "\t";
-      (*I)->print(OS, Target);
-    }
-  }
+  for (const_iterator BB = begin(); BB != end(); ++BB)
+    BB->print(OS);
   OS << "\nEnd function \"" << Fn->getName() << "\"\n\n";
 }
 
-
 // The next two methods are used to construct and to retrieve
 // the MachineCodeForFunction object for the given function.
 // construct() -- Allocates and initializes for a given function and target
@@ -277,7 +272,7 @@
 inline unsigned
 SizeToAlignment(unsigned size, const TargetMachine& target)
 {
-  unsigned short cacheLineSize = target.getCacheInfo().getCacheLineSize(1); 
+  const unsigned short cacheLineSize = 16;
   if (size > (unsigned) cacheLineSize / 2)
     return cacheLineSize;
   else


Index: llvm/lib/CodeGen/MachineInstr.cpp
diff -u llvm/lib/CodeGen/MachineInstr.cpp:1.82 llvm/lib/CodeGen/MachineInstr.cpp:1.82.2.1
--- llvm/lib/CodeGen/MachineInstr.cpp:1.82	Sun Dec 14 07:24:17 2003
+++ llvm/lib/CodeGen/MachineInstr.cpp	Mon Mar  1 17:58:13 2004
@@ -6,17 +6,22 @@
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
 // 
 //===----------------------------------------------------------------------===//
-// 
+//
+// Methods common to all machine instructions.
+//
+// FIXME: Now that MachineInstrs have parent pointers, they should always
+// print themselves using their MachineFunction's TargetMachine.
+//
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/Value.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/MRegisterInfo.h"
-
-namespace llvm {
+#include "Support/LeakDetector.h"
+using namespace llvm;
 
 // Global variable holding an array of descriptors for machine instructions.
 // The actual object needs to be created separately for each target machine.
@@ -25,15 +30,18 @@
 // FIXME: This should be a property of the target so that more than one target
 // at a time can be active...
 //
-extern const TargetInstrDescriptor *TargetInstrDescriptors;
+namespace llvm {
+  extern const TargetInstrDescriptor *TargetInstrDescriptors;
+}
 
 // Constructor for instructions with variable #operands
-MachineInstr::MachineInstr(MachineOpCode OpCode, unsigned  numOperands)
-  : opCode(OpCode),
-    opCodeFlags(0),
+MachineInstr::MachineInstr(short opcode, unsigned numOperands)
+  : Opcode(opcode),
+    numImplicitRefs(0),
     operands(numOperands, MachineOperand()),
-    numImplicitRefs(0)
-{
+    parent(0) {
+  // Make sure that we get added to a machine basicblock
+  LeakDetector::addGarbageObject(this);
 }
 
 /// MachineInstr ctor - This constructor only does a _reserve_ of the operands,
@@ -41,50 +49,48 @@
 /// add* methods below to fill up the operands, instead of the Set methods.
 /// Eventually, the "resizing" ctors will be phased out.
 ///
-MachineInstr::MachineInstr(MachineOpCode Opcode, unsigned numOperands,
-                           bool XX, bool YY)
-  : opCode(Opcode),
-    opCodeFlags(0),
-    numImplicitRefs(0)
-{
+MachineInstr::MachineInstr(short opcode, unsigned numOperands, bool XX, bool YY)
+  : Opcode(opcode), numImplicitRefs(0), parent(0) {
   operands.reserve(numOperands);
+  // Make sure that we get added to a machine basicblock
+  LeakDetector::addGarbageObject(this);
 }
 
 /// MachineInstr ctor - Work exactly the same as the ctor above, except that the
 /// MachineInstr is created and added to the end of the specified basic block.
 ///
-MachineInstr::MachineInstr(MachineBasicBlock *MBB, MachineOpCode Opcode,
+MachineInstr::MachineInstr(MachineBasicBlock *MBB, short opcode,
                            unsigned numOperands)
-  : opCode(Opcode),
-    opCodeFlags(0),
-    numImplicitRefs(0)
-{
+  : Opcode(opcode), numImplicitRefs(0), parent(0) {
   assert(MBB && "Cannot use inserting ctor with null basic block!");
   operands.reserve(numOperands);
+  // Make sure that we get added to a machine basicblock
+  LeakDetector::addGarbageObject(this);
   MBB->push_back(this);  // Add instruction to end of basic block!
 }
 
-
-// OperandComplete - Return true if it's illegal to add a new operand
-bool MachineInstr::OperandsComplete() const
+MachineInstr::~MachineInstr()
 {
-  int NumOperands = TargetInstrDescriptors[opCode].numOperands;
+  LeakDetector::removeGarbageObject(this);
+}
+
+/// OperandComplete - Return true if it's illegal to add a new operand
+///
+bool MachineInstr::OperandsComplete() const {
+  int NumOperands = TargetInstrDescriptors[Opcode].numOperands;
   if (NumOperands >= 0 && getNumOperands() >= (unsigned)NumOperands)
     return true;  // Broken: we have all the operands of this instruction!
   return false;
 }
 
-
-// 
-// Support for replacing opcode and operands of a MachineInstr in place.
-// This only resets the size of the operand vector and initializes it.
-// The new operands must be set explicitly later.
-// 
-void MachineInstr::replace(MachineOpCode Opcode, unsigned numOperands)
-{
+/// replace - Support for replacing opcode and operands of a MachineInstr in
+/// place. This only resets the size of the operand vector and initializes it.
+/// The new operands must be set explicitly later.
+/// 
+void MachineInstr::replace(short opcode, unsigned numOperands) {
   assert(getNumImplicitRefs() == 0 &&
          "This is probably broken because implicit refs are going to be lost.");
-  opCode = Opcode;
+  Opcode = opcode;
   operands.clear();
   operands.resize(numOperands, MachineOperand());
 }
@@ -100,14 +106,13 @@
 
 void
 MachineInstr::SetMachineOperandConst(unsigned i,
-				MachineOperand::MachineOperandType operandType,
-                                     int64_t intValue)
-{
+                                     MachineOperand::MachineOperandType opTy,
+                                     int intValue) {
   assert(i < getNumOperands());          // must be explicit op
-  assert(TargetInstrDescriptors[opCode].resultPos != (int) i &&
+  assert(TargetInstrDescriptors[Opcode].resultPos != (int) i &&
          "immed. constant cannot be defined");
 
-  operands[i].opType = operandType;
+  operands[i].opType = opTy;
   operands[i].value = NULL;
   operands[i].immedVal = intValue;
   operands[i].regNum = -1;
@@ -122,23 +127,24 @@
   operands[i].regNum = regNum;
 }
 
-void
-MachineInstr::SetRegForOperand(unsigned i, int regNum)
-{
+// Used only by the SPARC back-end.
+void MachineInstr::SetRegForOperand(unsigned i, int regNum) {
   assert(i < getNumOperands());          // must be explicit op
   operands[i].setRegForValue(regNum);
 }
 
-void
-MachineInstr::SetRegForImplicitRef(unsigned i, int regNum)
-{
+// Used only by the SPARC back-end.
+void MachineInstr::SetRegForImplicitRef(unsigned i, int regNum) {
   getImplicitOp(i).setRegForValue(regNum);
 }
 
-
-// Substitute all occurrences of Value* oldVal with newVal in all operands
-// and all implicit refs.
-// If defsOnly == true, substitute defs only.
+/// substituteValue - Substitute all occurrences of Value* oldVal with newVal
+/// in all operands and all implicit refs. If defsOnly == true, substitute defs
+/// only.
+///
+/// FIXME: Fold this into its single caller, at SparcInstrSelection.cpp:2865,
+/// or make it a static function in that file.
+///
 unsigned
 MachineInstr::substituteValue(const Value* oldVal, Value* newVal,
                               bool defsOnly, bool notDefsAndUses,
@@ -178,32 +184,28 @@
   return numSubst;
 }
 
-
-void
-MachineInstr::dump() const 
-{
+void MachineInstr::dump() const {
   std::cerr << "  " << *this;
 }
 
-static inline std::ostream&
-OutputValue(std::ostream &os, const Value* val)
-{
+static inline std::ostream& OutputValue(std::ostream &os, const Value* val) {
   os << "(val ";
   os << (void*) val;                    // print address always
   if (val && val->hasName())
-    os << " " << val->getName() << ")"; // print name also, if available
+    os << " " << val->getName(); // print name also, if available
+  os << ")";
   return os;
 }
 
 static inline void OutputReg(std::ostream &os, unsigned RegNo,
                              const MRegisterInfo *MRI = 0) {
-  if (MRI) {
-    if (RegNo < MRegisterInfo::FirstVirtualRegister)
+  if (!RegNo || MRegisterInfo::isPhysicalRegister(RegNo)) {
+    if (MRI)
       os << "%" << MRI->get(RegNo).Name;
     else
-      os << "%reg" << RegNo;
+      os << "%mreg(" << RegNo << ")";
   } else
-    os << "%mreg(" << RegNo << ")";
+    os << "%reg" << RegNo;
 }
 
 static void print(const MachineOperand &MO, std::ostream &OS,
@@ -230,14 +232,14 @@
         OS << "==";
     }
     if (MO.hasAllocatedReg())
-      OutputReg(OS, MO.getAllocatedRegNum(), MRI);
+      OutputReg(OS, MO.getReg(), MRI);
     break;
   case MachineOperand::MO_CCRegister:
     OS << "%ccreg";
     OutputValue(OS, MO.getVRegValue());
     if (MO.hasAllocatedReg()) {
       OS << "==";
-      OutputReg(OS, MO.getAllocatedRegNum(), MRI);
+      OutputReg(OS, MO.getReg(), MRI);
     }
     break;
   case MachineOperand::MO_MachineRegister:
@@ -290,7 +292,7 @@
 
    // Specialize printing if op#0 is definition
   if (getNumOperands() && getOperand(0).isDef() && !getOperand(0).isUse()) {
-      llvm::print(getOperand(0), OS, TM);
+    ::print(getOperand(0), OS, TM);
     OS << " = ";
     ++StartOp;   // Don't print this operand again!
   }
@@ -301,7 +303,7 @@
     if (i != StartOp)
       OS << ",";
     OS << " ";
-    llvm::print(mop, OS, TM);
+    ::print(mop, OS, TM);
     
     if (mop.isDef())
       if (mop.isUse())
@@ -327,10 +329,19 @@
   OS << "\n";
 }
 
+namespace llvm {
+std::ostream &operator<<(std::ostream &os, const MachineInstr &MI) {
+  // If the instruction is embedded into a basic block, we can find the target
+  // info for the instruction.
+  if (const MachineBasicBlock *MBB = MI.getParent()) {
+    const MachineFunction *MF = MBB->getParent();
+    MI.print(os, MF->getTarget());
+    return os;
+  }
 
-std::ostream &operator<<(std::ostream& os, const MachineInstr& MI)
-{
-  os << TargetInstrDescriptors[MI.opCode].Name;
+  // Otherwise, print it out in the "raw" format without symbolic register names
+  // and such.
+  os << TargetInstrDescriptors[MI.getOpcode()].Name;
   
   for (unsigned i=0, N=MI.getNumOperands(); i < N; i++) {
     os << "\t" << MI.getOperand(i);
@@ -359,8 +370,7 @@
   return os << "\n";
 }
 
-std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO)
-{
+std::ostream &operator<<(std::ostream &OS, const MachineOperand &MO) {
   if (MO.isHiBits32())
     OS << "%lm(";
   else if (MO.isLoBits32())
@@ -374,7 +384,7 @@
     {
     case MachineOperand::MO_VirtualRegister:
       if (MO.hasAllocatedReg())
-        OutputReg(OS, MO.getAllocatedRegNum());
+        OutputReg(OS, MO.getReg());
 
       if (MO.getVRegValue()) {
 	if (MO.hasAllocatedReg()) OS << "==";
@@ -387,7 +397,7 @@
       OutputValue(OS, MO.getVRegValue());
       if (MO.hasAllocatedReg()) {
         OS << "==";
-        OutputReg(OS, MO.getAllocatedRegNum());
+        OutputReg(OS, MO.getReg());
       }
       break;
     case MachineOperand::MO_MachineRegister:
@@ -433,12 +443,10 @@
       break;
     }
   
-  if (MO.flags &
-      (MachineOperand::HIFLAG32 | MachineOperand::LOFLAG32 | 
-       MachineOperand::HIFLAG64 | MachineOperand::LOFLAG64))
+  if (MO.isHiBits32() || MO.isLoBits32() || MO.isHiBits64() || MO.isLoBits64())
     OS << ")";
   
   return OS;
 }
 
-} // End llvm namespace
+}


Index: llvm/lib/CodeGen/MachineInstrAnnot.cpp
diff -u llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.10 llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.10.4.1
--- llvm/lib/CodeGen/MachineInstrAnnot.cpp:1.10	Tue Nov 11 16:41:32 2003
+++ llvm/lib/CodeGen/MachineInstrAnnot.cpp	Mon Mar  1 17:58:13 2004
@@ -12,13 +12,12 @@
 // 
 //===----------------------------------------------------------------------===//
 
-#include "llvm/CodeGen/MachineInstrAnnot.h"
+#include "../Target/SparcV9/MachineInstrAnnot.h"
 #include "llvm/CodeGen/InstrSelection.h"
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/iOther.h"
 #include "llvm/Type.h"
-
-namespace llvm {
+using namespace llvm;
 
 CallArgsDescriptor::CallArgsDescriptor(CallInst* _callInstr,
                                        TmpInstruction* _retAddrReg,
@@ -77,5 +76,3 @@
   assert(desc->getCallInst()==callInstr && "Incorrect call args descriptor?");
   return desc;
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/PHIElimination.cpp
diff -u llvm/lib/CodeGen/PHIElimination.cpp:1.14 llvm/lib/CodeGen/PHIElimination.cpp:1.14.2.1
--- llvm/lib/CodeGen/PHIElimination.cpp:1.14	Sun Dec 14 07:24:17 2003
+++ llvm/lib/CodeGen/PHIElimination.cpp	Mon Mar  1 17:58:13 2004
@@ -13,6 +13,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/SSARegMap.h"
@@ -20,8 +21,8 @@
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/CFG.h"
-
-namespace llvm {
+#include "Support/STLExtras.h"
+using namespace llvm;
 
 namespace {
   struct PNE : public MachineFunctionPass {
@@ -55,28 +56,28 @@
 }
 
 
-const PassInfo *PHIEliminationID = X.getPassInfo();
+const PassInfo *llvm::PHIEliminationID = X.getPassInfo();
 
 /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in
 /// predecessor basic blocks.
 ///
 bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {
-  if (MBB.empty() || MBB.front()->getOpcode() != TargetInstrInfo::PHI)
+  if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)
     return false;   // Quick exit for normal case...
 
   LiveVariables *LV = getAnalysisToUpdate<LiveVariables>();
   const TargetInstrInfo &MII = MF.getTarget().getInstrInfo();
   const MRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
 
-  while (MBB.front()->getOpcode() == TargetInstrInfo::PHI) {
-    MachineInstr *MI = MBB.front();
+  while (MBB.front().getOpcode() == TargetInstrInfo::PHI) {
     // Unlink the PHI node from the basic block... but don't delete the PHI yet
-    MBB.erase(MBB.begin());
-
-    assert(MI->getOperand(0).isVirtualRegister() &&
+    MachineBasicBlock::iterator begin = MBB.begin();
+    MachineInstr *MI = MBB.remove(begin);
+    
+    assert(MRegisterInfo::isVirtualRegister(MI->getOperand(0).getReg()) &&
            "PHI node doesn't write virt reg?");
 
-    unsigned DestReg = MI->getOperand(0).getAllocatedRegNum();
+    unsigned DestReg = MI->getOperand(0).getReg();
     
     // Create a new register for the incoming PHI arguments
     const TargetRegisterClass *RC = MF.getSSARegMap()->getRegClass(DestReg);
@@ -88,13 +89,13 @@
     //
     MachineBasicBlock::iterator AfterPHIsIt = MBB.begin();
     while (AfterPHIsIt != MBB.end() &&
-           (*AfterPHIsIt)->getOpcode() == TargetInstrInfo::PHI)
+           AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI)
       ++AfterPHIsIt;    // Skip over all of the PHI nodes...
     RegInfo->copyRegToReg(MBB, AfterPHIsIt, DestReg, IncomingReg, RC);
     
     // Update live variable information if there is any...
     if (LV) {
-      MachineInstr *PHICopy = *(AfterPHIsIt-1);
+      MachineInstr *PHICopy = --AfterPHIsIt;
 
       // Add information to LiveVariables to know that the incoming value is
       // killed.  Note that because the value is defined in several places (once
@@ -142,22 +143,7 @@
       // source path the PHI.
       MachineBasicBlock &opBlock = *MI->getOperand(i).getMachineBasicBlock();
 
-      // Figure out where to insert the copy, which is at the end of the
-      // predecessor basic block, but before any terminator/branch
-      // instructions...
-      MachineBasicBlock::iterator I = opBlock.end();
-      if (I != opBlock.begin()) {  // Handle empty blocks
-        --I;
-        // must backtrack over ALL the branches in the previous block
-        while (MII.isTerminatorInstr((*I)->getOpcode()) &&
-               I != opBlock.begin())
-          --I;
-        
-        // move back to the first branch instruction so new instructions
-        // are inserted right in front of it and not in front of a non-branch
-        if (!MII.isTerminatorInstr((*I)->getOpcode()))
-          ++I;
-      }
+      MachineBasicBlock::iterator I = opBlock.getFirstTerminator();
       
       // Check to make sure we haven't already emitted the copy for this block.
       // This can happen because PHI nodes may have multiple entries for the
@@ -171,10 +157,10 @@
       bool HaveNotEmitted = true;
       
       if (I != opBlock.begin()) {
-        MachineInstr *PrevInst = *(I-1);
+        MachineBasicBlock::iterator PrevInst = prior(I);
         for (unsigned i = 0, e = PrevInst->getNumOperands(); i != e; ++i) {
           MachineOperand &MO = PrevInst->getOperand(i);
-          if (MO.isVirtualRegister() && MO.getReg() == IncomingReg)
+          if (MO.isRegister() && MO.getReg() == IncomingReg)
             if (MO.isDef()) {
               HaveNotEmitted = false;
               break;
@@ -183,7 +169,7 @@
       }
 
       if (HaveNotEmitted) { // If the copy has not already been emitted, do it.
-        assert(opVal.isVirtualRegister() &&
+        assert(MRegisterInfo::isVirtualRegister(opVal.getReg()) &&
                "Machine PHI Operands must all be virtual registers!");
         unsigned SrcReg = opVal.getReg();
         RegInfo->copyRegToReg(opBlock, I, IncomingReg, SrcReg, RC);
@@ -238,10 +224,10 @@
             // Loop over all of the PHIs in this successor, checking to see if
             // the register is being used...
             for (MachineBasicBlock::iterator BBI = MBB->begin(), E=MBB->end();
-                 BBI != E && (*BBI)->getOpcode() == TargetInstrInfo::PHI;
+                 BBI != E && BBI->getOpcode() == TargetInstrInfo::PHI;
                  ++BBI)
-              for (unsigned i = 1, e = (*BBI)->getNumOperands(); i < e; i += 2)
-                if ((*BBI)->getOperand(i).getReg() == SrcReg) {
+              for (unsigned i = 1, e = BBI->getNumOperands(); i < e; i += 2)
+                if (BBI->getOperand(i).getReg() == SrcReg) {
                   ValueIsLive = true;
                   break;
                 }
@@ -251,8 +237,10 @@
           // we can add a kill marker to the copy we inserted saying that it
           // kills the incoming value!
           //
-          if (!ValueIsLive)
-            LV->addVirtualRegisterKilled(SrcReg, &opBlock, *(I-1));
+          if (!ValueIsLive) {
+            MachineBasicBlock::iterator Prev = prior(I);
+            LV->addVirtualRegisterKilled(SrcReg, &opBlock, Prev);
+          }
         }
       }
     }
@@ -260,8 +248,5 @@
     // really delete the PHI instruction now!
     delete MI;
   }
-
   return true;
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/Passes.cpp
diff -u llvm/lib/CodeGen/Passes.cpp:1.5 llvm/lib/CodeGen/Passes.cpp:1.5.2.1
--- llvm/lib/CodeGen/Passes.cpp:1.5	Sun Dec 28 01:59:53 2003
+++ llvm/lib/CodeGen/Passes.cpp	Mon Mar  1 17:58:13 2004
@@ -26,7 +26,7 @@
            cl::Prefix,
            cl::values(clEnumVal(simple,      "  simple register allocator"),
                       clEnumVal(local,       "  local register allocator"),
-                      clEnumVal(linearscan,  "  linear-scan global register allocator"),
+                      clEnumVal(linearscan,  "  linear scan register allocator (experimental)"),
                       0),
            cl::init(local));
 }


Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.16 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.16.2.1
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.16	Sun Dec 14 07:24:16 2003
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp	Mon Mar  1 17:58:13 2004
@@ -24,8 +24,7 @@
 #include "llvm/Target/MRegisterInfo.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
-
-namespace llvm {
+using namespace llvm;
 
 namespace {
   struct PEI : public MachineFunctionPass {
@@ -72,7 +71,7 @@
 /// createPrologEpilogCodeInserter - This function returns a pass that inserts
 /// prolog and epilog code, and eliminates abstract frame references.
 ///
-FunctionPass *createPrologEpilogCodeInserter() { return new PEI(); }
+FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); }
 
 
 /// saveCallerSavedRegisters - Scan the function for modified caller saved
@@ -99,28 +98,29 @@
     return;
 
   // This bitset contains an entry for each physical register for the target...
-  std::vector<bool> ModifiedRegs(MRegisterInfo::FirstVirtualRegister);
+  std::vector<bool> ModifiedRegs(RegInfo->getNumRegs());
   unsigned MaxCallFrameSize = 0;
   bool HasCalls = false;
 
   for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
     for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); )
-      if ((*I)->getOpcode() == FrameSetupOpcode ||
-	  (*I)->getOpcode() == FrameDestroyOpcode) {
-	assert((*I)->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo"
+      if (I->getOpcode() == FrameSetupOpcode ||
+	  I->getOpcode() == FrameDestroyOpcode) {
+	assert(I->getNumOperands() == 1 && "Call Frame Setup/Destroy Pseudo"
 	       " instructions should have a single immediate argument!");
-	unsigned Size = (*I)->getOperand(0).getImmedValue();
+	unsigned Size = I->getOperand(0).getImmedValue();
 	if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
 	HasCalls = true;
-	RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I);
+	RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++);
       } else {
-	for (unsigned i = 0, e = (*I)->getNumOperands(); i != e; ++i) {
-	  MachineOperand &MO = (*I)->getOperand(i);
-	  assert(!MO.isVirtualRegister() &&
-		 "Register allocation must be performed!");
-	  if (MO.isPhysicalRegister() && MO.isDef())
+	for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+	  MachineOperand &MO = I->getOperand(i);
+	  if (MO.isRegister() && MO.isDef()) {
+            assert(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+                   "Register allocation must be performed!");
 	    ModifiedRegs[MO.getReg()] = true;         // Register is modified
-	}
+          }
+        }
 	++I;
       }
 
@@ -173,8 +173,9 @@
   const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
   for (MachineFunction::iterator FI = Fn.begin(), E = Fn.end(); FI != E; ++FI) {
     // If last instruction is a return instruction, add an epilogue
-    if (!FI->empty() && TII.isReturn(FI->back()->getOpcode())) {
-      MBB = FI; I = MBB->end()-1;
+    if (!FI->empty() && TII.isReturn(FI->back().getOpcode())) {
+      MBB = FI;
+      I = MBB->end(); --I;
 
       for (unsigned i = 0, e = RegsToSave.size(); i != e; ++i) {
 	const TargetRegisterClass *RC = RegInfo->getRegClass(RegsToSave[i]);
@@ -201,8 +202,18 @@
 
   unsigned StackAlignment = TFI.getStackAlignment();
 
-  // Start at the beginning of the local area...
+  // Start at the beginning of the local area.
   int Offset = TFI.getOffsetOfLocalArea();
+
+  // Check to see if there are any fixed sized objects that are preallocated in
+  // the local area.  We currently don't support filling in holes in between
+  // fixed sized objects, so we just skip to the end of the last fixed sized
+  // preallocated object.
+  for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
+    int FixedOff = -FFI->getObjectOffset(i);
+    if (FixedOff > Offset) Offset = FixedOff;
+  }
+
   for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
     Offset += FFI->getObjectSize(i);         // Allocate Size bytes...
 
@@ -214,8 +225,11 @@
     FFI->setObjectOffset(i, -Offset);        // Set the computed offset
   }
 
-  // Align the final stack pointer offset...
-  Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment;
+  // Align the final stack pointer offset, but only if there are calls in the
+  // function.  This ensures that any calls to subroutines have their stack
+  // frames suitable aligned.
+  if (FFI->hasCalls())
+    Offset = (Offset+StackAlignment-1)/StackAlignment*StackAlignment;
 
   // Set the final value of the stack pointer...
   FFI->setStackSize(Offset-TFI.getOffsetOfLocalArea());
@@ -234,7 +248,7 @@
   const TargetInstrInfo &TII = Fn.getTarget().getInstrInfo();
   for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
     // If last instruction is a return instruction, add an epilogue
-    if (!I->empty() && TII.isReturn(I->back()->getOpcode()))
+    if (!I->empty() && TII.isReturn(I->back().getOpcode()))
       Fn.getTarget().getRegisterInfo()->emitEpilogue(Fn, *I);
   }
 }
@@ -252,13 +266,11 @@
 
   for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
     for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
-      for (unsigned i = 0, e = (*I)->getNumOperands(); i != e; ++i)
-	if ((*I)->getOperand(i).isFrameIndex()) {
+      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+	if (I->getOperand(i).isFrameIndex()) {
 	  // If this instruction has a FrameIndex operand, we need to use that
 	  // target machine register info object to eliminate it.
 	  MRI.eliminateFrameIndex(Fn, I);
 	  break;
 	}
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/RegAllocLinearScan.cpp
diff -u llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.31 llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.31.2.1
--- llvm/lib/CodeGen/RegAllocLinearScan.cpp:1.31	Fri Jan 16 14:33:13 2004
+++ llvm/lib/CodeGen/RegAllocLinearScan.cpp	Mon Mar  1 17:58:13 2004
@@ -10,56 +10,41 @@
 // This file implements a linear scan register allocator.
 //
 //===----------------------------------------------------------------------===//
+
 #define DEBUG_TYPE "regalloc"
 #include "llvm/Function.h"
-#include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/CodeGen/MachineFrameInfo.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/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/CFG.h"
 #include "Support/Debug.h"
-#include "Support/DepthFirstIterator.h"
-#include "Support/Statistic.h"
-#include "Support/STLExtras.h"
+#include "LiveIntervals.h"
+#include "PhysRegTracker.h"
+#include "VirtRegMap.h"
+#include <algorithm>
+#include <iostream>
+
 using namespace llvm;
 
 namespace {
-    Statistic<> numSpilled ("ra-linearscan", "Number of registers spilled");
-    Statistic<> numReloaded("ra-linearscan", "Number of registers reloaded");
-
     class RA : public MachineFunctionPass {
     private:
         MachineFunction* mf_;
         const TargetMachine* tm_;
         const MRegisterInfo* mri_;
-        MachineFunction::iterator currentMbb_;
-        MachineBasicBlock::iterator currentInstr_;
-        typedef std::vector<const LiveIntervals::Interval*> IntervalPtrs;
-        IntervalPtrs unhandled_, fixed_, active_, inactive_;
-
-        typedef std::vector<unsigned> Regs;
-        Regs tempUseOperands_;
-        Regs tempDefOperands_;
-
-        typedef std::vector<bool> RegMask;
-        RegMask reserved_;
-
-        unsigned regUse_[MRegisterInfo::FirstVirtualRegister];
-        unsigned regUseBackup_[MRegisterInfo::FirstVirtualRegister];
+        LiveIntervals* li_;
+        typedef std::list<LiveIntervals::Interval*> IntervalPtrs;
+        IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_;
+
+        std::auto_ptr<PhysRegTracker> prt_;
+        std::auto_ptr<VirtRegMap> vrm_;
+        std::auto_ptr<Spiller> spiller_;
 
-        typedef std::map<unsigned, unsigned> Virt2PhysMap;
-        Virt2PhysMap v2pMap_;
-
-        typedef std::map<unsigned, int> Virt2StackSlotMap;
-        Virt2StackSlotMap v2ssMap_;
-
-        int instrAdded_;
+        typedef std::vector<float> SpillWeights;
+        SpillWeights spillWeights_;
 
     public:
         virtual const char* getPassName() const {
@@ -72,13 +57,18 @@
             MachineFunctionPass::getAnalysisUsage(AU);
         }
 
-    private:
         /// runOnMachineFunction - register allocate the whole function
         bool runOnMachineFunction(MachineFunction&);
 
+        void releaseMemory();
+
+    private:
+        /// linearScan - the linear scan algorithm
+        void linearScan();
+
         /// initIntervalSets - initializa the four interval sets:
         /// unhandled, fixed, active and inactive
-        void initIntervalSets(const LiveIntervals::Intervals& li);
+        void initIntervalSets(LiveIntervals::Intervals& li);
 
         /// processActiveIntervals - expire old intervals and move
         /// non-overlapping ones to the incative list
@@ -88,11 +78,13 @@
         /// overlapping ones to the active list
         void processInactiveIntervals(IntervalPtrs::value_type cur);
 
-        /// assignStackSlotAtInterval - choose and spill
-        /// interval. Currently we spill the interval with the last
-        /// end point in the active and inactive lists and the current
-        /// interval
-        void assignStackSlotAtInterval(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 assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur);
 
         ///
         /// register handling helpers
@@ -103,321 +95,146 @@
         /// 0
         unsigned getFreePhysReg(IntervalPtrs::value_type cur);
 
-        /// physRegAvailable - returns true if the specifed physical
-        /// register is available
-        bool physRegAvailable(unsigned physReg);
-
-        /// tempPhysRegAvailable - returns true if the specifed
-        /// temporary physical register is available
-        bool tempPhysRegAvailable(unsigned physReg);
-
-        /// getFreeTempPhysReg - return a free temprorary physical
-        /// register for this virtual register if we have one (should
-        /// never return 0)
-        unsigned getFreeTempPhysReg(unsigned virtReg);
-
-        /// assignVirt2PhysReg - assigns the free physical register to
-        /// the virtual register passed as arguments
-        void assignVirt2PhysReg(unsigned virtReg, unsigned physReg);
-
-        /// clearVirtReg - free the physical register associated with this
-        /// virtual register and disassociate virtual->physical and
-        /// physical->virtual mappings
-        void clearVirtReg(unsigned virtReg);
-
         /// assignVirt2StackSlot - assigns this virtual register to a
-        /// stack slot
-        void assignVirt2StackSlot(unsigned virtReg);
-
-        /// getStackSlot - returns the offset of the specified
-        /// register on the stack
-        int getStackSlot(unsigned virtReg);
-
-        /// spillVirtReg - spills the virtual register
-        void spillVirtReg(unsigned virtReg);
-
-        /// loadPhysReg - loads to the physical register the value of
-        /// the virtual register specifed. Virtual register must have
-        /// an assigned stack slot
-        void loadVirt2PhysReg(unsigned virtReg, unsigned physReg);
-
-        void markPhysRegFree(unsigned physReg);
-        void markPhysRegNotFree(unsigned physReg);
-
-        void backupRegUse() {
-            memcpy(regUseBackup_, regUse_, sizeof(regUseBackup_));
-        }
-
-        void restoreRegUse() {
-            memcpy(regUse_, regUseBackup_, sizeof(regUseBackup_));
-        }
-
-        void printVirt2PhysMap() const {
-            std::cerr << "allocated registers:\n";
-            for (Virt2PhysMap::const_iterator
-                     i = v2pMap_.begin(), e = v2pMap_.end(); i != e; ++i) {
-                std::cerr << '[' << i->first << ','
-                          << mri_->getName(i->second) << "]\n";
-            }
-            std::cerr << '\n';
-        }
+        /// 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\t" << **i << " -> ";
+                std::cerr << "\t" << **i << " -> ";
                 unsigned reg = (*i)->reg;
-                if (reg >= MRegisterInfo::FirstVirtualRegister) {
-                    Virt2PhysMap::const_iterator it = v2pMap_.find(reg);
-                    reg = (it == v2pMap_.end() ? 0 : it->second);
+                if (MRegisterInfo::isVirtualRegister(reg)) {
+                    reg = vrm_->getPhys(reg);
                 }
                 std::cerr << mri_->getName(reg) << '\n';
             }
         }
 
-        void printFreeRegs(const char* const str,
-                           const TargetRegisterClass* rc) const {
-            if (str) std::cerr << str << ':';
-            for (TargetRegisterClass::iterator i =
-                     rc->allocation_order_begin(*mf_);
-                 i != rc->allocation_order_end(*mf_); ++i) {
-                unsigned reg = *i;
-                if (!regUse_[reg]) {
-                    std::cerr << ' ' << mri_->getName(reg);
-                    if (reserved_[reg]) std::cerr << "*";
-                }
-            }
-            std::cerr << '\n';
-        }
+//         void verifyAssignment() const {
+//             for (Virt2PhysMap::const_iterator i = v2pMap_.begin(),
+//                      e = v2pMap_.end(); i != e; ++i)
+//                 for (Virt2PhysMap::const_iterator i2 = next(i); i2 != e; ++i2)
+//                     if (MRegisterInfo::isVirtualRegister(i->second) &&
+//                         (i->second == i2->second ||
+//                          mri_->areAliases(i->second, i2->second))) {
+//                         const LiveIntervals::Interval
+//                             &in = li_->getInterval(i->second),
+//                             &in2 = li_->getInterval(i2->second);
+//                         if (in.overlaps(in2)) {
+//                             std::cerr << in << " overlaps " << in2 << '\n';
+//                             assert(0);
+//                         }
+//                     }
+//         }
     };
 }
 
+void RA::releaseMemory()
+{
+    unhandled_.clear();
+    active_.clear();
+    inactive_.clear();
+    fixed_.clear();
+    handled_.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(getAnalysis<LiveIntervals>().getIntervals());
+    initIntervalSets(li_->getIntervals());
 
-    v2pMap_.clear();
-    v2ssMap_.clear();
-    memset(regUse_, 0, sizeof(regUse_));
-    memset(regUseBackup_, 0, sizeof(regUseBackup_));
-
-    // FIXME: this will work only for the X86 backend. I need to
-    // device an algorthm to select the minimal (considering register
-    // aliasing) number of temp registers to reserve so that we have 2
-    // registers for each register class available.
-
-    // reserve R8:   CH,  CL
-    //         R16:  CX,  DI,
-    //         R32: ECX, EDI,
-    //         RFP: FP5, FP6
-    reserved_.assign(MRegisterInfo::FirstVirtualRegister, false);
-    reserved_[ 8] = true; /*  CH */
-    reserved_[ 9] = true; /*  CL */
-    reserved_[10] = true; /*  CX */
-    reserved_[12] = true; /*  DI */
-    reserved_[18] = true; /* ECX */
-    reserved_[19] = true; /* EDI */
-    reserved_[28] = true; /* FP5 */
-    reserved_[29] = true; /* FP6 */
+    linearScan();
 
-    // linear scan algorithm
+    spiller_->runOnMachineFunction(*mf_, *vrm_);
 
-    DEBUG(printIntervals("\tunhandled", unhandled_.begin(), unhandled_.end()));
-    DEBUG(printIntervals("\tfixed", fixed_.begin(), fixed_.end()));
-    DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
-    DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));
+    return true;
+}
+
+void RA::linearScan()
+{
+    // linear scan algorithm
+    DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
+    DEBUG(std::cerr << "********** Function: "
+          << mf_->getFunction()->getName() << '\n');
+
+    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() || !fixed_.empty()) {
         // pick the interval with the earliest start point
         IntervalPtrs::value_type cur;
         if (fixed_.empty()) {
             cur = unhandled_.front();
-            unhandled_.erase(unhandled_.begin());
+            unhandled_.pop_front();
         }
         else if (unhandled_.empty()) {
             cur = fixed_.front();
-            fixed_.erase(fixed_.begin());
+            fixed_.pop_front();
         }
         else if (unhandled_.front()->start() < fixed_.front()->start()) {
             cur = unhandled_.front();
-            unhandled_.erase(unhandled_.begin());
+            unhandled_.pop_front();
         }
         else {
             cur = fixed_.front();
-            fixed_.erase(fixed_.begin());
+            fixed_.pop_front();
         }
 
-        DEBUG(std::cerr << *cur << '\n');
+        DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
 
         processActiveIntervals(cur);
         processInactiveIntervals(cur);
 
         // if this register is fixed we are done
-        if (cur->reg < MRegisterInfo::FirstVirtualRegister) {
-            markPhysRegNotFree(cur->reg);
+        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 {
-            backupRegUse();
-
-            // for every interval in inactive we overlap with, mark the
-            // register as not free
-            for (IntervalPtrs::const_iterator i = inactive_.begin(),
-                     e = inactive_.end(); i != e; ++i) {
-                unsigned reg = (*i)->reg;
-                if (reg >= MRegisterInfo::FirstVirtualRegister)
-                    reg = v2pMap_[reg];
-
-                if (cur->overlaps(**i)) {
-                    markPhysRegNotFree(reg);
-                }
-            }
-
-            // for every interval in fixed we overlap with,
-            // mark the register as not free
-            for (IntervalPtrs::const_iterator i = fixed_.begin(),
-                     e = fixed_.end(); i != e; ++i) {
-                assert((*i)->reg < MRegisterInfo::FirstVirtualRegister &&
-                       "virtual register interval in fixed set?");
-                if (cur->overlaps(**i))
-                    markPhysRegNotFree((*i)->reg);
-            }
-
-            DEBUG(std::cerr << "\tallocating current interval:\n");
-
-            unsigned physReg = getFreePhysReg(cur);
-            if (!physReg) {
-                assignStackSlotAtInterval(cur);
-            }
-            else {
-                restoreRegUse();
-                assignVirt2PhysReg(cur->reg, physReg);
-                active_.push_back(cur);
-            }
+            assignRegOrStackSlotAtInterval(cur);
         }
 
-        DEBUG(printIntervals("\tactive", active_.begin(), active_.end()));
-        DEBUG(printIntervals("\tinactive", inactive_.begin(), inactive_.end()));    }
+        DEBUG(printIntervals("active", active_.begin(), active_.end()));
+        DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
+        // DEBUG(verifyAssignment());
+    }
 
     // expire any remaining active intervals
     for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
         unsigned reg = (*i)->reg;
-        DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-        if (reg >= MRegisterInfo::FirstVirtualRegister) {
-            reg = v2pMap_[reg];
-        }
-        markPhysRegFree(reg);
-    }
-    active_.clear();
-    inactive_.clear();
-
-    DEBUG(std::cerr << "finished register allocation\n");
-    DEBUG(printVirt2PhysMap());
-
-    DEBUG(std::cerr << "Rewrite machine code:\n");
-    for (currentMbb_ = mf_->begin(); currentMbb_ != mf_->end(); ++currentMbb_) {
-        instrAdded_ = 0;
-
-        for (currentInstr_ = currentMbb_->begin();
-             currentInstr_ != currentMbb_->end(); ++currentInstr_) {
-
-            DEBUG(std::cerr << "\tinstruction: ";
-                  (*currentInstr_)->print(std::cerr, *tm_););
-
-            // use our current mapping and actually replace and
-            // virtual register with its allocated physical registers
-            DEBUG(std::cerr << "\t\treplacing virtual registers with mapped "
-                  "physical registers:\n");
-            for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
-                 i != e; ++i) {
-                MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister()) {
-                    unsigned virtReg = op.getAllocatedRegNum();
-                    unsigned physReg = v2pMap_[virtReg];
-                    if (physReg) {
-                        DEBUG(std::cerr << "\t\t\t%reg" << virtReg
-                              << " -> " << mri_->getName(physReg) << '\n');
-                        (*currentInstr_)->SetMachineOperandReg(i, physReg);
-                    }
-                }
-            }
-
-            DEBUG(std::cerr << "\t\tloading temporarily used operands to "
-                  "registers:\n");
-            for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
-                 i != e; ++i) {
-                MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister() && op.isUse() && !op.isDef()) {
-                    unsigned virtReg = op.getAllocatedRegNum();
-                    unsigned physReg = v2pMap_[virtReg];
-                    if (!physReg) {
-                        physReg = getFreeTempPhysReg(virtReg);
-                        loadVirt2PhysReg(virtReg, physReg);
-                        tempUseOperands_.push_back(virtReg);
-                    }
-                    (*currentInstr_)->SetMachineOperandReg(i, physReg);
-                }
-            }
-
-            DEBUG(std::cerr << "\t\tclearing temporarily used operands:\n");
-            for (unsigned i = 0, e = tempUseOperands_.size(); i != e; ++i) {
-                clearVirtReg(tempUseOperands_[i]);
-            }
-            tempUseOperands_.clear();
-
-            DEBUG(std::cerr << "\t\tassigning temporarily defined operands to "
-                  "registers:\n");
-            for (unsigned i = 0, e = (*currentInstr_)->getNumOperands();
-                 i != e; ++i) {
-                MachineOperand& op = (*currentInstr_)->getOperand(i);
-                if (op.isVirtualRegister() && op.isDef()) {
-                    unsigned virtReg = op.getAllocatedRegNum();
-                    unsigned physReg = v2pMap_[virtReg];
-                    if (!physReg) {
-                        physReg = getFreeTempPhysReg(virtReg);
-                    }
-                    if (op.isUse()) { // def and use
-                        loadVirt2PhysReg(virtReg, physReg);
-                    }
-                    else {
-                        assignVirt2PhysReg(virtReg, physReg);
-                    }
-                    tempDefOperands_.push_back(virtReg);
-                    (*currentInstr_)->SetMachineOperandReg(i, physReg);
-                }
-            }
-
-            DEBUG(std::cerr << "\t\tspilling temporarily defined operands "
-                  "of this instruction:\n");
-            ++currentInstr_; // we want to insert after this instruction
-            for (unsigned i = 0, e = tempDefOperands_.size(); i != e; ++i) {
-                spillVirtReg(tempDefOperands_[i]);
-            }
-            --currentInstr_; // restore currentInstr_ iterator
-            tempDefOperands_.clear();
-        }
+        DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
+        if (MRegisterInfo::isVirtualRegister(reg))
+            reg = vrm_->getPhys(reg);
+        prt_->delRegUse(reg);
     }
 
-    return true;
+    DEBUG(std::cerr << *vrm_);
 }
 
-void RA::initIntervalSets(const LiveIntervals::Intervals& li)
+void RA::initIntervalSets(LiveIntervals::Intervals& li)
 {
     assert(unhandled_.empty() && fixed_.empty() &&
            active_.empty() && inactive_.empty() &&
            "interval sets should be empty on initialization");
 
-    for (LiveIntervals::Intervals::const_iterator i = li.begin(), e = li.end();
+    for (LiveIntervals::Intervals::iterator i = li.begin(), e = li.end();
          i != e; ++i) {
-        if (i->reg < MRegisterInfo::FirstVirtualRegister)
+        if (MRegisterInfo::isPhysicalRegister(i->reg))
             fixed_.push_back(&*i);
         else
             unhandled_.push_back(&*i);
@@ -432,20 +249,18 @@
         // remove expired intervals
         if ((*i)->expiredAt(cur->start())) {
             DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-            if (reg >= MRegisterInfo::FirstVirtualRegister) {
-                reg = v2pMap_[reg];
-            }
-            markPhysRegFree(reg);
+            if (MRegisterInfo::isVirtualRegister(reg))
+                reg = vrm_->getPhys(reg);
+            prt_->delRegUse(reg);
             // remove from active
             i = active_.erase(i);
         }
         // move inactive intervals to inactive list
         else if (!(*i)->liveAt(cur->start())) {
-            DEBUG(std::cerr << "\t\t\tinterval " << **i << " inactive\n");
-            if (reg >= MRegisterInfo::FirstVirtualRegister) {
-                reg = v2pMap_[reg];
-            }
-            markPhysRegFree(reg);
+            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);
             // remove from active
@@ -465,17 +280,16 @@
 
         // remove expired intervals
         if ((*i)->expiredAt(cur->start())) {
-            DEBUG(std::cerr << "\t\t\tinterval " << **i << " expired\n");
+            DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
             // remove from inactive
             i = inactive_.erase(i);
         }
         // move re-activated intervals in active list
         else if ((*i)->liveAt(cur->start())) {
-            DEBUG(std::cerr << "\t\t\tinterval " << **i << " active\n");
-            if (reg >= MRegisterInfo::FirstVirtualRegister) {
-                reg = v2pMap_[reg];
-            }
-            markPhysRegNotFree(reg);
+            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);
             // remove from inactive
@@ -487,281 +301,237 @@
     }
 }
 
-namespace {
-    template <typename T>
-    void updateWeight(T rw[], int reg, T w)
-    {
-        if (rw[reg] == std::numeric_limits<T>::max() ||
-            w == std::numeric_limits<T>::max())
-            rw[reg] = std::numeric_limits<T>::max();
-        else
-            rw[reg] += w;
-    }
+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::assignStackSlotAtInterval(IntervalPtrs::value_type cur)
+void RA::assignRegOrStackSlotAtInterval(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\t\tassigning stack slot at interval "
-          << *cur << ":\n");
+    DEBUG(std::cerr << "\tallocating current interval: ");
+
+    PhysRegTracker backupPrt = *prt_;
 
-    // set all weights to zero
-    float regWeight[MRegisterInfo::FirstVirtualRegister];
-    for (unsigned i = 0; i < MRegisterInfo::FirstVirtualRegister; ++i)
-        regWeight[i] = 0.0F;
+    spillWeights_.assign(mri_->getNumRegs(), 0.0);
 
-    // for each interval in active that overlaps
+    // for each interval in active update spill weights
     for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
          i != e; ++i) {
-        if (!cur->overlaps(**i))
-            continue;
-
         unsigned reg = (*i)->reg;
-        if (reg >= MRegisterInfo::FirstVirtualRegister) {
-            reg = v2pMap_[reg];
-        }
-        updateWeight(regWeight, reg, (*i)->weight);
-        for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
-            updateWeight(regWeight, *as, (*i)->weight);
+        if (MRegisterInfo::isVirtualRegister(reg))
+            reg = vrm_->getPhys(reg);
+        updateSpillWeights(reg, (*i)->weight);
     }
 
-    // for each interval in inactive that overlaps
+    // 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))
-            continue;
-
-        unsigned reg = (*i)->reg;
-        if (reg >= MRegisterInfo::FirstVirtualRegister) {
-            reg = v2pMap_[reg];
+        if (cur->overlaps(**i)) {
+            unsigned reg = (*i)->reg;
+            if (MRegisterInfo::isVirtualRegister(reg))
+                reg = vrm_->getPhys(reg);
+            prt_->addRegUse(reg);
+            updateSpillWeights(reg, (*i)->weight);
         }
-        updateWeight(regWeight, reg, (*i)->weight);
-        for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
-            updateWeight(regWeight, *as, (*i)->weight);
     }
 
-    // for each fixed interval that overlaps
-    for (IntervalPtrs::const_iterator i = fixed_.begin(), e = fixed_.end();
-         i != e; ++i) {
-        if (!cur->overlaps(**i))
-            continue;
+    // 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);
+        }
+    }
 
-        assert((*i)->reg < MRegisterInfo::FirstVirtualRegister &&
-               "virtual register interval in fixed set?");
-        updateWeight(regWeight, (*i)->reg, (*i)->weight);
-        for (const unsigned* as = mri_->getAliasSet((*i)->reg); *as; ++as)
-            updateWeight(regWeight, *as, (*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 = std::numeric_limits<float>::max();
+    float minWeight = std::numeric_limits<float>::infinity();
     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 (!reserved_[reg] && minWeight > regWeight[reg]) {
-            minWeight = regWeight[reg];
+        if (minWeight > spillWeights_[reg]) {
+            minWeight = spillWeights_[reg];
             minReg = reg;
         }
     }
+    DEBUG(std::cerr << "\t\tregister with min weight: "
+          << mri_->getName(minReg) << " (" << minWeight << ")\n");
 
-    if (cur->weight < minWeight) {
-        restoreRegUse();
-        DEBUG(std::cerr << "\t\t\t\tspilling: " << *cur << '\n');
-        assignVirt2StackSlot(cur->reg);
-    }
-    else {
-        DEBUG(std::cerr << "\t\t\t\tfreeing: " << mri_->getName(minReg) << '\n');
-        std::set<unsigned> toSpill;
-        toSpill.insert(minReg);
-        for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
-            toSpill.insert(*as);
-
-        std::vector<unsigned> spilled;
-        for (IntervalPtrs::iterator i = active_.begin();
-             i != active_.end(); ) {
-            unsigned reg = (*i)->reg;
-            if (reg >= MRegisterInfo::FirstVirtualRegister &&
-                toSpill.find(v2pMap_[reg]) != toSpill.end() &&
-                cur->overlaps(**i)) {
-                spilled.push_back(v2pMap_[reg]);
-                DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
-                assignVirt2StackSlot(reg);
-                i = active_.erase(i);
+    // if the current has the minimum weight, we need to modify it,
+    // push it back in unhandled and let the linear scan algorithm run
+    // again
+    if (cur->weight <= minWeight) {
+        DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
+        int slot = vrm_->assignVirt2StackSlot(cur->reg);
+        li_->updateSpilledInterval(*cur, *vrm_, slot);
+
+        // if we didn't eliminate the interval find where to add it
+        // back to unhandled. We need to scan since unhandled are
+        // sorted on earliest start point and we may have changed our
+        // start point.
+        if (!cur->empty()) {
+            IntervalPtrs::iterator it = unhandled_.begin();
+            while (it != unhandled_.end() && (*it)->start() < cur->start())
+                ++it;
+            unhandled_.insert(it, cur);
+        }
+        return;
+    }
+
+    // push the current interval back to unhandled since we are going
+    // to re-run at least this iteration. Since we didn't modify it it
+    // should go back right in the front of the list
+    unhandled_.push_front(cur);
+
+    // otherwise we spill all intervals aliasing the register with
+    // minimum weight, rollback to the interval with the earliest
+    // start point and let the linear scan algorithm run again
+    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->start();
+
+    for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ++i) {
+        unsigned reg = (*i)->reg;
+        if (MRegisterInfo::isVirtualRegister(reg) &&
+            toSpill[vrm_->getPhys(reg)] &&
+            cur->overlaps(**i)) {
+            DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
+            earliestStart = std::min(earliestStart, (*i)->start());
+            int slot = vrm_->assignVirt2StackSlot((*i)->reg);
+            li_->updateSpilledInterval(**i, *vrm_, slot);
+        }
+    }
+    for (IntervalPtrs::iterator i = inactive_.begin();
+         i != inactive_.end(); ++i) {
+        unsigned reg = (*i)->reg;
+        if (MRegisterInfo::isVirtualRegister(reg) &&
+            toSpill[vrm_->getPhys(reg)] &&
+            cur->overlaps(**i)) {
+            DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
+            earliestStart = std::min(earliestStart, (*i)->start());
+            int slot = vrm_->assignVirt2StackSlot((*i)->reg);
+            li_->updateSpilledInterval(**i, *vrm_, slot);
+        }
+    }
+
+    DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
+    // scan handled in reverse order and undo each one, restoring the
+    // state of unhandled and fixed
+    while (!handled_.empty()) {
+        IntervalPtrs::value_type i = handled_.back();
+        // if this interval starts before t we are done
+        if (!i->empty() && i->start() < earliestStart)
+            break;
+        DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
+        handled_.pop_back();
+        IntervalPtrs::iterator it;
+        if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) {
+            active_.erase(it);
+            if (MRegisterInfo::isPhysicalRegister(i->reg)) {
+                fixed_.push_front(i);
+                prt_->delRegUse(i->reg);
             }
             else {
-                ++i;
+                prt_->delRegUse(vrm_->getPhys(i->reg));
+                vrm_->clearVirt(i->reg);
+                if (i->spilled()) {
+                    if (!i->empty()) {
+                        IntervalPtrs::iterator it = unhandled_.begin();
+                        while (it != unhandled_.end() &&
+                               (*it)->start() < i->start())
+                            ++it;
+                        unhandled_.insert(it, i);
+                    }
+                }
+                else
+                    unhandled_.push_front(i);
+
             }
         }
-        for (IntervalPtrs::iterator i = inactive_.begin();
-             i != inactive_.end(); ) {
-            unsigned reg = (*i)->reg;
-            if (reg >= MRegisterInfo::FirstVirtualRegister &&
-                toSpill.find(v2pMap_[reg]) != toSpill.end() &&
-                cur->overlaps(**i)) {
-                DEBUG(std::cerr << "\t\t\t\tspilling : " << **i << '\n');
-                assignVirt2StackSlot(reg);
-                i = inactive_.erase(i);
+        else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
+            inactive_.erase(it);
+            if (MRegisterInfo::isPhysicalRegister(i->reg))
+                fixed_.push_front(i);
+            else {
+                vrm_->clearVirt(i->reg);
+                if (i->spilled()) {
+                    if (!i->empty()) {
+                        IntervalPtrs::iterator it = unhandled_.begin();
+                        while (it != unhandled_.end() &&
+                               (*it)->start() < i->start())
+                            ++it;
+                        unhandled_.insert(it, i);
+                    }
+                }
+                else
+                    unhandled_.push_front(i);
             }
+        }
+        else {
+            if (MRegisterInfo::isPhysicalRegister(i->reg))
+                fixed_.push_front(i);
             else {
-                ++i;
+                vrm_->clearVirt(i->reg);
+                unhandled_.push_front(i);
             }
         }
-
-        unsigned physReg = getFreePhysReg(cur);
-        assert(physReg && "no free physical register after spill?");
-
-        restoreRegUse();
-        for (unsigned i = 0; i < spilled.size(); ++i)
-            markPhysRegFree(spilled[i]);
-
-        assignVirt2PhysReg(cur->reg, physReg);
-        active_.push_back(cur);
     }
-}
-
-bool RA::physRegAvailable(unsigned physReg)
-{
-    assert(!reserved_[physReg] &&
-           "cannot call this method with a reserved register");
 
-    return !regUse_[physReg];
+    // scan the rest and undo each interval that expired after t and
+    // insert it in active (the next iteration of the algorithm will
+    // put it in inactive if required)
+    IntervalPtrs::iterator i = handled_.begin(), e = handled_.end();
+    for (; i != e; ++i) {
+        if (!(*i)->expiredAt(earliestStart) && (*i)->expiredAt(cur->start())) {
+            DEBUG(std::cerr << "\t\t\tundo changes for: " << **i << '\n');
+            active_.push_back(*i);
+            if (MRegisterInfo::isPhysicalRegister((*i)->reg))
+                prt_->addRegUse((*i)->reg);
+            else
+                prt_->addRegUse(vrm_->getPhys((*i)->reg));
+        }
+    }
 }
 
 unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\t\tgetting free physical register: ");
     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 (!reserved_[reg] && !regUse_[reg]) {
-            DEBUG(std::cerr << mri_->getName(reg) << '\n');
-            return reg;
-        }
-    }
-
-    DEBUG(std::cerr << "no free register\n");
-    return 0;
-}
-
-bool RA::tempPhysRegAvailable(unsigned physReg)
-{
-    assert(reserved_[physReg] &&
-           "cannot call this method with a not reserved temp register");
-
-    return !regUse_[physReg];
-}
-
-unsigned RA::getFreeTempPhysReg(unsigned virtReg)
-{
-    DEBUG(std::cerr << "\t\tgetting free temporary physical register: ");
-
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
-    // go in reverse allocation order for the temp registers
-    for (TargetRegisterClass::iterator i = rc->allocation_order_end(*mf_) - 1;
-         i != rc->allocation_order_begin(*mf_) - 1; --i) {
-        unsigned reg = *i;
-        if (reserved_[reg] && !regUse_[reg]) {
-            DEBUG(std::cerr << mri_->getName(reg) << '\n');
+        if (prt_->isRegAvail(reg))
             return reg;
-        }
     }
-
-    assert(0 && "no free temporary physical register?");
     return 0;
-}
-
-void RA::assignVirt2PhysReg(unsigned virtReg, unsigned physReg)
-{
-    v2pMap_[virtReg] = physReg;
-    markPhysRegNotFree(physReg);
-}
-
-void RA::clearVirtReg(unsigned virtReg)
-{
-    Virt2PhysMap::iterator it = v2pMap_.find(virtReg);
-    assert(it != v2pMap_.end() &&
-           "attempting to clear a not allocated virtual register");
-    unsigned physReg = it->second;
-    markPhysRegFree(physReg);
-    v2pMap_[virtReg] = 0; // this marks that this virtual register
-                          // lives on the stack
-    DEBUG(std::cerr << "\t\t\tcleared register " << mri_->getName(physReg)
-          << "\n");
-}
-
-void RA::assignVirt2StackSlot(unsigned virtReg)
-{
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
-    int frameIndex = mf_->getFrameInfo()->CreateStackObject(rc);
-
-    bool inserted = v2ssMap_.insert(std::make_pair(virtReg, frameIndex)).second;
-    assert(inserted &&
-           "attempt to assign stack slot to already assigned register?");
-    // if the virtual register was previously assigned clear the mapping
-    // and free the virtual register
-    if (v2pMap_.find(virtReg) != v2pMap_.end()) {
-        clearVirtReg(virtReg);
-    }
-    else {
-        v2pMap_[virtReg] = 0; // this marks that this virtual register
-                              // lives on the stack
-    }
-}
-
-int RA::getStackSlot(unsigned virtReg)
-{
-    // use lower_bound so that we can do a possibly O(1) insert later
-    // if necessary
-    Virt2StackSlotMap::iterator it = v2ssMap_.find(virtReg);
-    assert(it != v2ssMap_.end() &&
-           "attempt to get stack slot on register that does not live on the stack");
-    return it->second;
-}
-
-void RA::spillVirtReg(unsigned virtReg)
-{
-    DEBUG(std::cerr << "\t\t\tspilling register: " << virtReg);
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
-    int frameIndex = getStackSlot(virtReg);
-    DEBUG(std::cerr << " to stack slot #" << frameIndex << '\n');
-    ++numSpilled;
-    instrAdded_ += mri_->storeRegToStackSlot(*currentMbb_, currentInstr_,
-                                             v2pMap_[virtReg], frameIndex, rc);
-    clearVirtReg(virtReg);
-}
-
-void RA::loadVirt2PhysReg(unsigned virtReg, unsigned physReg)
-{
-    DEBUG(std::cerr << "\t\t\tloading register: " << virtReg);
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(virtReg);
-    int frameIndex = getStackSlot(virtReg);
-    DEBUG(std::cerr << " from stack slot #" << frameIndex << '\n');
-    ++numReloaded;
-    instrAdded_ += mri_->loadRegFromStackSlot(*currentMbb_, currentInstr_,
-                                              physReg, frameIndex, rc);
-    assignVirt2PhysReg(virtReg, physReg);
-}
-
-void RA::markPhysRegFree(unsigned physReg)
-{
-    assert(regUse_[physReg] != 0);
-    --regUse_[physReg];
-    for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
-        physReg = *as;
-        assert(regUse_[physReg] != 0);
-        --regUse_[physReg];
-    }
-}
-
-void RA::markPhysRegNotFree(unsigned physReg)
-{
-    ++regUse_[physReg];
-    for (const unsigned* as = mri_->getAliasSet(physReg); *as; ++as) {
-        physReg = *as;
-        ++regUse_[physReg];
-    }
 }
 
 FunctionPass* llvm::createLinearScanRegisterAllocator() {


Index: llvm/lib/CodeGen/RegAllocLocal.cpp
diff -u llvm/lib/CodeGen/RegAllocLocal.cpp:1.37 llvm/lib/CodeGen/RegAllocLocal.cpp:1.37.2.1
--- llvm/lib/CodeGen/RegAllocLocal.cpp:1.37	Tue Jan 13 00:24:30 2004
+++ llvm/lib/CodeGen/RegAllocLocal.cpp	Mon Mar  1 17:58:13 2004
@@ -1,10 +1,10 @@
 //===-- RegAllocLocal.cpp - A BasicBlock generic 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 register allocator allocates registers to a basic block at a time,
@@ -23,17 +23,16 @@
 #include "llvm/Target/TargetMachine.h"
 #include "Support/CommandLine.h"
 #include "Support/Debug.h"
+#include "Support/DenseMap.h"
 #include "Support/Statistic.h"
 #include <iostream>
-
-namespace llvm {
+using namespace llvm;
 
 namespace {
-  Statistic<> NumSpilled ("ra-local", "Number of registers spilled");
-  Statistic<> NumReloaded("ra-local", "Number of registers reloaded");
-  cl::opt<bool> DisableKill("disable-kill", cl::Hidden, 
-                            cl::desc("Disable register kill in local-ra"));
-
+  Statistic<> NumStores("ra-local", "Number of stores added");
+  Statistic<> NumLoads ("ra-local", "Number of loads added");
+  Statistic<> NumFolded("ra-local", "Number of loads/stores folded into "
+                        "instructions");
   class RA : public MachineFunctionPass {
     const TargetMachine *TM;
     MachineFunction *MF;
@@ -46,16 +45,21 @@
 
     // Virt2PhysRegMap - This map contains entries for each virtual register
     // that is currently available in a physical register.
+    DenseMap<unsigned, VirtReg2IndexFunctor> Virt2PhysRegMap;
+
+    unsigned &getVirt2PhysRegMapSlot(unsigned VirtReg) {
+      return Virt2PhysRegMap[VirtReg];
+    }
+
+    // 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.  If the entry for a physical
+    // register is -1, then the physical register is "not in the map".
     //
-    std::map<unsigned, unsigned> Virt2PhysRegMap;
-    
-    // PhysRegsUsed - This map contains 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.
-    //
-    std::map<unsigned, unsigned> PhysRegsUsed;
+    std::vector<int> PhysRegsUsed;
 
     // PhysRegsUseOrder - This contains a list of the physical registers that
     // currently have a virtual register value in them.  This list provides an
@@ -75,16 +79,16 @@
     std::vector<bool> VirtRegModified;
 
     void markVirtRegModified(unsigned Reg, bool Val = true) {
-      assert(Reg >= MRegisterInfo::FirstVirtualRegister && "Illegal VirtReg!");
+      assert(MRegisterInfo::isVirtualRegister(Reg) && "Illegal VirtReg!");
       Reg -= MRegisterInfo::FirstVirtualRegister;
       if (VirtRegModified.size() <= Reg) VirtRegModified.resize(Reg+1);
       VirtRegModified[Reg] = Val;
     }
 
     bool isVirtRegModified(unsigned Reg) const {
-      assert(Reg >= MRegisterInfo::FirstVirtualRegister && "Illegal VirtReg!");
+      assert(MRegisterInfo::isVirtualRegister(Reg) && "Illegal VirtReg!");
       assert(Reg - MRegisterInfo::FirstVirtualRegister < VirtRegModified.size()
-	     && "Illegal virtual register!");
+             && "Illegal virtual register!");
       return VirtRegModified[Reg - MRegisterInfo::FirstVirtualRegister];
     }
 
@@ -93,14 +97,14 @@
       if (PhysRegsUseOrder.back() == Reg) return;  // Already most recently used
 
       for (unsigned i = PhysRegsUseOrder.size(); i != 0; --i)
-	if (areRegsEqual(Reg, PhysRegsUseOrder[i-1])) {
-	  unsigned RegMatch = PhysRegsUseOrder[i-1];       // remove from middle
-	  PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
-	  // Add it to the end of the list
-	  PhysRegsUseOrder.push_back(RegMatch);
-	  if (RegMatch == Reg) 
-	    return;    // Found an exact match, exit early
-	}
+        if (areRegsEqual(Reg, PhysRegsUseOrder[i-1])) {
+          unsigned RegMatch = PhysRegsUseOrder[i-1];       // remove from middle
+          PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
+          // Add it to the end of the list
+          PhysRegsUseOrder.push_back(RegMatch);
+          if (RegMatch == Reg)
+            return;    // Found an exact match, exit early
+        }
     }
 
   public:
@@ -109,8 +113,7 @@
     }
 
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-      if (!DisableKill)
-	AU.addRequired<LiveVariables>();
+      AU.addRequired<LiveVariables>();
       AU.addRequiredID(PHIEliminationID);
       AU.addRequiredID(TwoAddressInstructionPassID);
       MachineFunctionPass::getAnalysisUsage(AU);
@@ -150,7 +153,7 @@
     /// 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 &I,
+    void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                       unsigned VirtReg, unsigned PhysReg);
 
     /// spillPhysReg - This method spills the specified physical register into
@@ -158,7 +161,7 @@
     /// true, then the request is ignored if the physical register does not
     /// contain a virtual register.
     ///
-    void spillPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
+    void spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
                       unsigned PhysReg, bool OnlyVirtRegs = false);
 
     /// assignVirtToPhysReg - This method updates local state so that we know
@@ -172,7 +175,7 @@
     /// the way or spilled to memory.
     ///
     void liberatePhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
-			 unsigned PhysReg);
+                         unsigned PhysReg);
 
     /// isPhysRegAvailable - Return true if the specified physical register is
     /// free and available for use.  This also includes checking to see if
@@ -184,22 +187,29 @@
     /// specified register class.  If not, return 0.
     ///
     unsigned getFreeReg(const TargetRegisterClass *RC);
-    
+
     /// getReg - Find a physical register to hold the specified virtual
     /// register.  If all compatible physical registers are used, this method
     /// spills the last used virtual register to the stack, and uses that
     /// register.
     ///
-    unsigned getReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
-		    unsigned VirtReg);
+    unsigned getReg(MachineBasicBlock &MBB, MachineInstr *MI,
+                    unsigned VirtReg);
 
-    /// reloadVirtReg - This method loads the specified virtual register into a
-    /// physical register, returning the physical register chosen.  This updates
-    /// the regalloc data structures to reflect the fact that the virtual reg is
-    /// now alive in a physical register, and the previous one isn't.
+    /// 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.
     ///
-    unsigned reloadVirtReg(MachineBasicBlock &MBB,
-                           MachineBasicBlock::iterator &I, unsigned VirtReg);
+    MachineInstr *reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
+                                unsigned OpNum);
+ 
 
     void reloadPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
                        unsigned PhysReg);
@@ -224,11 +234,11 @@
 }
 
 
-/// removePhysReg - This method marks the specified physical register as no 
+/// removePhysReg - This method marks the specified physical register as no
 /// longer being in use.
 ///
 void RA::removePhysReg(unsigned PhysReg) {
-  PhysRegsUsed.erase(PhysReg);      // PhyReg no longer used
+  PhysRegsUsed[PhysReg] = -1;      // PhyReg no longer used
 
   std::vector<unsigned>::iterator It =
     std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), PhysReg);
@@ -241,9 +251,8 @@
 /// virtual register slot specified by VirtReg.  It then updates the RA data
 /// structures to indicate the fact that PhysReg is now available.
 ///
-void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
+void RA::spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                       unsigned VirtReg, unsigned PhysReg) {
-  if (!VirtReg && DisableKill) return;
   assert(VirtReg && "Spilling a physical register is illegal!"
          " Must not have appropriate kill for the register or use exists beyond"
          " the intended one.");
@@ -260,9 +269,10 @@
     int FrameIndex = getStackSpaceFor(VirtReg, RC);
     DEBUG(std::cerr << " to stack slot #" << FrameIndex);
     RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIndex, RC);
-    ++NumSpilled;   // Update statistics
+    ++NumStores;   // Update statistics
   }
-  Virt2PhysRegMap.erase(VirtReg);   // VirtReg no longer available
+
+  getVirt2PhysRegMapSlot(VirtReg) = 0;   // VirtReg no longer available
 
   DEBUG(std::cerr << "\n");
   removePhysReg(PhysReg);
@@ -274,22 +284,19 @@
 /// then the request is ignored if the physical register does not contain a
 /// virtual register.
 ///
-void RA::spillPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
+void RA::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
                       unsigned PhysReg, bool OnlyVirtRegs) {
-  std::map<unsigned, unsigned>::iterator PI = PhysRegsUsed.find(PhysReg);
-  if (PI != PhysRegsUsed.end()) {             // Only spill it if it's used!
-    if (PI->second || !OnlyVirtRegs)
-      spillVirtReg(MBB, I, PI->second, PhysReg);
+  if (PhysRegsUsed[PhysReg] != -1) {            // Only spill it if it's 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) {
-      PI = PhysRegsUsed.find(*AliasSet);
-      if (PI != PhysRegsUsed.end())     // Spill aliased register...
-        if (PI->second || !OnlyVirtRegs)
-          spillVirtReg(MBB, I, PI->second, *AliasSet);
-    }
+         *AliasSet; ++AliasSet)
+      if (PhysRegsUsed[*AliasSet] != -1)     // Spill aliased register...
+        if (PhysRegsUsed[*AliasSet] || !OnlyVirtRegs)
+          spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
   }
 }
 
@@ -299,12 +306,11 @@
 /// register must not be used for anything else when this is called.
 ///
 void RA::assignVirtToPhysReg(unsigned VirtReg, unsigned PhysReg) {
-  assert(PhysRegsUsed.find(PhysReg) == PhysRegsUsed.end() &&
-         "Phys reg already assigned!");
+  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;
-  Virt2PhysRegMap[VirtReg] = PhysReg;
+  getVirt2PhysRegMapSlot(VirtReg) = PhysReg;
   PhysRegsUseOrder.push_back(PhysReg);   // New use of PhysReg
 }
 
@@ -314,13 +320,13 @@
 /// registers are all free...
 ///
 bool RA::isPhysRegAvailable(unsigned PhysReg) const {
-  if (PhysRegsUsed.count(PhysReg)) return false;
+  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.count(*AliasSet)) // Aliased register in use?
+    if (PhysRegsUsed[*AliasSet] != -1) // Aliased register in use?
       return false;                    // Can't use this reg then.
   return true;
 }
@@ -349,7 +355,7 @@
 /// or spilled to memory.
 ///
 void RA::liberatePhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
-			 unsigned PhysReg) {
+                         unsigned PhysReg) {
   // FIXME: This code checks to see if a register is available, but it really
   // wants to know if a reg is available BEFORE the instruction executes.  If
   // called after killed operands are freed, it runs the risk of reallocating a
@@ -360,9 +366,9 @@
   // Check to see if the register is directly used, not indirectly used through
   // aliases.  If aliased registers are the ones actually used, we cannot be
   // sure that we will be able to save the whole thing if we do a reg-reg copy.
-  std::map<unsigned, unsigned>::iterator PRUI = PhysRegsUsed.find(PhysReg);
-  if (PRUI != PhysRegsUsed.end()) {
-    unsigned VirtReg = PRUI->second;   // The virtual register held...
+  if (PhysRegsUsed[PhysReg] != -1) {
+    // The virtual register held...
+    unsigned VirtReg = PhysRegsUsed[PhysReg]->second;
 
     // Check to see if there is a compatible register available.  If so, we can
     // move the value into the new register...
@@ -371,12 +377,12 @@
     if (unsigned NewReg = getFreeReg(RC)) {
       // Emit the code to copy the value...
       RegInfo->copyRegToReg(MBB, I, NewReg, PhysReg, RC);
-      
+
       // Update our internal state to indicate that PhysReg is available and Reg
       // isn't.
-      Virt2PhysRegMap.erase(VirtReg);
+      getVirt2PhysRegMapSlot[VirtReg] = 0;
       removePhysReg(PhysReg);  // Free the physreg
-      
+
       // Move reference over to new register...
       assignVirtToPhysReg(VirtReg, NewReg);
       return;
@@ -391,8 +397,8 @@
 /// register.  If all compatible physical registers are used, this method spills
 /// the last used virtual register to the stack, and uses that register.
 ///
-unsigned RA::getReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
-		    unsigned VirtReg) {
+unsigned RA::getReg(MachineBasicBlock &MBB, MachineInstr *I,
+                    unsigned VirtReg) {
   const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg);
 
   // First check to see if we have a free register of the requested type...
@@ -408,13 +414,13 @@
     for (unsigned i = 0; PhysReg == 0; ++i) {
       assert(i != PhysRegsUseOrder.size() &&
              "Couldn't find a register of the appropriate class!");
-      
+
       unsigned R = PhysRegsUseOrder[i];
 
       // We can only use this register if it holds a virtual register (ie, it
       // can be spilled).  Do not use it if it is an explicitly allocated
       // physical register!
-      assert(PhysRegsUsed.count(R) &&
+      assert(PhysRegsUsed[R] != -1 &&
              "PhysReg in PhysRegsUseOrder, but is not allocated?");
       if (PhysRegsUsed[R]) {
         // If the current register is compatible, use it.
@@ -448,57 +454,87 @@
 }
 
 
-/// reloadVirtReg - This method loads the specified virtual register into a
-/// physical register, returning the physical register chosen.  This updates the
-/// regalloc data structures to reflect the fact that the virtual reg is now
-/// alive in a physical register, and the previous one isn't.
+/// 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.
 ///
-unsigned RA::reloadVirtReg(MachineBasicBlock &MBB,
-                           MachineBasicBlock::iterator &I,
-                           unsigned VirtReg) {
-  std::map<unsigned, unsigned>::iterator It = Virt2PhysRegMap.find(VirtReg);
-  if (It != Virt2PhysRegMap.end()) {
-    MarkPhysRegRecentlyUsed(It->second);
-    return It->second;               // Already have this value available!
+MachineInstr *RA::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
+                                unsigned OpNum) {
+  unsigned VirtReg = MI->getOperand(OpNum).getReg();
+
+  // If the virtual register is already available, just update the instruction
+  // and return.
+  if (unsigned PR = getVirt2PhysRegMapSlot(VirtReg)) {
+    MarkPhysRegRecentlyUsed(PR);          // Already have this value available!
+    MI->SetMachineOperandReg(OpNum, PR);  // Assign the input register
+    return MI;
   }
 
-  unsigned PhysReg = getReg(MBB, I, VirtReg);
-
+  // Otherwise, we need to fold it into the current instruction, or reload it.
+  // If we have registers available to hold the value, use them.
   const TargetRegisterClass *RC = MF->getSSARegMap()->getRegClass(VirtReg);
+  unsigned PhysReg = getFreeReg(RC);
   int FrameIndex = getStackSpaceFor(VirtReg, RC);
 
+  if (PhysReg) {   // Register is available, allocate it!
+    assignVirtToPhysReg(VirtReg, PhysReg);
+  } else {         // No registers available.
+    // If we can fold this spill into this instruction, do so now.
+    MachineBasicBlock::iterator MII = MI;
+    if (RegInfo->foldMemoryOperand(MII, OpNum, 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, MII);
+      return MII;
+    }
+
+    // It looks like we can't fold this virtual register load into this
+    // instruction.  Force some poor hapless value out of the register file to
+    // make room for the new register, and reload it.
+    PhysReg = getReg(MBB, MI, VirtReg);
+  }
+
   markVirtRegModified(VirtReg, false);   // Note that this reg was just reloaded
 
   DEBUG(std::cerr << "  Reloading %reg" << VirtReg << " into "
                   << RegInfo->getName(PhysReg) << "\n");
 
   // Add move instruction(s)
-  RegInfo->loadRegFromStackSlot(MBB, I, PhysReg, FrameIndex, RC);
-  ++NumReloaded;    // Update statistics
-  return PhysReg;
+  RegInfo->loadRegFromStackSlot(MBB, MI, PhysReg, FrameIndex, RC);
+  ++NumLoads;    // Update statistics
+
+  MI->SetMachineOperandReg(OpNum, PhysReg);  // Assign the input register
+  return MI;
 }
 
 
 
 void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
   // loop over each instruction
-  MachineBasicBlock::iterator I = MBB.begin();
-  for (; I != MBB.end(); ++I) {
-    MachineInstr *MI = *I;
+  MachineBasicBlock::iterator MI = MBB.begin();
+  for (; MI != MBB.end(); ++MI) {
     const TargetInstrDescriptor &TID = TM->getInstrInfo().get(MI->getOpcode());
     DEBUG(std::cerr << "\nStarting RegAlloc of: " << *MI;
           std::cerr << "  Regs have values: ";
-          for (std::map<unsigned, unsigned>::const_iterator
-                 I = PhysRegsUsed.begin(), E = PhysRegsUsed.end(); I != E; ++I)
-             std::cerr << "[" << RegInfo->getName(I->first)
-                       << ",%reg" << I->second << "] ";
+          for (unsigned i = 0; i != RegInfo->getNumRegs(); ++i)
+            if (PhysRegsUsed[i] != -1)
+               std::cerr << "[" << RegInfo->getName(i)
+                         << ",%reg" << PhysRegsUsed[i] << "] ";
           std::cerr << "\n");
 
     // Loop over the implicit uses, making sure that they are at the head of the
     // use order list, so they don't get reallocated.
     for (const unsigned *ImplicitUses = TID.ImplicitUses;
          *ImplicitUses; ++ImplicitUses)
-        MarkPhysRegRecentlyUsed(*ImplicitUses);
+      MarkPhysRegRecentlyUsed(*ImplicitUses);
 
     // Get the used operands into registers.  This has the potential to spill
     // incoming values if we are out of registers.  Note that we completely
@@ -506,67 +542,66 @@
     // 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, e = MI->getNumOperands(); i != e; ++i)
-      if (MI->getOperand(i).isUse() &&
-          !MI->getOperand(i).isDef() &&
-          MI->getOperand(i).isVirtualRegister()){
-        unsigned VirtSrcReg = MI->getOperand(i).getAllocatedRegNum();
-        unsigned PhysSrcReg = reloadVirtReg(MBB, I, VirtSrcReg);
-        MI->SetMachineOperandReg(i, PhysSrcReg);  // Assign the input register
+    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.isDef() && MO.isRegister() && MO.getReg() &&
+          MRegisterInfo::isVirtualRegister(MO.getReg()))
+        MI = reloadVirtReg(MBB, MI, i);
+    }
+
+    // If this instruction is the last user of anything in registers, kill the
+    // value, freeing the register being used, so it doesn't need to be
+    // spilled to memory.
+    //
+    for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
+           KE = LV->killed_end(MI); KI != KE; ++KI) {
+      unsigned VirtReg = KI->second;
+      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;
       }
-    
-    if (!DisableKill) {
-      // If this instruction is the last user of anything in registers, kill the
-      // value, freeing the register being used, so it doesn't need to be
-      // spilled to memory.
-      //
-      for (LiveVariables::killed_iterator KI = LV->killed_begin(MI),
-             KE = LV->killed_end(MI); KI != KE; ++KI) {
-        unsigned VirtReg = KI->second;
-        unsigned PhysReg = VirtReg;
-        if (VirtReg >= MRegisterInfo::FirstVirtualRegister) {
-          std::map<unsigned, unsigned>::iterator I =
-            Virt2PhysRegMap.find(VirtReg);
-          assert(I != Virt2PhysRegMap.end());
-          PhysReg = I->second;
-          Virt2PhysRegMap.erase(I);
-        }
 
-        if (PhysReg) {
-          DEBUG(std::cerr << "  Last use of " << RegInfo->getName(PhysReg)
-                      << "[%reg" << VirtReg <<"], removing it from live set\n");
-          removePhysReg(PhysReg);
-        }
+      if (PhysReg) {
+        DEBUG(std::cerr << "  Last use of " << RegInfo->getName(PhysReg)
+              << "[%reg" << VirtReg <<"], removing it from live set\n");
+        removePhysReg(PhysReg);
       }
     }
 
     // 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)
-      if (MI->getOperand(i).isDef() &&
-          MI->getOperand(i).isPhysicalRegister()) {
-        unsigned Reg = MI->getOperand(i).getAllocatedRegNum();
-        spillPhysReg(MBB, I, Reg, true);  // Spill any existing value in the reg
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      MachineOperand& MO = MI->getOperand(i);
+      if (MO.isDef() && MO.isRegister() && MO.getReg() &&
+          MRegisterInfo::isPhysicalRegister(MO.getReg())) {
+        unsigned Reg = MO.getReg();
+        spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in the reg
         PhysRegsUsed[Reg] = 0;            // It is free and reserved now
         PhysRegsUseOrder.push_back(Reg);
         for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
              *AliasSet; ++AliasSet) {
-            PhysRegsUseOrder.push_back(*AliasSet);
-            PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
+          PhysRegsUseOrder.push_back(*AliasSet);
+          PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
         }
       }
+    }
 
     // Loop over the implicit defs, spilling them as well.
     for (const unsigned *ImplicitDefs = TID.ImplicitDefs;
          *ImplicitDefs; ++ImplicitDefs) {
       unsigned Reg = *ImplicitDefs;
-      spillPhysReg(MBB, I, Reg);
+      spillPhysReg(MBB, MI, Reg, true);
       PhysRegsUseOrder.push_back(Reg);
       PhysRegsUsed[Reg] = 0;            // It is free and reserved now
       for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
            *AliasSet; ++AliasSet) {
-          PhysRegsUseOrder.push_back(*AliasSet);
-          PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
+        PhysRegsUseOrder.push_back(*AliasSet);
+        PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
       }
     }
 
@@ -575,71 +610,65 @@
     // implicit 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)
-      if (MI->getOperand(i).isDef() &&
-          MI->getOperand(i).isVirtualRegister()) {
-        unsigned DestVirtReg = MI->getOperand(i).getAllocatedRegNum();
+    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+      MachineOperand& MO = MI->getOperand(i);
+      if (MO.isDef() && MO.isRegister() && MO.getReg() &&
+          MRegisterInfo::isVirtualRegister(MO.getReg())) {
+        unsigned DestVirtReg = MO.getReg();
         unsigned DestPhysReg;
 
         // If DestVirtReg already has a value, use it.
-        std::map<unsigned, unsigned>::iterator DestI =
-          Virt2PhysRegMap.find(DestVirtReg);
-        if (DestI != Virt2PhysRegMap.end()) {
-          DestPhysReg = DestI->second;
-        }
-        else {
-          DestPhysReg = getReg(MBB, I, DestVirtReg);
-        }
+        if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg)))
+          DestPhysReg = getReg(MBB, MI, DestVirtReg);
         markVirtRegModified(DestVirtReg);
         MI->SetMachineOperandReg(i, DestPhysReg);  // Assign the output register
       }
+    }
 
-    if (!DisableKill) {
-      // If this instruction defines any registers that are immediately dead,
-      // kill them now.
-      //
-      for (LiveVariables::killed_iterator KI = LV->dead_begin(MI),
-             KE = LV->dead_end(MI); KI != KE; ++KI) {
-        unsigned VirtReg = KI->second;
-        unsigned PhysReg = VirtReg;
-        if (VirtReg >= MRegisterInfo::FirstVirtualRegister) {
-          std::map<unsigned, unsigned>::iterator I =
-            Virt2PhysRegMap.find(VirtReg);
-          assert(I != Virt2PhysRegMap.end());
-          PhysReg = I->second;
-          Virt2PhysRegMap.erase(I);
-        }
+    // If this instruction defines any registers that are immediately dead,
+    // kill them now.
+    //
+    for (LiveVariables::killed_iterator KI = LV->dead_begin(MI),
+           KE = LV->dead_end(MI); KI != KE; ++KI) {
+      unsigned VirtReg = KI->second;
+      unsigned PhysReg = VirtReg;
+      if (MRegisterInfo::isVirtualRegister(VirtReg)) {
+        unsigned &PhysRegSlot = getVirt2PhysRegMapSlot(VirtReg);
+        PhysReg = PhysRegSlot;
+        assert(PhysReg != 0);
+        PhysRegSlot = 0;
+      }
 
-        if (PhysReg) {
-          DEBUG(std::cerr << "  Register " << RegInfo->getName(PhysReg)
-                          << " [%reg" << VirtReg
-                          << "] is never used, removing it frame live list\n");
-          removePhysReg(PhysReg);
-        }
+      if (PhysReg) {
+        DEBUG(std::cerr << "  Register " << RegInfo->getName(PhysReg)
+              << " [%reg" << VirtReg
+              << "] is never used, removing it frame live list\n");
+        removePhysReg(PhysReg);
       }
     }
   }
 
-  // Rewind the iterator to point to the first flow control instruction...
-  const TargetInstrInfo &TII = TM->getInstrInfo();
-  I = MBB.end();
-  while (I != MBB.begin() && TII.isTerminatorInstr((*(I-1))->getOpcode()))
-    --I;
+  MI = MBB.getFirstTerminator();
 
   // Spill all physical registers holding virtual registers now.
-  while (!PhysRegsUsed.empty())
-    if (unsigned VirtReg = PhysRegsUsed.begin()->second)
-      spillVirtReg(MBB, I, VirtReg, PhysRegsUsed.begin()->first);
-    else
-      removePhysReg(PhysRegsUsed.begin()->first);
-
-  for (std::map<unsigned, unsigned>::iterator I = Virt2PhysRegMap.begin(),
-         E = Virt2PhysRegMap.end(); I != E; ++I)
-    std::cerr << "Register still mapped: " << I->first << " -> "
-              << I->second << "\n";
+  for (unsigned i = 0, e = RegInfo->getNumRegs(); i != e; ++i)
+    if (PhysRegsUsed[i] != -1)
+      if (unsigned VirtReg = PhysRegsUsed[i])
+        spillVirtReg(MBB, MI, VirtReg, i);
+      else
+        removePhysReg(i);
+
+#ifndef NDEBUG
+  bool AllOk = true;
+  for (unsigned i = MRegisterInfo::FirstVirtualRegister,
+           e = MF->getSSARegMap()->getLastVirtReg(); i <= e; ++i)
+    if (unsigned PR = Virt2PhysRegMap[i]) {
+      std::cerr << "Register still mapped: " << i << " -> " << PR << "\n";
+      AllOk = false;
+    }
+  assert(AllOk && "Virtual registers still in phys regs?");
+#endif
 
-  assert(Virt2PhysRegMap.empty() && "Virtual registers still in phys regs?");
-  
   // Clear any physical register which appear live at the end of the basic
   // block, but which do not hold any virtual registers.  e.g., the stack
   // pointer.
@@ -654,9 +683,13 @@
   MF = &Fn;
   TM = &Fn.getTarget();
   RegInfo = TM->getRegisterInfo();
+  LV = &getAnalysis<LiveVariables>();
 
-  if (!DisableKill)
-    LV = &getAnalysis<LiveVariables>();
+  PhysRegsUsed.assign(RegInfo->getNumRegs(), -1);
+
+  // initialize the virtual->physical register map to have a 'null'
+  // mapping for all virtual registers
+  Virt2PhysRegMap.grow(MF->getSSARegMap()->getLastVirtReg());
 
   // Loop over all of the basic blocks, eliminating virtual register references
   for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
@@ -664,12 +697,12 @@
     AllocateBasicBlock(*MBB);
 
   StackSlotForVirtReg.clear();
+  PhysRegsUsed.clear();
   VirtRegModified.clear();
+  Virt2PhysRegMap.clear();
   return true;
 }
 
-FunctionPass *createLocalRegisterAllocator() {
+FunctionPass *llvm::createLocalRegisterAllocator() {
   return new RA();
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/RegAllocSimple.cpp
diff -u llvm/lib/CodeGen/RegAllocSimple.cpp:1.47 llvm/lib/CodeGen/RegAllocSimple.cpp:1.47.2.1
--- llvm/lib/CodeGen/RegAllocSimple.cpp:1.47	Sun Dec 14 07:24:16 2003
+++ llvm/lib/CodeGen/RegAllocSimple.cpp	Mon Mar  1 17:58:13 2004
@@ -24,13 +24,13 @@
 #include "llvm/Target/TargetMachine.h"
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
+#include "Support/STLExtras.h"
 #include <iostream>
-
-namespace llvm {
+using namespace llvm;
 
 namespace {
-  Statistic<> NumSpilled ("ra-simple", "Number of registers spilled");
-  Statistic<> NumReloaded("ra-simple", "Number of registers reloaded");
+  Statistic<> NumStores("ra-simple", "Number of stores added");
+  Statistic<> NumLoads ("ra-simple", "Number of loads added");
 
   class RegAllocSimple : public MachineFunctionPass {
     MachineFunction *MF;
@@ -79,10 +79,10 @@
 
     /// Moves value from memory into that register
     unsigned reloadVirtReg(MachineBasicBlock &MBB,
-                           MachineBasicBlock::iterator &I, unsigned VirtReg);
+                           MachineBasicBlock::iterator I, unsigned VirtReg);
 
     /// Saves reg value on the stack (maps virtual register to stack value)
-    void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator &I,
+    void spillVirtReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                       unsigned VirtReg, unsigned PhysReg);
   };
 
@@ -124,39 +124,37 @@
 }
 
 unsigned RegAllocSimple::reloadVirtReg(MachineBasicBlock &MBB,
-                                       MachineBasicBlock::iterator &I,
+                                       MachineBasicBlock::iterator I,
                                        unsigned VirtReg) {
   const TargetRegisterClass* RC = MF->getSSARegMap()->getRegClass(VirtReg);
   int FrameIdx = getStackSpaceFor(VirtReg, RC);
   unsigned PhysReg = getFreeReg(VirtReg);
 
   // Add move instruction(s)
-  ++NumReloaded;
+  ++NumLoads;
   RegInfo->loadRegFromStackSlot(MBB, I, PhysReg, FrameIdx, RC);
   return PhysReg;
 }
 
 void RegAllocSimple::spillVirtReg(MachineBasicBlock &MBB,
-                                  MachineBasicBlock::iterator &I,
+                                  MachineBasicBlock::iterator I,
                                   unsigned VirtReg, unsigned PhysReg) {
   const TargetRegisterClass* RC = MF->getSSARegMap()->getRegClass(VirtReg);
   int FrameIdx = getStackSpaceFor(VirtReg, RC);
 
   // Add move instruction(s)
-  ++NumSpilled;
+  ++NumStores;
   RegInfo->storeRegToStackSlot(MBB, I, PhysReg, FrameIdx, RC);
 }
 
 
 void RegAllocSimple::AllocateBasicBlock(MachineBasicBlock &MBB) {
   // loop over each instruction
-  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
+  for (MachineBasicBlock::iterator MI = MBB.begin(); MI != MBB.end(); ++MI) {
     // Made to combat the incorrect allocation of r2 = add r1, r1
     std::map<unsigned, unsigned> Virt2PhysRegMap;
 
-    MachineInstr *MI = *I;
-
-    RegsUsed.resize(MRegisterInfo::FirstVirtualRegister);
+    RegsUsed.resize(RegInfo->getNumRegs());
     
     // a preliminary pass that will invalidate any registers that
     // are used by the instruction (including implicit uses)
@@ -174,8 +172,8 @@
     for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
       MachineOperand &op = MI->getOperand(i);
       
-      if (op.isVirtualRegister()) {
-        unsigned virtualReg = (unsigned) op.getAllocatedRegNum();
+      if (op.isRegister() && MRegisterInfo::isVirtualRegister(op.getReg())) {
+        unsigned virtualReg = (unsigned) op.getReg();
         DEBUG(std::cerr << "op: " << op << "\n");
         DEBUG(std::cerr << "\t inst[" << i << "]: ";
               MI->print(std::cerr, *TM));
@@ -185,29 +183,31 @@
         unsigned physReg = Virt2PhysRegMap[virtualReg];
         if (physReg == 0) {
           if (op.isDef()) {
-            if (TM->getInstrInfo().isTwoAddrInstr(MI->getOpcode()) && i == 0) {
+            if (!TM->getInstrInfo().isTwoAddrInstr(MI->getOpcode()) || i) {
+              physReg = getFreeReg(virtualReg);
+            } else {
               // must be same register number as the first operand
               // This maps a = b + c into b += c, and saves b into a's spot
               assert(MI->getOperand(1).isRegister()  &&
-                     MI->getOperand(1).getAllocatedRegNum() &&
+                     MI->getOperand(1).getReg() &&
                      MI->getOperand(1).isUse() &&
                      "Two address instruction invalid!");
 
-              physReg = MI->getOperand(1).getAllocatedRegNum();
-            } else {
-              physReg = getFreeReg(virtualReg);
+              physReg = MI->getOperand(1).getReg();
+              spillVirtReg(MBB, next(MI), virtualReg, physReg);
+              MI->getOperand(1).setDef();
+              MI->RemoveOperand(0);
+              break; // This is the last operand to process
             }
-            ++I;
-            spillVirtReg(MBB, I, virtualReg, physReg);
-            --I;
+            spillVirtReg(MBB, next(MI), virtualReg, physReg);
           } else {
-            physReg = reloadVirtReg(MBB, I, virtualReg);
+            physReg = reloadVirtReg(MBB, MI, virtualReg);
             Virt2PhysRegMap[virtualReg] = physReg;
           }
         }
         MI->SetMachineOperandReg(i, physReg);
         DEBUG(std::cerr << "virt: " << virtualReg << 
-              ", phys: " << op.getAllocatedRegNum() << "\n");
+              ", phys: " << op.getReg() << "\n");
       }
     }
     RegClassIdx.clear();
@@ -233,8 +233,6 @@
   return true;
 }
 
-FunctionPass *createSimpleRegisterAllocator() {
+FunctionPass *llvm::createSimpleRegisterAllocator() {
   return new RegAllocSimple();
 }
-
-} // End llvm namespace


Index: llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
diff -u llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.6 llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.6.2.1
--- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp:1.6	Sun Jan 11 03:18:43 2004
+++ llvm/lib/CodeGen/TwoAddressInstructionPass.cpp	Mon Mar  1 17:58:13 2004
@@ -16,53 +16,49 @@
 // to:
 //
 //     A = B
-//     A = A op C
+//     A op= C
+//
+// Note that if a register allocator chooses to use this pass, that it
+// has to be capable of handling the non-SSA nature of these rewritten
+// virtual registers.
+//
+// It is also worth noting that the duplicate operand of the two
+// address instruction is removed.
 //
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "twoaddrinstr"
 #include "llvm/Function.h"
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/CodeGen/MachineFrameInfo.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/TargetInstrInfo.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegInfo.h"
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
 #include "Support/STLExtras.h"
 #include <iostream>
-
 using namespace llvm;
 
 namespace {
-    class TwoAddressInstructionPass : public MachineFunctionPass
-    {
-    private:
-        MachineFunction* mf_;
-        const TargetMachine* tm_;
-        const MRegisterInfo* mri_;
-        LiveVariables* lv_;
+    Statistic<> numTwoAddressInstrs("twoaddressinstruction",
+                                    "Number of two-address instructions");
+    Statistic<> numInstrsAdded("twoaddressinstruction",
+                               "Number of instructions added");
 
-    public:
+    struct TwoAddressInstructionPass : public MachineFunctionPass
+    {
         virtual void getAnalysisUsage(AnalysisUsage &AU) const;
 
-    private:
         /// runOnMachineFunction - pass entry point
         bool runOnMachineFunction(MachineFunction&);
     };
 
     RegisterPass<TwoAddressInstructionPass> X(
         "twoaddressinstruction", "Two-Address instruction pass");
-
-    Statistic<> numTwoAddressInstrs("twoaddressinstruction",
-                                    "Number of two-address instructions");
-    Statistic<> numInstrsAdded("twoaddressinstruction",
-                               "Number of instructions added");
 };
 
 const PassInfo *llvm::TwoAddressInstructionPassID = X.getPassInfo();
@@ -70,101 +66,113 @@
 void TwoAddressInstructionPass::getAnalysisUsage(AnalysisUsage &AU) const
 {
     AU.addPreserved<LiveVariables>();
-    AU.addRequired<LiveVariables>();
     AU.addPreservedID(PHIEliminationID);
-    AU.addRequiredID(PHIEliminationID);
     MachineFunctionPass::getAnalysisUsage(AU);
 }
 
 /// runOnMachineFunction - Reduce two-address instructions to two
-/// operands
+/// operands.
 ///
-bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &fn) {
+bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
     DEBUG(std::cerr << "Machine Function\n");
-    mf_ = &fn;
-    tm_ = &fn.getTarget();
-    mri_ = tm_->getRegisterInfo();
-    lv_ = &getAnalysis<LiveVariables>();
-
-    const TargetInstrInfo& tii = tm_->getInstrInfo();
+    const TargetMachine &TM = MF.getTarget();
+    const MRegisterInfo &MRI = *TM.getRegisterInfo();
+    const TargetInstrInfo &TII = TM.getInstrInfo();
+    LiveVariables* LV = getAnalysisToUpdate<LiveVariables>();
+
+    bool MadeChange = false;
+
+    DEBUG(std::cerr << "********** REWRITING TWO-ADDR INSTRS **********\n");
+    DEBUG(std::cerr << "********** Function: "
+          << MF.getFunction()->getName() << '\n');
 
-    for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+    for (MachineFunction::iterator mbbi = MF.begin(), mbbe = MF.end();
          mbbi != mbbe; ++mbbi) {
-        for (MachineBasicBlock::iterator mii = mbbi->begin();
-             mii != mbbi->end(); ++mii) {
-            MachineInstr* mi = *mii;
-
+        for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end();
+             mi != me; ++mi) {
             unsigned opcode = mi->getOpcode();
+
             // ignore if it is not a two-address instruction
-            if (!tii.isTwoAddrInstr(opcode))
+            if (!TII.isTwoAddrInstr(opcode))
                 continue;
 
             ++numTwoAddressInstrs;
 
-            DEBUG(std::cerr << "\tinstruction: "; mi->print(std::cerr, *tm_));
-
-            // we have nothing to do if the two operands are the same
-            if (mi->getOperand(0).getAllocatedRegNum() ==
-                mi->getOperand(1).getAllocatedRegNum())
-                continue;
+            DEBUG(std::cerr << '\t'; mi->print(std::cerr, TM));
 
             assert(mi->getOperand(1).isRegister() &&
-                   mi->getOperand(1).getAllocatedRegNum() &&
+                   mi->getOperand(1).getReg() &&
                    mi->getOperand(1).isUse() &&
                    "two address instruction invalid");
 
-            // rewrite:
-            //     a = b op c
-            // to:
-            //     a = b
-            //     a = a op c
-            unsigned regA = mi->getOperand(0).getAllocatedRegNum();
-            unsigned regB = mi->getOperand(1).getAllocatedRegNum();
-
-            assert(regA >= MRegisterInfo::FirstVirtualRegister &&
-                   regB >= MRegisterInfo::FirstVirtualRegister &&
-                   "cannot update physical register live information");
-
-            // first make sure we do not have a use of a in the
-            // instruction (a = b + a for example) because our
-            // transofrmation will not work. This should never occur
-            // because of SSA.
-            for (unsigned i = 1; i < mi->getNumOperands(); ++i) {
-                assert(!mi->getOperand(i).isRegister() ||
-                       mi->getOperand(i).getAllocatedRegNum() != (int)regA);
+            // if the two operands are the same we just remove the use
+            // and mark the def as def&use
+            if (mi->getOperand(0).getReg() ==
+                mi->getOperand(1).getReg()) {
             }
+            else {
+                MadeChange = true;
 
-            const TargetRegisterClass* rc =
-                mf_->getSSARegMap()->getRegClass(regA);
-            numInstrsAdded += mri_->copyRegToReg(*mbbi, mii, regA, regB, rc);
-
-            MachineInstr* prevMi = *(mii - 1);
-            DEBUG(std::cerr << "\t\tadded instruction: ";
-                  prevMi->print(std::cerr, *tm_));
-
-            // update live variables for regA
-            LiveVariables::VarInfo& varInfo = lv_->getVarInfo(regA);
-            varInfo.DefInst = prevMi;
-
-            // update live variables for regB
-            if (lv_->removeVirtualRegisterKilled(regB, &*mbbi, mi))
-                lv_->addVirtualRegisterKilled(regB, &*mbbi, prevMi);
-
-            if (lv_->removeVirtualRegisterDead(regB, &*mbbi, mi))
-                lv_->addVirtualRegisterDead(regB, &*mbbi, prevMi);
-
-            // replace all occurences of regB with regA
-            for (unsigned i = 1; i < mi->getNumOperands(); ++i) {
-                if (mi->getOperand(i).isRegister() &&
-                    mi->getOperand(i).getReg() == regB)
-                    mi->SetMachineOperandReg(i, regA);
+                // rewrite:
+                //     a = b op c
+                // to:
+                //     a = b
+                //     a = a op c
+                unsigned regA = mi->getOperand(0).getReg();
+                unsigned regB = mi->getOperand(1).getReg();
+
+                assert(MRegisterInfo::isVirtualRegister(regA) &&
+                       MRegisterInfo::isVirtualRegister(regB) &&
+                       "cannot update physical register live information");
+
+                // first make sure we do not have a use of a in the
+                // instruction (a = b + a for example) because our
+                // transformation will not work. This should never occur
+                // because we are in SSA form.
+                for (unsigned i = 1; i != mi->getNumOperands(); ++i)
+                    assert(!mi->getOperand(i).isRegister() ||
+                           mi->getOperand(i).getReg() != regA);
+
+                const TargetRegisterClass* rc =
+                    MF.getSSARegMap()->getRegClass(regA);
+                unsigned Added = MRI.copyRegToReg(*mbbi, mi, regA, regB, rc);
+                numInstrsAdded += Added;
+
+                MachineBasicBlock::iterator prevMi = prior(mi);
+                DEBUG(std::cerr << "\t\tprepend:\t";
+                      prevMi->print(std::cerr, TM));
+
+                if (LV) {
+                    // update live variables for regA
+                    assert(Added == 1 &&
+                           "Cannot handle multi-instruction copies yet!");
+                    LiveVariables::VarInfo& varInfo = LV->getVarInfo(regA);
+                    varInfo.DefInst = prevMi;
+
+                    // update live variables for regB
+                    if (LV->removeVirtualRegisterKilled(regB, &*mbbi, mi))
+                        LV->addVirtualRegisterKilled(regB, &*mbbi, prevMi);
+
+                    if (LV->removeVirtualRegisterDead(regB, &*mbbi, mi))
+                        LV->addVirtualRegisterDead(regB, &*mbbi, prevMi);
+                }
+
+                // replace all occurences of regB with regA
+                for (unsigned i = 1, e = mi->getNumOperands(); i != e; ++i) {
+                    if (mi->getOperand(i).isRegister() &&
+                        mi->getOperand(i).getReg() == regB)
+                        mi->SetMachineOperandReg(i, regA);
+                }
             }
-            DEBUG(std::cerr << "\t\tmodified original to: ";
-                  mi->print(std::cerr, *tm_));
-            assert(mi->getOperand(0).getAllocatedRegNum() ==
-                   mi->getOperand(1).getAllocatedRegNum());
+
+            assert(mi->getOperand(0).isDef());
+            mi->getOperand(0).setUse();
+            mi->RemoveOperand(1);
+
+            DEBUG(std::cerr << "\t\trewrite to:\t";
+                  mi->print(std::cerr, TM));
         }
     }
 
-    return numInstrsAdded != 0;
+    return MadeChange;
 }





More information about the llvm-commits mailing list