diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index ed90fca..fc65e00 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -37,447 +37,446 @@
 using namespace llvm;
 
 namespace {
-    RegisterAnalysis<LiveIntervals> X("liveintervals",
-                                      "Live Interval Analysis");
+  RegisterAnalysis<LiveIntervals> X("liveintervals", "Live Interval Analysis");
 
-    Statistic<> numIntervals
-    ("liveintervals", "Number of original intervals");
+  Statistic<> numIntervals
+  ("liveintervals", "Number of original intervals");
 
-    Statistic<> numIntervalsAfter
-    ("liveintervals", "Number of intervals after coalescing");
+  Statistic<> numIntervalsAfter
+  ("liveintervals", "Number of intervals after coalescing");
 
-    Statistic<> numJoins
-    ("liveintervals", "Number of interval joins performed");
+  Statistic<> numJoins
+  ("liveintervals", "Number of interval joins performed");
 
-    Statistic<> numPeep
-    ("liveintervals", "Number of identity moves eliminated after coalescing");
+  Statistic<> numPeep
+  ("liveintervals", "Number of identity moves eliminated after coalescing");
 
-    Statistic<> numFolded
-    ("liveintervals", "Number of loads/stores folded into instructions");
+  Statistic<> numFolded
+  ("liveintervals", "Number of loads/stores folded into instructions");
 
-    cl::opt<bool>
-    EnableJoining("join-liveintervals",
-                  cl::desc("Join compatible live intervals"),
-                  cl::init(true));
+  cl::opt<bool>
+  EnableJoining("join-liveintervals",
+                cl::desc("Join compatible live intervals"),
+                cl::init(true));
 };
 
 void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const
 {
-    AU.addPreserved<LiveVariables>();
-    AU.addRequired<LiveVariables>();
-    AU.addPreservedID(PHIEliminationID);
-    AU.addRequiredID(PHIEliminationID);
-    AU.addRequiredID(TwoAddressInstructionPassID);
-    AU.addRequired<LoopInfo>();
-    MachineFunctionPass::getAnalysisUsage(AU);
+  AU.addPreserved<LiveVariables>();
+  AU.addRequired<LiveVariables>();
+  AU.addPreservedID(PHIEliminationID);
+  AU.addRequiredID(PHIEliminationID);
+  AU.addRequiredID(TwoAddressInstructionPassID);
+  AU.addRequired<LoopInfo>();
+  MachineFunctionPass::getAnalysisUsage(AU);
 }
 
 void LiveIntervals::releaseMemory()
 {
-    mi2iMap_.clear();
-    i2miMap_.clear();
-    r2iMap_.clear();
-    r2rMap_.clear();
+  mi2iMap_.clear();
+  i2miMap_.clear();
+  r2iMap_.clear();
+  r2rMap_.clear();
 }
 
 
 /// runOnMachineFunction - Register allocate the whole function
 ///
 bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
-    mf_ = &fn;
-    tm_ = &fn.getTarget();
-    mri_ = tm_->getRegisterInfo();
-    lv_ = &getAnalysis<LiveVariables>();
+  mf_ = &fn;
+  tm_ = &fn.getTarget();
+  mri_ = tm_->getRegisterInfo();
+  lv_ = &getAnalysis<LiveVariables>();
 
-    // number MachineInstrs
-    unsigned miIndex = 0;
-    for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end();
-         mbb != mbbEnd; ++mbb)
-        for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
-             mi != miEnd; ++mi) {
-            bool inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second;
-            assert(inserted && "multiple MachineInstr -> index mappings");
-            i2miMap_.push_back(mi);
-            miIndex += InstrSlots::NUM;
-        }
-
-    computeIntervals();
-
-    numIntervals += getNumIntervals();
-
-#if 1
-    DEBUG(std::cerr << "********** INTERVALS **********\n");
-    DEBUG(for (iterator I = begin(), E = end(); I != E; ++I)
-            std::cerr << I->second << "\n");
-#endif
-
-    // join intervals if requested
-    if (EnableJoining) joinIntervals();
-
-    numIntervalsAfter += getNumIntervals();
-
-    // 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 (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
-         mbbi != mbbe; ++mbbi) {
-        MachineBasicBlock* mbb = mbbi;
-        unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock());
-
-        for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
-             mii != mie; ) {
-            // if the move will be an identity move delete it
-            unsigned srcReg, dstReg, RegRep;
-            if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
-                (RegRep = rep(srcReg)) == rep(dstReg)) {
-                // remove from def list
-                LiveInterval &interval = getOrCreateInterval(RegRep);
-                // 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 {
-                for (unsigned i = 0; i < mii->getNumOperands(); ++i) {
-                    const MachineOperand& mop = mii->getOperand(i);
-                    if (mop.isRegister() && mop.getReg() &&
-                        MRegisterInfo::isVirtualRegister(mop.getReg())) {
-                        // replace register with representative register
-                        unsigned reg = rep(mop.getReg());
-                        mii->SetMachineOperandReg(i, reg);
-
-                        LiveInterval &RegInt = getInterval(reg);
-                        RegInt.weight +=
-                            (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
-                    }
-                }
-                ++mii;
-            }
-        }
+  // number MachineInstrs
+  unsigned miIndex = 0;
+  for (MachineFunction::iterator mbb = mf_->begin(), mbbEnd = mf_->end();
+       mbb != mbbEnd; ++mbb)
+    for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
+         mi != miEnd; ++mi) {
+      bool inserted = mi2iMap_.insert(std::make_pair(mi, miIndex)).second;
+      assert(inserted && "multiple MachineInstr -> index mappings");
+      i2miMap_.push_back(mi);
+      miIndex += InstrSlots::NUM;
     }
 
-    DEBUG(std::cerr << "********** INTERVALS **********\n");
-    DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
-             std::cerr << I->second << "\n");
-    DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
-    DEBUG(
-        for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
-             mbbi != mbbe; ++mbbi) {
-            std::cerr << ((Value*)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_);
-            }
-        });
+  computeIntervals();
 
-    return true;
+  numIntervals += getNumIntervals();
+
+#if 1
+  DEBUG(std::cerr << "********** INTERVALS **********\n");
+  DEBUG(for (iterator I = begin(), E = end(); I != E; ++I)
+        std::cerr << I->second << "\n");
+#endif
+
+  // join intervals if requested
+  if (EnableJoining) joinIntervals();
+
+  numIntervalsAfter += getNumIntervals();
+
+  // 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 (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+       mbbi != mbbe; ++mbbi) {
+    MachineBasicBlock* mbb = mbbi;
+    unsigned loopDepth = loopInfo.getLoopDepth(mbb->getBasicBlock());
+
+    for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
+         mii != mie; ) {
+      // if the move will be an identity move delete it
+      unsigned srcReg, dstReg, RegRep;
+      if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
+          (RegRep = rep(srcReg)) == rep(dstReg)) {
+        // remove from def list
+        LiveInterval &interval = getOrCreateInterval(RegRep);
+        // 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 {
+        for (unsigned i = 0; i < mii->getNumOperands(); ++i) {
+          const MachineOperand& mop = mii->getOperand(i);
+          if (mop.isRegister() && mop.getReg() &&
+              MRegisterInfo::isVirtualRegister(mop.getReg())) {
+            // replace register with representative register
+            unsigned reg = rep(mop.getReg());
+            mii->SetMachineOperandReg(i, reg);
+
+            LiveInterval &RegInt = getInterval(reg);
+            RegInt.weight +=
+              (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
+          }
+        }
+        ++mii;
+      }
+    }
+  }
+
+  DEBUG(std::cerr << "********** INTERVALS **********\n");
+  DEBUG (for (iterator I = begin(), E = end(); I != E; ++I)
+         std::cerr << I->second << "\n");
+  DEBUG(std::cerr << "********** MACHINEINSTRS **********\n");
+  DEBUG(
+    for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+         mbbi != mbbe; ++mbbi) {
+      std::cerr << ((Value*)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;
 }
 
 std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
-    const LiveInterval& li,
-    VirtRegMap& vrm,
-    int slot)
+  const LiveInterval& li,
+  VirtRegMap& vrm,
+  int slot)
 {
-    std::vector<LiveInterval*> added;
+  std::vector<LiveInterval*> added;
 
-    assert(li.weight != HUGE_VAL &&
-           "attempt to spill already spilled interval!");
+  assert(li.weight != HUGE_VAL &&
+         "attempt to spill already spilled interval!");
 
-    DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: "
-          << li << '\n');
+  DEBUG(std::cerr << "\t\t\t\tadding intervals for spills for interval: "
+        << li << '\n');
 
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
+  const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(li.reg);
 
-    for (LiveInterval::Ranges::const_iterator
-              i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
-        unsigned index = getBaseIndex(i->start);
-        unsigned end = getBaseIndex(i->end-1) + InstrSlots::NUM;
-        for (; index != end; index += InstrSlots::NUM) {
-            // skip deleted instructions
-            while (index != end && !getInstructionFromIndex(index))
-                index += InstrSlots::NUM;
-            if (index == end) break;
+  for (LiveInterval::Ranges::const_iterator
+         i = li.ranges.begin(), e = li.ranges.end(); i != e; ++i) {
+    unsigned index = getBaseIndex(i->start);
+    unsigned end = getBaseIndex(i->end-1) + InstrSlots::NUM;
+    for (; index != end; index += InstrSlots::NUM) {
+      // skip deleted instructions
+      while (index != end && !getInstructionFromIndex(index))
+        index += InstrSlots::NUM;
+      if (index == end) break;
 
-            MachineBasicBlock::iterator mi = getInstructionFromIndex(index);
+      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) {
-                    if (MachineInstr* fmi =
-                        mri_->foldMemoryOperand(mi, i, slot)) {
-                        lv_->instructionChanged(mi, fmi);
-                        vrm.virtFolded(li.reg, mi, fmi);
-                        mi2iMap_.erase(mi);
-                        i2miMap_[index/InstrSlots::NUM] = fmi;
-                        mi2iMap_[fmi] = index;
-                        MachineBasicBlock& mbb = *mi->getParent();
-                        mi = mbb.insert(mbb.erase(mi), fmi);
-                        ++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() ?
-                                            getStoreIndex(index) :
-                                            getUseIndex(index));
+    for_operand:
+      for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
+        MachineOperand& mop = mi->getOperand(i);
+        if (mop.isRegister() && mop.getReg() == li.reg) {
+          if (MachineInstr* fmi =
+              mri_->foldMemoryOperand(mi, i, slot)) {
+            lv_->instructionChanged(mi, fmi);
+            vrm.virtFolded(li.reg, mi, fmi);
+            mi2iMap_.erase(mi);
+            i2miMap_[index/InstrSlots::NUM] = fmi;
+            mi2iMap_[fmi] = index;
+            MachineBasicBlock& mbb = *mi->getParent();
+            mi = mbb.insert(mbb.erase(mi), fmi);
+            ++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() ?
+                                getStoreIndex(index) :
+                                getUseIndex(index));
 
-                        // create a new register for this spill
-                        unsigned nReg =
-                            mf_->getSSARegMap()->createVirtualRegister(rc);
-                        mi->SetMachineOperandReg(i, nReg);
-                        vrm.grow();
-                        vrm.assignVirt2StackSlot(nReg, slot);
-                        LiveInterval& nI = getOrCreateInterval(nReg);
-                        assert(nI.empty());
-                        // the spill weight is now infinity as it
-                        // cannot be spilled again
-                        nI.weight = HUGE_VAL;
-                        LiveRange LR(start, end, nI.getNextValue());
-                        DEBUG(std::cerr << " +" << LR);
-                        nI.addRange(LR);
-                        added.push_back(&nI);
-                        // update live variables
-                        lv_->addVirtualRegisterKilled(nReg, mi);
-                        DEBUG(std::cerr << "\t\t\t\tadded new interval: "
-                              << nI << '\n');
-                    }
-                }
-            }
+            // create a new register for this spill
+            unsigned nReg =
+              mf_->getSSARegMap()->createVirtualRegister(rc);
+            mi->SetMachineOperandReg(i, nReg);
+            vrm.grow();
+            vrm.assignVirt2StackSlot(nReg, slot);
+            LiveInterval& nI = getOrCreateInterval(nReg);
+            assert(nI.empty());
+            // the spill weight is now infinity as it
+            // cannot be spilled again
+            nI.weight = HUGE_VAL;
+            LiveRange LR(start, end, nI.getNextValue());
+            DEBUG(std::cerr << " +" << LR);
+            nI.addRange(LR);
+            added.push_back(&nI);
+            // update live variables
+            lv_->addVirtualRegisterKilled(nReg, mi);
+            DEBUG(std::cerr << "\t\t\t\tadded new interval: "
+                  << nI << '\n');
+          }
         }
+      }
     }
+  }
 
-    return added;
+  return added;
 }
 
 void LiveIntervals::printRegName(unsigned reg) const
 {
-    if (MRegisterInfo::isPhysicalRegister(reg))
-        std::cerr << mri_->getName(reg);
-    else
-        std::cerr << "%reg" << reg;
+  if (MRegisterInfo::isPhysicalRegister(reg))
+    std::cerr << mri_->getName(reg);
+  else
+    std::cerr << "%reg" << reg;
 }
 
 void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
                                              MachineBasicBlock::iterator mi,
                                              LiveInterval& interval)
 {
-    DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
-    LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
+  DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
+  LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
 
-    // Virtual registers may be defined multiple times (due to phi 
-    // elimination and 2-addr elimination).  Much of what we do only has to be 
-    // done once for the vreg.  We use an empty interval to detect the first 
-    // time we see a vreg.
-    if (interval.empty()) {
-       // Get the Idx of the defining instructions.
-       unsigned defIndex = getDefIndex(getInstructionIndex(mi));
+  // Virtual registers may be defined multiple times (due to phi 
+  // elimination and 2-addr elimination).  Much of what we do only has to be 
+  // done once for the vreg.  We use an empty interval to detect the first 
+  // time we see a vreg.
+  if (interval.empty()) {
+    // Get the Idx of the defining instructions.
+    unsigned defIndex = getDefIndex(getInstructionIndex(mi));
 
-       unsigned ValNum = interval.getNextValue();
-       assert(ValNum == 0 && "First value in interval is not 0?");
-       ValNum = 0;  // Clue in the optimizer.
+    unsigned ValNum = interval.getNextValue();
+    assert(ValNum == 0 && "First value in interval is not 0?");
+    ValNum = 0;  // Clue in the optimizer.
 
-       // Loop over all of the blocks that the vreg is defined in.  There are
-       // two cases we have to handle here.  The most common case is a vreg
-       // whose lifetime is contained within a basic block.  In this case there
-       // will be a single kill, in MBB, which comes after the definition.
-       if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) {
-           // FIXME: what about dead vars?
-           unsigned killIdx;
-           if (vi.Kills[0] != mi)
-               killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1;
-           else
-               killIdx = defIndex+1;
+    // Loop over all of the blocks that the vreg is defined in.  There are
+    // two cases we have to handle here.  The most common case is a vreg
+    // whose lifetime is contained within a basic block.  In this case there
+    // will be a single kill, in MBB, which comes after the definition.
+    if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) {
+      // FIXME: what about dead vars?
+      unsigned killIdx;
+      if (vi.Kills[0] != mi)
+        killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1;
+      else
+        killIdx = defIndex+1;
 
-           // If the kill happens after the definition, we have an intra-block
-           // live range.
-           if (killIdx > defIndex) {
-              assert(vi.AliveBlocks.empty() && 
-                     "Shouldn't be alive across any blocks!");
-              LiveRange LR(defIndex, killIdx, ValNum);
-              interval.addRange(LR);
-              DEBUG(std::cerr << " +" << LR << "\n");
-              return;
-           }
-       }
-
-       // The other case we handle is when a virtual register lives to the end
-       // of the defining block, potentially live across some blocks, then is
-       // live into some number of blocks, but gets killed.  Start by adding a
-       // range that goes from this definition to the end of the defining block.
-       LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) +
-                                                   InstrSlots::NUM, ValNum);
-       DEBUG(std::cerr << " +" << NewLR);
-       interval.addRange(NewLR);
-
-       // Iterate over all of the blocks that the variable is completely
-       // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
-       // live interval.
-       for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) {
-           if (vi.AliveBlocks[i]) {
-               MachineBasicBlock* mbb = mf_->getBlockNumbered(i);
-               if (!mbb->empty()) {
-                 LiveRange LR(getInstructionIndex(&mbb->front()),
-                              getInstructionIndex(&mbb->back())+InstrSlots::NUM,
-                              ValNum);
-                 interval.addRange(LR);
-                 DEBUG(std::cerr << " +" << LR);
-               }
-           }
-       }
-
-       // Finally, this virtual register is live from the start of any killing
-       // block to the 'use' slot of the killing instruction.
-       for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
-           MachineInstr *Kill = vi.Kills[i];
-           LiveRange LR(getInstructionIndex(Kill->getParent()->begin()),
-                        getUseIndex(getInstructionIndex(Kill))+1, ValNum);
-           interval.addRange(LR);
-           DEBUG(std::cerr << " +" << LR);
-       }
-
-    } else {
-       // If this is the second time we see a virtual register definition, it
-       // must be due to phi elimination or two addr elimination.  If this is
-       // the result of two address elimination, then the vreg is the first
-       // operand, and is a def-and-use.
-       if (mi->getOperand(0).isRegister() && 
-           mi->getOperand(0).getReg() == interval.reg &&
-           mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) {
-         // If this is a two-address definition, then we have already processed
-         // the live range.  The only problem is that we didn't realize there
-         // are actually two values in the live interval.  Because of this we
-         // need to take the LiveRegion that defines this register and split it
-         // into two values.
-         unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst));
-         unsigned RedefIndex = getDefIndex(getInstructionIndex(mi));
-
-         // Delete the initial value, which should be short and continuous,
-         // becuase the 2-addr copy must be in the same MBB as the redef.
-         interval.removeRange(DefIndex, RedefIndex);
-         
-         LiveRange LR(DefIndex, RedefIndex, interval.getNextValue());
-         DEBUG(std::cerr << " replace range with " << LR);
-         interval.addRange(LR);
-
-         // If this redefinition is dead, we need to add a dummy unit live
-         // range covering the def slot.
-         for (LiveVariables::killed_iterator KI = lv_->dead_begin(mi),
-                E = lv_->dead_end(mi); KI != E; ++KI)
-           if (KI->second == interval.reg) {
-             interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0));
-             break;
-           }
-
-         DEBUG(std::cerr << "RESULT: " << interval);
-
-       } else {
-         // Otherwise, this must be because of phi elimination.  If this is the
-         // first redefinition of the vreg that we have seen, go back and change
-         // the live range in the PHI block to be a different value number.
-         if (interval.containsOneValue()) {
-           assert(vi.Kills.size() == 1 &&
-                  "PHI elimination vreg should have one kill, the PHI itself!");
-
-           // Remove the old range that we now know has an incorrect number.
-           MachineInstr *Killer = vi.Kills[0];
-           unsigned Start = getInstructionIndex(Killer->getParent()->begin());
-           unsigned End = getUseIndex(getInstructionIndex(Killer))+1;
-           DEBUG(std::cerr << "Removing [" << Start << "," << End << "] from: "
-                 << interval << "\n");
-           interval.removeRange(Start, End);
-           DEBUG(std::cerr << "RESULT: " << interval);
-
-           // Replace the interval with one of a NEW value number.
-           LiveRange LR(Start, End, interval.getNextValue());
-           DEBUG(std::cerr << " replace range with " << LR);
-           interval.addRange(LR);
-           DEBUG(std::cerr << "RESULT: " << interval);
-         }
-
-         // In the case of PHI elimination, each variable definition is only
-         // live until the end of the block.  We've already taken care of the
-         // rest of the live range.
-         unsigned defIndex = getDefIndex(getInstructionIndex(mi));
-         LiveRange LR(defIndex, 
-                      getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
-                      interval.getNextValue());
-         interval.addRange(LR);
-         DEBUG(std::cerr << " +" << LR);
-       }
+      // If the kill happens after the definition, we have an intra-block
+      // live range.
+      if (killIdx > defIndex) {
+        assert(vi.AliveBlocks.empty() && 
+               "Shouldn't be alive across any blocks!");
+        LiveRange LR(defIndex, killIdx, ValNum);
+        interval.addRange(LR);
+        DEBUG(std::cerr << " +" << LR << "\n");
+        return;
+      }
     }
 
-    DEBUG(std::cerr << '\n');
+    // The other case we handle is when a virtual register lives to the end
+    // of the defining block, potentially live across some blocks, then is
+    // live into some number of blocks, but gets killed.  Start by adding a
+    // range that goes from this definition to the end of the defining block.
+    LiveRange NewLR(defIndex, getInstructionIndex(&mbb->back()) +
+                    InstrSlots::NUM, ValNum);
+    DEBUG(std::cerr << " +" << NewLR);
+    interval.addRange(NewLR);
+
+    // Iterate over all of the blocks that the variable is completely
+    // live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
+    // live interval.
+    for (unsigned i = 0, e = vi.AliveBlocks.size(); i != e; ++i) {
+      if (vi.AliveBlocks[i]) {
+        MachineBasicBlock* mbb = mf_->getBlockNumbered(i);
+        if (!mbb->empty()) {
+          LiveRange LR(getInstructionIndex(&mbb->front()),
+                       getInstructionIndex(&mbb->back())+InstrSlots::NUM,
+                       ValNum);
+          interval.addRange(LR);
+          DEBUG(std::cerr << " +" << LR);
+        }
+      }
+    }
+
+    // Finally, this virtual register is live from the start of any killing
+    // block to the 'use' slot of the killing instruction.
+    for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
+      MachineInstr *Kill = vi.Kills[i];
+      LiveRange LR(getInstructionIndex(Kill->getParent()->begin()),
+                   getUseIndex(getInstructionIndex(Kill))+1, ValNum);
+      interval.addRange(LR);
+      DEBUG(std::cerr << " +" << LR);
+    }
+
+  } else {
+    // If this is the second time we see a virtual register definition, it
+    // must be due to phi elimination or two addr elimination.  If this is
+    // the result of two address elimination, then the vreg is the first
+    // operand, and is a def-and-use.
+    if (mi->getOperand(0).isRegister() && 
+        mi->getOperand(0).getReg() == interval.reg &&
+        mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) {
+      // If this is a two-address definition, then we have already processed
+      // the live range.  The only problem is that we didn't realize there
+      // are actually two values in the live interval.  Because of this we
+      // need to take the LiveRegion that defines this register and split it
+      // into two values.
+      unsigned DefIndex = getDefIndex(getInstructionIndex(vi.DefInst));
+      unsigned RedefIndex = getDefIndex(getInstructionIndex(mi));
+
+      // Delete the initial value, which should be short and continuous,
+      // becuase the 2-addr copy must be in the same MBB as the redef.
+      interval.removeRange(DefIndex, RedefIndex);
+         
+      LiveRange LR(DefIndex, RedefIndex, interval.getNextValue());
+      DEBUG(std::cerr << " replace range with " << LR);
+      interval.addRange(LR);
+
+      // If this redefinition is dead, we need to add a dummy unit live
+      // range covering the def slot.
+      for (LiveVariables::killed_iterator KI = lv_->dead_begin(mi),
+             E = lv_->dead_end(mi); KI != E; ++KI)
+        if (KI->second == interval.reg) {
+          interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0));
+          break;
+        }
+
+      DEBUG(std::cerr << "RESULT: " << interval);
+
+    } else {
+      // Otherwise, this must be because of phi elimination.  If this is the
+      // first redefinition of the vreg that we have seen, go back and change
+      // the live range in the PHI block to be a different value number.
+      if (interval.containsOneValue()) {
+        assert(vi.Kills.size() == 1 &&
+               "PHI elimination vreg should have one kill, the PHI itself!");
+
+        // Remove the old range that we now know has an incorrect number.
+        MachineInstr *Killer = vi.Kills[0];
+        unsigned Start = getInstructionIndex(Killer->getParent()->begin());
+        unsigned End = getUseIndex(getInstructionIndex(Killer))+1;
+        DEBUG(std::cerr << "Removing [" << Start << "," << End << "] from: "
+              << interval << "\n");
+        interval.removeRange(Start, End);
+        DEBUG(std::cerr << "RESULT: " << interval);
+
+        // Replace the interval with one of a NEW value number.
+        LiveRange LR(Start, End, interval.getNextValue());
+        DEBUG(std::cerr << " replace range with " << LR);
+        interval.addRange(LR);
+        DEBUG(std::cerr << "RESULT: " << interval);
+      }
+
+      // In the case of PHI elimination, each variable definition is only
+      // live until the end of the block.  We've already taken care of the
+      // rest of the live range.
+      unsigned defIndex = getDefIndex(getInstructionIndex(mi));
+      LiveRange LR(defIndex, 
+                   getInstructionIndex(&mbb->back()) + InstrSlots::NUM,
+                   interval.getNextValue());
+      interval.addRange(LR);
+      DEBUG(std::cerr << " +" << LR);
+    }
+  }
+
+  DEBUG(std::cerr << '\n');
 }
 
 void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
                                               MachineBasicBlock::iterator mi,
                                               LiveInterval& interval)
 {
-    // A physical register cannot be live across basic block, so its
-    // lifetime must end somewhere in its defining basic block.
-    DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
-    typedef LiveVariables::killed_iterator KillIter;
+  // A physical register cannot be live across basic block, so its
+  // lifetime must end somewhere in its defining basic block.
+  DEBUG(std::cerr << "\t\tregister: "; printRegName(interval.reg));
+  typedef LiveVariables::killed_iterator KillIter;
 
-    unsigned baseIndex = getInstructionIndex(mi);
-    unsigned start = getDefIndex(baseIndex);
-    unsigned end = start;
+  unsigned baseIndex = getInstructionIndex(mi);
+  unsigned start = getDefIndex(baseIndex);
+  unsigned end = start;
 
-    // If it is not used after definition, it is considered dead at
-    // the instruction defining it. Hence its interval is:
-    // [defSlot(def), defSlot(def)+1)
-    for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi);
+  // If it is not used after definition, it is considered dead at
+  // the instruction defining it. Hence its interval is:
+  // [defSlot(def), defSlot(def)+1)
+  for (KillIter ki = lv_->dead_begin(mi), ke = lv_->dead_end(mi);
+       ki != ke; ++ki) {
+    if (interval.reg == ki->second) {
+      DEBUG(std::cerr << " dead");
+      end = getDefIndex(start) + 1;
+      goto exit;
+    }
+  }
+
+  // If it is not dead on definition, it must be killed by a
+  // subsequent instruction. Hence its interval is:
+  // [defSlot(def), useSlot(kill)+1)
+  while (true) {
+    ++mi;
+    assert(mi != MBB->end() && "physreg was not killed in defining block!");
+    baseIndex += InstrSlots::NUM;
+    for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi);
          ki != ke; ++ki) {
-        if (interval.reg == ki->second) {
-            DEBUG(std::cerr << " dead");
-            end = getDefIndex(start) + 1;
-            goto exit;
-        }
+      if (interval.reg == ki->second) {
+        DEBUG(std::cerr << " killed");
+        end = getUseIndex(baseIndex) + 1;
+        goto exit;
+      }
     }
-
-    // If it is not dead on definition, it must be killed by a
-    // subsequent instruction. Hence its interval is:
-    // [defSlot(def), useSlot(kill)+1)
-    while (true) {
-        ++mi;
-        assert(mi != MBB->end() && "physreg was not killed in defining block!");
-        baseIndex += InstrSlots::NUM;
-        for (KillIter ki = lv_->killed_begin(mi), ke = lv_->killed_end(mi);
-             ki != ke; ++ki) {
-            if (interval.reg == ki->second) {
-                DEBUG(std::cerr << " killed");
-                end = getUseIndex(baseIndex) + 1;
-                goto exit;
-            }
-        }
-    }
+  }
 
 exit:
-    assert(start < end && "did not find end of interval?");
-    LiveRange LR(start, end, interval.getNextValue());
-    interval.addRange(LR);
-    DEBUG(std::cerr << " +" << LR << '\n');
+  assert(start < end && "did not find end of interval?");
+  LiveRange LR(start, end, interval.getNextValue());
+  interval.addRange(LR);
+  DEBUG(std::cerr << " +" << LR << '\n');
 }
 
 void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
@@ -498,35 +497,35 @@
 /// which a variable is live
 void LiveIntervals::computeIntervals()
 {
-    DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n");
-    DEBUG(std::cerr << "********** Function: "
-          << ((Value*)mf_->getFunction())->getName() << '\n');
+  DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n");
+  DEBUG(std::cerr << "********** Function: "
+        << ((Value*)mf_->getFunction())->getName() << '\n');
 
-    for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); 
-         I != E; ++I) {
-        MachineBasicBlock* mbb = I;
-        DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n");
+  for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); 
+       I != E; ++I) {
+    MachineBasicBlock* mbb = I;
+    DEBUG(std::cerr << ((Value*)mbb->getBasicBlock())->getName() << ":\n");
 
-        for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
-             mi != miEnd; ++mi) {
-            const TargetInstrDescriptor& tid =
-                tm_->getInstrInfo()->get(mi->getOpcode());
-            DEBUG(std::cerr << getInstructionIndex(mi) << "\t";
-                  mi->print(std::cerr, tm_));
+    for (MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
+         mi != miEnd; ++mi) {
+      const TargetInstrDescriptor& tid =
+        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 implicit defs
+      for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
+        handleRegisterDef(mbb, mi, *id);
 
-            // handle explicit defs
-            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());
-            }
-        }
+      // handle explicit defs
+      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());
+      }
     }
+  }
 }
 
 void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
@@ -543,9 +542,9 @@
     unsigned regA, regB;
     if (TII.isMoveInstr(*mi, regA, regB) &&
         (MRegisterInfo::isVirtualRegister(regA) ||
-                 lv_->getAllocatablePhysicalRegisters()[regA]) &&
+         lv_->getAllocatablePhysicalRegisters()[regA]) &&
         (MRegisterInfo::isVirtualRegister(regB) ||
-                 lv_->getAllocatablePhysicalRegisters()[regB])) {
+         lv_->getAllocatablePhysicalRegisters()[regB])) {
       
       // Get representative registers.
       regA = rep(regA);
@@ -609,7 +608,7 @@
     bool operator()(const DepthMBBPair &LHS, const DepthMBBPair &RHS) const {
       if (LHS.first > RHS.first) return true;   // Deeper loops first
       return LHS.first == RHS.first && 
-             LHS.second->getNumber() < RHS.second->getNumber();
+        LHS.second->getNumber() < RHS.second->getNumber();
     }
   };
 }
@@ -642,8 +641,8 @@
 
   DEBUG(std::cerr << "*** Register mapping ***\n");
   DEBUG(for (std::map<unsigned, unsigned>::iterator I = r2rMap_.begin(),
-             E = r2rMap_.end(); I != E; ++I)
-          std::cerr << "  reg " << I->first << " -> reg " << I->second << "\n";);
+               E = r2rMap_.end(); I != E; ++I)
+        std::cerr << "  reg " << I->first << " -> reg " << I->second << "\n";);
 }
 
 /// Return true if the two specified registers belong to different register
diff --git a/lib/CodeGen/LiveIntervalAnalysis.h b/lib/CodeGen/LiveIntervalAnalysis.h
index e4e31ec..de7cc80 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.h
+++ b/lib/CodeGen/LiveIntervalAnalysis.h
@@ -25,160 +25,160 @@
 
 namespace llvm {
 
-    class LiveVariables;
-    class MRegisterInfo;
-    class VirtRegMap;
+  class LiveVariables;
+  class MRegisterInfo;
+  class VirtRegMap;
 
-    class LiveIntervals : public MachineFunctionPass {
-        MachineFunction* mf_;
-        const TargetMachine* tm_;
-        const MRegisterInfo* mri_;
-        LiveVariables* lv_;
+  class LiveIntervals : public MachineFunctionPass {
+    MachineFunction* mf_;
+    const TargetMachine* tm_;
+    const MRegisterInfo* mri_;
+    LiveVariables* lv_;
 
-        typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
-        Mi2IndexMap mi2iMap_;
+    typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
+    Mi2IndexMap mi2iMap_;
 
-        typedef std::vector<MachineInstr*> Index2MiMap;
-        Index2MiMap i2miMap_;
+    typedef std::vector<MachineInstr*> Index2MiMap;
+    Index2MiMap i2miMap_;
 
-        typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
-        Reg2IntervalMap r2iMap_;
+    typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
+    Reg2IntervalMap r2iMap_;
 
-        typedef std::map<unsigned, unsigned> Reg2RegMap;
-        Reg2RegMap r2rMap_;
+    typedef std::map<unsigned, unsigned> Reg2RegMap;
+    Reg2RegMap r2rMap_;
 
-    public:
-        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;
-        }
-
-        // FIXME: this should really be a const_iterator
-        typedef Reg2IntervalMap::iterator iterator;
-        iterator begin() { return r2iMap_.begin(); }
-        iterator end() { return r2iMap_.end(); }
-        unsigned getNumIntervals() const { return r2iMap_.size(); }
-
-        LiveInterval &getInterval(unsigned reg) {
-          Reg2IntervalMap::iterator I = r2iMap_.find(reg);
-          assert(I != r2iMap_.end() && "Interval does not exist for register");
-          return I->second;
-        }
-
-        const LiveInterval &getInterval(unsigned reg) const {
-          Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
-          assert(I != r2iMap_.end() && "Interval does not exist for register");
-          return I->second;
-        }
-
-        /// getInstructionIndex - returns the base index of instr
-        unsigned getInstructionIndex(MachineInstr* instr) const {
-          Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
-          assert(it != mi2iMap_.end() && "Invalid instruction!");
-          return it->second;
-        }
-
-        /// getInstructionFromIndex - given an index in any slot of an
-        /// instruction return a pointer the instruction
-        MachineInstr* 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];
-        }
-
-        std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
-                                                         VirtRegMap& vrm,
-                                                         int slot);
-
-        virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-        virtual void releaseMemory();
-
-        /// runOnMachineFunction - pass entry point
-        virtual bool runOnMachineFunction(MachineFunction&);
-
-    private:
-        /// computeIntervals - compute live intervals
-        void computeIntervals();
-
-        /// joinIntervals - join compatible live intervals
-        void joinIntervals();
-
-        /// joinIntervalsInMachineBB - Join intervals based on move
-        /// instructions in the specified basic block.
-        void joinIntervalsInMachineBB(MachineBasicBlock *MBB);
-
-        /// handleRegisterDef - update intervals for a register def
-        /// (calls handlePhysicalRegisterDef and
-        /// handleVirtualRegisterDef)
-        void handleRegisterDef(MachineBasicBlock* mbb,
-                               MachineBasicBlock::iterator mi,
-                               unsigned reg);
-
-        /// handleVirtualRegisterDef - update intervals for a virtual
-        /// register def
-        void handleVirtualRegisterDef(MachineBasicBlock* mbb,
-                                      MachineBasicBlock::iterator mi,
-                                      LiveInterval& interval);
-
-        /// handlePhysicalRegisterDef - update intervals for a
-        /// physical register def
-        void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
-                                       MachineBasicBlock::iterator mi,
-                                       LiveInterval& interval);
-
-        /// Return true if the two specified registers belong to different
-        /// register classes.  The registers may be either phys or virt regs.
-        bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
-
-        bool overlapsAliases(const LiveInterval *lhs, 
-                             const LiveInterval *rhs) const;
-
-        static LiveInterval createInterval(unsigned Reg);
-
-        LiveInterval &getOrCreateInterval(unsigned reg) {
-          Reg2IntervalMap::iterator I = r2iMap_.find(reg);
-          if (I == r2iMap_.end())
-            I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
-          return I->second;
-        }
-
-        /// rep - returns the representative of this register
-        unsigned rep(unsigned reg) {
-          Reg2RegMap::iterator it = r2rMap_.find(reg);
-          if (it != r2rMap_.end())
-            return it->second = rep(it->second);
-          return reg;
-        }
-
-        void printRegName(unsigned reg) const;
+  public:
+    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;
+    }
+
+    // FIXME: this should really be a const_iterator
+    typedef Reg2IntervalMap::iterator iterator;
+    iterator begin() { return r2iMap_.begin(); }
+    iterator end() { return r2iMap_.end(); }
+    unsigned getNumIntervals() const { return r2iMap_.size(); }
+
+    LiveInterval &getInterval(unsigned reg) {
+      Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+      assert(I != r2iMap_.end() && "Interval does not exist for register");
+      return I->second;
+    }
+
+    const LiveInterval &getInterval(unsigned reg) const {
+      Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
+      assert(I != r2iMap_.end() && "Interval does not exist for register");
+      return I->second;
+    }
+
+    /// getInstructionIndex - returns the base index of instr
+    unsigned getInstructionIndex(MachineInstr* instr) const {
+      Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
+      assert(it != mi2iMap_.end() && "Invalid instruction!");
+      return it->second;
+    }
+
+    /// getInstructionFromIndex - given an index in any slot of an
+    /// instruction return a pointer the instruction
+    MachineInstr* 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];
+    }
+
+    std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
+                                                     VirtRegMap& vrm,
+                                                     int slot);
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+    virtual void releaseMemory();
+
+    /// runOnMachineFunction - pass entry point
+    virtual bool runOnMachineFunction(MachineFunction&);
+
+  private:
+    /// computeIntervals - compute live intervals
+    void computeIntervals();
+
+    /// joinIntervals - join compatible live intervals
+    void joinIntervals();
+
+    /// joinIntervalsInMachineBB - Join intervals based on move
+    /// instructions in the specified basic block.
+    void joinIntervalsInMachineBB(MachineBasicBlock *MBB);
+
+    /// handleRegisterDef - update intervals for a register def
+    /// (calls handlePhysicalRegisterDef and
+    /// handleVirtualRegisterDef)
+    void handleRegisterDef(MachineBasicBlock* mbb,
+                           MachineBasicBlock::iterator mi,
+                           unsigned reg);
+
+    /// handleVirtualRegisterDef - update intervals for a virtual
+    /// register def
+    void handleVirtualRegisterDef(MachineBasicBlock* mbb,
+                                  MachineBasicBlock::iterator mi,
+                                  LiveInterval& interval);
+
+    /// handlePhysicalRegisterDef - update intervals for a
+    /// physical register def
+    void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
+                                   MachineBasicBlock::iterator mi,
+                                   LiveInterval& interval);
+
+    /// Return true if the two specified registers belong to different
+    /// register classes.  The registers may be either phys or virt regs.
+    bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
+
+    bool overlapsAliases(const LiveInterval *lhs, 
+                         const LiveInterval *rhs) const;
+
+    static LiveInterval createInterval(unsigned Reg);
+
+    LiveInterval &getOrCreateInterval(unsigned reg) {
+      Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+      if (I == r2iMap_.end())
+        I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
+      return I->second;
+    }
+
+    /// rep - returns the representative of this register
+    unsigned rep(unsigned reg) {
+      Reg2RegMap::iterator it = r2rMap_.find(reg);
+      if (it != r2rMap_.end())
+        return it->second = rep(it->second);
+      return reg;
+    }
+
+    void printRegName(unsigned reg) const;
+  };
+
 } // End llvm namespace
 
 #endif
diff --git a/lib/CodeGen/RegAllocIterativeScan.cpp b/lib/CodeGen/RegAllocIterativeScan.cpp
index e9e9fd8..ddd0451 100644
--- a/lib/CodeGen/RegAllocIterativeScan.cpp
+++ b/lib/CodeGen/RegAllocIterativeScan.cpp
@@ -40,439 +40,439 @@
 
 namespace {
 
-    Statistic<double> efficiency
-    ("regalloc", "Ratio of intervals processed over total intervals");
+  Statistic<double> efficiency
+  ("regalloc", "Ratio of intervals processed over total intervals");
 
-    static unsigned numIterations = 0;
-    static unsigned numIntervals = 0;
+  static unsigned numIterations = 0;
+  static unsigned numIntervals = 0;
 
-    class RA : public MachineFunctionPass {
-    private:
-        MachineFunction* mf_;
-        const TargetMachine* tm_;
-        const MRegisterInfo* mri_;
-        LiveIntervals* li_;
-        typedef std::vector<LiveInterval*> IntervalPtrs;
-        IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_;
+  class RA : public MachineFunctionPass {
+  private:
+    MachineFunction* mf_;
+    const TargetMachine* tm_;
+    const MRegisterInfo* mri_;
+    LiveIntervals* li_;
+    typedef std::vector<LiveInterval*> IntervalPtrs;
+    IntervalPtrs unhandled_, fixed_, active_, inactive_, handled_, spilled_;
 
-        std::auto_ptr<PhysRegTracker> prt_;
-        std::auto_ptr<VirtRegMap> vrm_;
-        std::auto_ptr<Spiller> spiller_;
+    std::auto_ptr<PhysRegTracker> prt_;
+    std::auto_ptr<VirtRegMap> vrm_;
+    std::auto_ptr<Spiller> spiller_;
 
-        typedef std::vector<float> SpillWeights;
-        SpillWeights spillWeights_;
+    typedef std::vector<float> SpillWeights;
+    SpillWeights spillWeights_;
 
-    public:
-        virtual const char* getPassName() const {
-            return "Iterative Scan Register Allocator";
+  public:
+    virtual const char* getPassName() const {
+      return "Iterative Scan Register Allocator";
+    }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<LiveVariables>();
+      AU.addRequired<LiveIntervals>();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
+    /// runOnMachineFunction - register allocate the whole function
+    bool runOnMachineFunction(MachineFunction&);
+
+    void releaseMemory();
+
+  private:
+    /// linearScan - the linear scan algorithm. Returns a boolean
+    /// indicating if there were any spills
+    bool linearScan();
+
+    /// initIntervalSets - initializes the four interval sets:
+    /// unhandled, fixed, active and inactive
+    void initIntervalSets();
+
+    /// processActiveIntervals - expire old intervals and move
+    /// non-overlapping ones to the incative list
+    void processActiveIntervals(IntervalPtrs::value_type cur);
+
+    /// processInactiveIntervals - expire old intervals and move
+    /// overlapping ones to the active list
+    void processInactiveIntervals(IntervalPtrs::value_type cur);
+
+    /// updateSpillWeights - updates the spill weights of the
+    /// specifed physical register and its weight
+    void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
+
+    /// assignRegOrStackSlotAtInterval - assign a register if one
+    /// is available, or spill.
+    void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur);
+
+    ///
+    /// register handling helpers
+    ///
+
+    /// getFreePhysReg - return a free physical register for this
+    /// virtual register interval if we have one, otherwise return
+    /// 0
+    unsigned getFreePhysReg(IntervalPtrs::value_type cur);
+
+    /// assignVirt2StackSlot - assigns this virtual register to a
+    /// stack slot. returns the stack slot
+    int assignVirt2StackSlot(unsigned virtReg);
+
+    void printIntervals(const char* const str,
+                        RA::IntervalPtrs::const_iterator i,
+                        RA::IntervalPtrs::const_iterator e) const {
+      if (str) std::cerr << str << " intervals:\n";
+      for (; i != e; ++i) {
+        std::cerr << "\t" << **i << " -> ";
+        unsigned reg = (*i)->reg;
+        if (MRegisterInfo::isVirtualRegister(reg)) {
+          reg = vrm_->getPhys(reg);
         }
-
-        virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-            AU.addRequired<LiveVariables>();
-            AU.addRequired<LiveIntervals>();
-            MachineFunctionPass::getAnalysisUsage(AU);
-        }
-
-        /// runOnMachineFunction - register allocate the whole function
-        bool runOnMachineFunction(MachineFunction&);
-
-        void releaseMemory();
-
-    private:
-        /// linearScan - the linear scan algorithm. Returns a boolean
-        /// indicating if there were any spills
-        bool linearScan();
-
-        /// initIntervalSets - initializes the four interval sets:
-        /// unhandled, fixed, active and inactive
-        void initIntervalSets();
-
-        /// processActiveIntervals - expire old intervals and move
-        /// non-overlapping ones to the incative list
-        void processActiveIntervals(IntervalPtrs::value_type cur);
-
-        /// processInactiveIntervals - expire old intervals and move
-        /// overlapping ones to the active list
-        void processInactiveIntervals(IntervalPtrs::value_type cur);
-
-        /// updateSpillWeights - updates the spill weights of the
-        /// specifed physical register and its weight
-        void updateSpillWeights(unsigned reg, SpillWeights::value_type weight);
-
-        /// assignRegOrStackSlotAtInterval - assign a register if one
-        /// is available, or spill.
-        void assignRegOrSpillAtInterval(IntervalPtrs::value_type cur);
-
-        ///
-        /// register handling helpers
-        ///
-
-        /// getFreePhysReg - return a free physical register for this
-        /// virtual register interval if we have one, otherwise return
-        /// 0
-        unsigned getFreePhysReg(IntervalPtrs::value_type cur);
-
-        /// assignVirt2StackSlot - assigns this virtual register to a
-        /// stack slot. returns the stack slot
-        int assignVirt2StackSlot(unsigned virtReg);
-
-        void printIntervals(const char* const str,
-                            RA::IntervalPtrs::const_iterator i,
-                            RA::IntervalPtrs::const_iterator e) const {
-            if (str) std::cerr << str << " intervals:\n";
-            for (; i != e; ++i) {
-                std::cerr << "\t" << **i << " -> ";
-                unsigned reg = (*i)->reg;
-                if (MRegisterInfo::isVirtualRegister(reg)) {
-                    reg = vrm_->getPhys(reg);
-                }
-                std::cerr << mri_->getName(reg) << '\n';
-            }
-        }
-    };
+        std::cerr << mri_->getName(reg) << '\n';
+      }
+    }
+  };
 }
 
 void RA::releaseMemory()
 {
-    unhandled_.clear();
-    fixed_.clear();
-    active_.clear();
-    inactive_.clear();
-    handled_.clear();
-    spilled_.clear();
+  unhandled_.clear();
+  fixed_.clear();
+  active_.clear();
+  inactive_.clear();
+  handled_.clear();
+  spilled_.clear();
 }
 
 bool RA::runOnMachineFunction(MachineFunction &fn) {
-    mf_ = &fn;
-    tm_ = &fn.getTarget();
-    mri_ = tm_->getRegisterInfo();
-    li_ = &getAnalysis<LiveIntervals>();
-    if (!prt_.get()) prt_.reset(new PhysRegTracker(*mri_));
-    vrm_.reset(new VirtRegMap(*mf_));
-    if (!spiller_.get()) spiller_.reset(createSpiller());
+  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();
+  initIntervalSets();
 
-    numIntervals += li_->getNumIntervals();
+  numIntervals += li_->getNumIntervals();
 
-    while (linearScan()) {
-        // we spilled some registers, so we need to add intervals for
-        // the spill code and restart the algorithm
-        std::set<unsigned> spilledRegs;
-        for (IntervalPtrs::iterator
-                 i = spilled_.begin(); i != spilled_.end(); ++i) {
-            int slot = vrm_->assignVirt2StackSlot((*i)->reg);
-            std::vector<LiveInterval*> added =
-                li_->addIntervalsForSpills(**i, *vrm_, slot);
-            std::copy(added.begin(), added.end(), std::back_inserter(handled_));
-            spilledRegs.insert((*i)->reg);
-        }
-        spilled_.clear();
-        for (IntervalPtrs::iterator
-                 i = handled_.begin(); i != handled_.end(); )
-            if (spilledRegs.count((*i)->reg))
-                i = handled_.erase(i);
-            else
-                ++i;
-        handled_.swap(unhandled_);
-        vrm_->clearAllVirt();
+  while (linearScan()) {
+    // we spilled some registers, so we need to add intervals for
+    // the spill code and restart the algorithm
+    std::set<unsigned> spilledRegs;
+    for (IntervalPtrs::iterator
+           i = spilled_.begin(); i != spilled_.end(); ++i) {
+      int slot = vrm_->assignVirt2StackSlot((*i)->reg);
+      std::vector<LiveInterval*> added =
+        li_->addIntervalsForSpills(**i, *vrm_, slot);
+      std::copy(added.begin(), added.end(), std::back_inserter(handled_));
+      spilledRegs.insert((*i)->reg);
     }
+    spilled_.clear();
+    for (IntervalPtrs::iterator
+           i = handled_.begin(); i != handled_.end(); )
+      if (spilledRegs.count((*i)->reg))
+        i = handled_.erase(i);
+      else
+        ++i;
+    handled_.swap(unhandled_);
+    vrm_->clearAllVirt();
+  }
 
-    efficiency = double(numIterations) / double(numIntervals);
+  efficiency = double(numIterations) / double(numIntervals);
 
-    DEBUG(std::cerr << *vrm_);
+  DEBUG(std::cerr << *vrm_);
 
-    spiller_->runOnMachineFunction(*mf_, *vrm_);
+  spiller_->runOnMachineFunction(*mf_, *vrm_);
 
-    return true;
+  return true;
 }
 
 bool RA::linearScan()
 {
-    // linear scan algorithm
-    DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
-    DEBUG(std::cerr << "********** Function: "
-          << mf_->getFunction()->getName() << '\n');
+  // linear scan algorithm
+  DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
+  DEBUG(std::cerr << "********** Function: "
+        << mf_->getFunction()->getName() << '\n');
 
 
-    std::sort(unhandled_.begin(), unhandled_.end(),
-              greater_ptr<LiveInterval>());
-    DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end()));
-    DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
+  std::sort(unhandled_.begin(), unhandled_.end(),
+            greater_ptr<LiveInterval>());
+  DEBUG(printIntervals("unhandled", unhandled_.begin(), unhandled_.end()));
+  DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
+  DEBUG(printIntervals("active", active_.begin(), active_.end()));
+  DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
+
+  while (!unhandled_.empty()) {
+    // pick the interval with the earliest start point
+    IntervalPtrs::value_type cur = unhandled_.back();
+    unhandled_.pop_back();
+    ++numIterations;
+    DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
+
+    processActiveIntervals(cur);
+    processInactiveIntervals(cur);
+
+    // if this register is fixed we are done
+    if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
+      prt_->addRegUse(cur->reg);
+      active_.push_back(cur);
+      handled_.push_back(cur);
+    }
+    // otherwise we are allocating a virtual register. try to find
+    // a free physical register or spill an interval in order to
+    // assign it one (we could spill the current though).
+    else {
+      assignRegOrSpillAtInterval(cur);
+    }
+
     DEBUG(printIntervals("active", active_.begin(), active_.end()));
     DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
+  }
 
-    while (!unhandled_.empty()) {
-        // pick the interval with the earliest start point
-        IntervalPtrs::value_type cur = unhandled_.back();
-        unhandled_.pop_back();
-        ++numIterations;
-        DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
+  // expire any remaining active intervals
+  for (IntervalPtrs::reverse_iterator
+         i = active_.rbegin(); i != active_.rend(); ) {
+    unsigned reg = (*i)->reg;
+    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
+    if (MRegisterInfo::isVirtualRegister(reg))
+      reg = vrm_->getPhys(reg);
+    prt_->delRegUse(reg);
+    i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
+  }
 
-        processActiveIntervals(cur);
-        processInactiveIntervals(cur);
+  // expire any remaining inactive intervals
+  for (IntervalPtrs::reverse_iterator
+         i = inactive_.rbegin(); i != inactive_.rend(); ) {
+    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
+    i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
+  }
 
-        // if this register is fixed we are done
-        if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
-            prt_->addRegUse(cur->reg);
-            active_.push_back(cur);
-            handled_.push_back(cur);
-        }
-        // otherwise we are allocating a virtual register. try to find
-        // a free physical register or spill an interval in order to
-        // assign it one (we could spill the current though).
-        else {
-            assignRegOrSpillAtInterval(cur);
-        }
-
-        DEBUG(printIntervals("active", active_.begin(), active_.end()));
-        DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
-    }
-    
-    // expire any remaining active intervals
-    for (IntervalPtrs::reverse_iterator
-             i = active_.rbegin(); i != active_.rend(); ) {
-        unsigned reg = (*i)->reg;
-        DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
-        if (MRegisterInfo::isVirtualRegister(reg))
-            reg = vrm_->getPhys(reg);
-        prt_->delRegUse(reg);
-        i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-    }
-
-    // expire any remaining inactive intervals
-    for (IntervalPtrs::reverse_iterator
-             i = inactive_.rbegin(); i != inactive_.rend(); ) {
-        DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
-        i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-    }
-
-    // return true if we spilled anything
-    return !spilled_.empty();
+  // return true if we spilled anything
+  return !spilled_.empty();
 }
 
 void RA::initIntervalSets() {
-    assert(unhandled_.empty() && fixed_.empty() &&
-           active_.empty() && inactive_.empty() &&
-           "interval sets should be empty on initialization");
+  assert(unhandled_.empty() && fixed_.empty() &&
+         active_.empty() && inactive_.empty() &&
+         "interval sets should be empty on initialization");
 
-    for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
-      unhandled_.push_back(&i->second);
-      if (MRegisterInfo::isPhysicalRegister(i->second.reg))
-        fixed_.push_back(&i->second);
-    }
+  for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
+    unhandled_.push_back(&i->second);
+    if (MRegisterInfo::isPhysicalRegister(i->second.reg))
+      fixed_.push_back(&i->second);
+  }
 }
 
 void RA::processActiveIntervals(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\tprocessing active intervals:\n");
-    for (IntervalPtrs::reverse_iterator
-             i = active_.rbegin(); i != active_.rend();) {
-        unsigned reg = (*i)->reg;
-        // remove expired intervals
-        if ((*i)->expiredAt(cur->start())) {
-            DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-            if (MRegisterInfo::isVirtualRegister(reg))
-                reg = vrm_->getPhys(reg);
-            prt_->delRegUse(reg);
-            // remove from active
-            i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-        }
-        // move inactive intervals to inactive list
-        else if (!(*i)->liveAt(cur->start())) {
-            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
-            i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-        }
-        else {
-            ++i;
-        }
+  DEBUG(std::cerr << "\tprocessing active intervals:\n");
+  for (IntervalPtrs::reverse_iterator
+         i = active_.rbegin(); i != active_.rend();) {
+    unsigned reg = (*i)->reg;
+    // remove expired intervals
+    if ((*i)->expiredAt(cur->start())) {
+      DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
+      if (MRegisterInfo::isVirtualRegister(reg))
+        reg = vrm_->getPhys(reg);
+      prt_->delRegUse(reg);
+      // remove from active
+      i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
     }
+    // move inactive intervals to inactive list
+    else if (!(*i)->liveAt(cur->start())) {
+      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
+      i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
+    }
+    else {
+      ++i;
+    }
+  }
 }
 
 void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
-    for (IntervalPtrs::reverse_iterator
-             i = inactive_.rbegin(); i != inactive_.rend();) {
-        unsigned reg = (*i)->reg;
+  DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
+  for (IntervalPtrs::reverse_iterator
+         i = inactive_.rbegin(); i != inactive_.rend();) {
+    unsigned reg = (*i)->reg;
 
-        // remove expired intervals
-        if ((*i)->expiredAt(cur->start())) {
-            DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-            // remove from inactive
-            i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-        }
-        // move re-activated intervals in active list
-        else if ((*i)->liveAt(cur->start())) {
-            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
-            i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-        }
-        else {
-            ++i;
-        }
+    // remove expired intervals
+    if ((*i)->expiredAt(cur->start())) {
+      DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
+      // remove from inactive
+      i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
     }
+    // move re-activated intervals in active list
+    else if ((*i)->liveAt(cur->start())) {
+      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
+      i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
+    }
+    else {
+      ++i;
+    }
+  }
 }
 
 void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
 {
-    spillWeights_[reg] += weight;
-    for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
-        spillWeights_[*as] += weight;
+  spillWeights_[reg] += weight;
+  for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
+    spillWeights_[*as] += weight;
 }
 
 void RA::assignRegOrSpillAtInterval(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\tallocating current interval: ");
+  DEBUG(std::cerr << "\tallocating current interval: ");
 
-    PhysRegTracker backupPrt = *prt_;
+  PhysRegTracker backupPrt = *prt_;
 
-    spillWeights_.assign(mri_->getNumRegs(), 0.0);
+  spillWeights_.assign(mri_->getNumRegs(), 0.0);
 
-    // for each interval in active update spill weights
-    for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
-         i != e; ++i) {
-        unsigned reg = (*i)->reg;
-        if (MRegisterInfo::isVirtualRegister(reg))
-            reg = vrm_->getPhys(reg);
-        updateSpillWeights(reg, (*i)->weight);
+  // for each interval in active update spill weights
+  for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
+       i != e; ++i) {
+    unsigned reg = (*i)->reg;
+    if (MRegisterInfo::isVirtualRegister(reg))
+      reg = vrm_->getPhys(reg);
+    updateSpillWeights(reg, (*i)->weight);
+  }
+
+  // for every interval in inactive we overlap with, mark the
+  // register as not free and update spill weights
+  for (IntervalPtrs::const_iterator i = inactive_.begin(),
+         e = inactive_.end(); i != e; ++i) {
+    if (cur->overlaps(**i)) {
+      unsigned reg = (*i)->reg;
+      if (MRegisterInfo::isVirtualRegister(reg))
+        reg = vrm_->getPhys(reg);
+      prt_->addRegUse(reg);
+      updateSpillWeights(reg, (*i)->weight);
     }
+  }
 
-    // for every interval in inactive we overlap with, mark the
-    // register as not free and update spill weights
-    for (IntervalPtrs::const_iterator i = inactive_.begin(),
-             e = inactive_.end(); i != e; ++i) {
-        if (cur->overlaps(**i)) {
-            unsigned reg = (*i)->reg;
-            if (MRegisterInfo::isVirtualRegister(reg))
-                reg = vrm_->getPhys(reg);
-            prt_->addRegUse(reg);
-            updateSpillWeights(reg, (*i)->weight);
-        }
+  // for every interval in fixed we overlap with,
+  // mark the register as not free and update spill weights
+  for (IntervalPtrs::const_iterator i = fixed_.begin(),
+         e = fixed_.end(); i != e; ++i) {
+    if (cur->overlaps(**i)) {
+      unsigned reg = (*i)->reg;
+      prt_->addRegUse(reg);
+      updateSpillWeights(reg, (*i)->weight);
     }
+  }
 
-    // for every interval in fixed we overlap with,
-    // mark the register as not free and update spill weights
-    for (IntervalPtrs::const_iterator i = fixed_.begin(),
-             e = fixed_.end(); i != e; ++i) {
-        if (cur->overlaps(**i)) {
-            unsigned reg = (*i)->reg;
-            prt_->addRegUse(reg);
-            updateSpillWeights(reg, (*i)->weight);
-        }
-    }
-
-    unsigned physReg = getFreePhysReg(cur);
-    // restore the physical register tracker
-    *prt_ = backupPrt;
-    // if we find a free register, we are done: assign this virtual to
-    // the free physical register and add this interval to the active
-    // list.
-    if (physReg) {
-        DEBUG(std::cerr <<  mri_->getName(physReg) << '\n');
-        vrm_->assignVirt2Phys(cur->reg, physReg);
-        prt_->addRegUse(physReg);
-        active_.push_back(cur);
-        handled_.push_back(cur);
-        return;
-    }
-    DEBUG(std::cerr << "no free registers\n");
-
-    DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
-
-    float minWeight = HUGE_VAL;
-    unsigned minReg = 0;
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
-    for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
-         i != rc->allocation_order_end(*mf_); ++i) {
-        unsigned reg = *i;
-        if (minWeight > spillWeights_[reg]) {
-            minWeight = spillWeights_[reg];
-            minReg = reg;
-        }
-    }
-    DEBUG(std::cerr << "\t\tregister with min weight: "
-          << mri_->getName(minReg) << " (" << minWeight << ")\n");
-
-    // if the current has the minimum weight, we spill it and move on
-    if (cur->weight <= minWeight) {
-        DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n');
-        spilled_.push_back(cur);
-        return;
-    }
-
-    // otherwise we spill all intervals aliasing the register with
-    // minimum weight, assigned the newly cleared register to the
-    // current interval and continue
-    assert(MRegisterInfo::isPhysicalRegister(minReg) &&
-           "did not choose a register to spill?");
-    std::vector<bool> toSpill(mri_->getNumRegs(), false);
-    toSpill[minReg] = true;
-    for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
-        toSpill[*as] = true;
-    unsigned earliestStart = cur->start();
-
-    std::set<unsigned> spilled;
-
-    for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) {
-        unsigned reg = (*i)->reg;
-        if (MRegisterInfo::isVirtualRegister(reg) &&
-            toSpill[vrm_->getPhys(reg)] &&
-            cur->overlaps(**i)) {
-            DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
-            spilled_.push_back(*i);
-            prt_->delRegUse(vrm_->getPhys(reg));
-            vrm_->clearVirt(reg);
-            i = active_.erase(i);
-        }
-        else
-            ++i;
-    }
-    for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) {
-        unsigned reg = (*i)->reg;
-        if (MRegisterInfo::isVirtualRegister(reg) &&
-            toSpill[vrm_->getPhys(reg)] &&
-            cur->overlaps(**i)) {
-            DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
-            spilled_.push_back(*i);
-            vrm_->clearVirt(reg);
-            i = inactive_.erase(i);
-        }
-        else
-            ++i;
-    }
-
-    vrm_->assignVirt2Phys(cur->reg, minReg);
-    prt_->addRegUse(minReg);
+  unsigned physReg = getFreePhysReg(cur);
+  // restore the physical register tracker
+  *prt_ = backupPrt;
+  // if we find a free register, we are done: assign this virtual to
+  // the free physical register and add this interval to the active
+  // list.
+  if (physReg) {
+    DEBUG(std::cerr <<  mri_->getName(physReg) << '\n');
+    vrm_->assignVirt2Phys(cur->reg, physReg);
+    prt_->addRegUse(physReg);
     active_.push_back(cur);
     handled_.push_back(cur);
+    return;
+  }
+  DEBUG(std::cerr << "no free registers\n");
+
+  DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
+
+  float minWeight = HUGE_VAL;
+  unsigned minReg = 0;
+  const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
+  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
+       i != rc->allocation_order_end(*mf_); ++i) {
+    unsigned reg = *i;
+    if (minWeight > spillWeights_[reg]) {
+      minWeight = spillWeights_[reg];
+      minReg = reg;
+    }
+  }
+  DEBUG(std::cerr << "\t\tregister with min weight: "
+        << mri_->getName(minReg) << " (" << minWeight << ")\n");
+
+  // if the current has the minimum weight, we spill it and move on
+  if (cur->weight <= minWeight) {
+    DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n');
+    spilled_.push_back(cur);
+    return;
+  }
+
+  // otherwise we spill all intervals aliasing the register with
+  // minimum weight, assigned the newly cleared register to the
+  // current interval and continue
+  assert(MRegisterInfo::isPhysicalRegister(minReg) &&
+         "did not choose a register to spill?");
+  std::vector<bool> toSpill(mri_->getNumRegs(), false);
+  toSpill[minReg] = true;
+  for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
+    toSpill[*as] = true;
+  unsigned earliestStart = cur->start();
+
+  std::set<unsigned> spilled;
+
+  for (IntervalPtrs::iterator i = active_.begin(); i != active_.end(); ) {
+    unsigned reg = (*i)->reg;
+    if (MRegisterInfo::isVirtualRegister(reg) &&
+        toSpill[vrm_->getPhys(reg)] &&
+        cur->overlaps(**i)) {
+      DEBUG(std::cerr << "\t\t\tspilling(a): " << **i << '\n');
+      spilled_.push_back(*i);
+      prt_->delRegUse(vrm_->getPhys(reg));
+      vrm_->clearVirt(reg);
+      i = active_.erase(i);
+    }
+    else
+      ++i;
+  }
+  for (IntervalPtrs::iterator i = inactive_.begin(); i != inactive_.end(); ) {
+    unsigned reg = (*i)->reg;
+    if (MRegisterInfo::isVirtualRegister(reg) &&
+        toSpill[vrm_->getPhys(reg)] &&
+        cur->overlaps(**i)) {
+      DEBUG(std::cerr << "\t\t\tspilling(i): " << **i << '\n');
+      spilled_.push_back(*i);
+      vrm_->clearVirt(reg);
+      i = inactive_.erase(i);
+    }
+    else
+      ++i;
+  }
+
+  vrm_->assignVirt2Phys(cur->reg, minReg);
+  prt_->addRegUse(minReg);
+  active_.push_back(cur);
+  handled_.push_back(cur);
 
 }
 
 unsigned RA::getFreePhysReg(IntervalPtrs::value_type cur)
 {
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
+  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 (prt_->isRegAvail(reg))
-            return reg;
-    }
-    return 0;
+  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
+       i != rc->allocation_order_end(*mf_); ++i) {
+    unsigned reg = *i;
+    if (prt_->isRegAvail(reg))
+      return reg;
+  }
+  return 0;
 }
 
 FunctionPass* llvm::createIterativeScanRegisterAllocator() {
-    return new RA();
+  return new RA();
 }
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 4c44d92..6858744 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -35,502 +35,502 @@
 
 namespace {
 
-    Statistic<double> efficiency
-    ("regalloc", "Ratio of intervals processed over total intervals");
+  Statistic<double> efficiency
+  ("regalloc", "Ratio of intervals processed over total intervals");
 
-    static unsigned numIterations = 0;
-    static unsigned numIntervals = 0;
+  static unsigned numIterations = 0;
+  static unsigned numIntervals = 0;
 
-    class RA : public MachineFunctionPass {
-    private:
-        MachineFunction* mf_;
-        const TargetMachine* tm_;
-        const MRegisterInfo* mri_;
-        LiveIntervals* li_;
-        typedef std::vector<LiveInterval*> IntervalPtrs;
-        IntervalPtrs handled_, fixed_, active_, inactive_;
-        typedef std::priority_queue<LiveInterval*,
-                                    IntervalPtrs,
-                                    greater_ptr<LiveInterval> > IntervalHeap;
-        IntervalHeap unhandled_;
-        std::auto_ptr<PhysRegTracker> prt_;
-        std::auto_ptr<VirtRegMap> vrm_;
-        std::auto_ptr<Spiller> spiller_;
+  class RA : public MachineFunctionPass {
+  private:
+    MachineFunction* mf_;
+    const TargetMachine* tm_;
+    const MRegisterInfo* mri_;
+    LiveIntervals* li_;
+    typedef std::vector<LiveInterval*> IntervalPtrs;
+    IntervalPtrs handled_, fixed_, active_, inactive_;
+    typedef std::priority_queue<LiveInterval*,
+                                IntervalPtrs,
+                                greater_ptr<LiveInterval> > IntervalHeap;
+    IntervalHeap unhandled_;
+    std::auto_ptr<PhysRegTracker> prt_;
+    std::auto_ptr<VirtRegMap> vrm_;
+    std::auto_ptr<Spiller> spiller_;
 
-        typedef std::vector<float> SpillWeights;
-        SpillWeights spillWeights_;
+    typedef std::vector<float> SpillWeights;
+    SpillWeights spillWeights_;
 
-    public:
-        virtual const char* getPassName() const {
-            return "Linear Scan Register Allocator";
+  public:
+    virtual const char* getPassName() const {
+      return "Linear Scan Register Allocator";
+    }
+
+    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.addRequired<LiveVariables>();
+      AU.addRequired<LiveIntervals>();
+      MachineFunctionPass::getAnalysisUsage(AU);
+    }
+
+    /// 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();
+
+    /// processActiveIntervals - expire old intervals and move
+    /// non-overlapping ones to the incative list
+    void processActiveIntervals(LiveInterval* cur);
+
+    /// processInactiveIntervals - expire old intervals and move
+    /// overlapping ones to the active list
+    void processInactiveIntervals(LiveInterval* 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(LiveInterval* cur);
+
+    ///
+    /// register handling helpers
+    ///
+
+    /// getFreePhysReg - return a free physical register for this
+    /// virtual register interval if we have one, otherwise return
+    /// 0
+    unsigned getFreePhysReg(LiveInterval* cur);
+
+    /// assignVirt2StackSlot - assigns this virtual register to a
+    /// stack slot. returns the stack slot
+    int assignVirt2StackSlot(unsigned virtReg);
+
+    template <typename ItTy>
+    void printIntervals(const char* const str, ItTy i, ItTy e) const {
+      if (str) std::cerr << str << " intervals:\n";
+      for (; i != e; ++i) {
+        std::cerr << "\t" << **i << " -> ";
+        unsigned reg = (*i)->reg;
+        if (MRegisterInfo::isVirtualRegister(reg)) {
+          reg = vrm_->getPhys(reg);
         }
-
-        virtual void getAnalysisUsage(AnalysisUsage &AU) const {
-            AU.addRequired<LiveVariables>();
-            AU.addRequired<LiveIntervals>();
-            MachineFunctionPass::getAnalysisUsage(AU);
-        }
-
-        /// 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();
-
-        /// processActiveIntervals - expire old intervals and move
-        /// non-overlapping ones to the incative list
-        void processActiveIntervals(LiveInterval* cur);
-
-        /// processInactiveIntervals - expire old intervals and move
-        /// overlapping ones to the active list
-        void processInactiveIntervals(LiveInterval* 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(LiveInterval* cur);
-
-        ///
-        /// register handling helpers
-        ///
-
-        /// getFreePhysReg - return a free physical register for this
-        /// virtual register interval if we have one, otherwise return
-        /// 0
-        unsigned getFreePhysReg(LiveInterval* cur);
-
-        /// assignVirt2StackSlot - assigns this virtual register to a
-        /// stack slot. returns the stack slot
-        int assignVirt2StackSlot(unsigned virtReg);
-
-        template <typename ItTy>
-        void printIntervals(const char* const str, ItTy i, ItTy e) const {
-            if (str) std::cerr << str << " intervals:\n";
-            for (; i != e; ++i) {
-                std::cerr << "\t" << **i << " -> ";
-                unsigned reg = (*i)->reg;
-                if (MRegisterInfo::isVirtualRegister(reg)) {
-                    reg = vrm_->getPhys(reg);
-                }
-                std::cerr << mri_->getName(reg) << '\n';
-            }
-        }
-    };
+        std::cerr << mri_->getName(reg) << '\n';
+      }
+    }
+  };
 }
 
 void RA::releaseMemory()
 {
-    while (!unhandled_.empty()) unhandled_.pop();
-    fixed_.clear();
-    active_.clear();
-    inactive_.clear();
-    handled_.clear();
+  while (!unhandled_.empty()) unhandled_.pop();
+  fixed_.clear();
+  active_.clear();
+  inactive_.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());
+  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();
+  initIntervalSets();
 
-    linearScan();
+  linearScan();
 
-    spiller_->runOnMachineFunction(*mf_, *vrm_);
+  spiller_->runOnMachineFunction(*mf_, *vrm_);
 
-    return true;
+  return true;
 }
 
 void RA::linearScan()
 {
-    // linear scan algorithm
-    DEBUG(std::cerr << "********** LINEAR SCAN **********\n");
-    DEBUG(std::cerr << "********** Function: "
-          << mf_->getFunction()->getName() << '\n');
+  // 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("unhandled", unhandled_.begin(), unhandled_.end()));
+  DEBUG(printIntervals("fixed", fixed_.begin(), fixed_.end()));
+  DEBUG(printIntervals("active", active_.begin(), active_.end()));
+  DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
+
+  while (!unhandled_.empty()) {
+    // pick the interval with the earliest start point
+    LiveInterval* cur = unhandled_.top();
+    unhandled_.pop();
+    ++numIterations;
+    DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
+
+    processActiveIntervals(cur);
+    processInactiveIntervals(cur);
+
+    // if this register is fixed we are done
+    if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
+      prt_->addRegUse(cur->reg);
+      active_.push_back(cur);
+      handled_.push_back(cur);
+    }
+    // otherwise we are allocating a virtual register. try to find
+    // a free physical register or spill an interval in order to
+    // assign it one (we could spill the current though).
+    else {
+      assignRegOrStackSlotAtInterval(cur);
+    }
+
     DEBUG(printIntervals("active", active_.begin(), active_.end()));
     DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
+  }
+  numIntervals += li_->getNumIntervals();
+  efficiency = double(numIterations) / double(numIntervals);
 
-    while (!unhandled_.empty()) {
-        // pick the interval with the earliest start point
-        LiveInterval* cur = unhandled_.top();
-        unhandled_.pop();
-        ++numIterations;
-        DEBUG(std::cerr << "\n*** CURRENT ***: " << *cur << '\n');
+  // expire any remaining active intervals
+  for (IntervalPtrs::reverse_iterator
+         i = active_.rbegin(); i != active_.rend(); ) {
+    unsigned reg = (*i)->reg;
+    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
+    if (MRegisterInfo::isVirtualRegister(reg))
+      reg = vrm_->getPhys(reg);
+    prt_->delRegUse(reg);
+    i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
+  }
 
-        processActiveIntervals(cur);
-        processInactiveIntervals(cur);
+  // expire any remaining inactive intervals
+  for (IntervalPtrs::reverse_iterator
+         i = inactive_.rbegin(); i != inactive_.rend(); ) {
+    DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
+    i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
+  }
 
-        // if this register is fixed we are done
-        if (MRegisterInfo::isPhysicalRegister(cur->reg)) {
-            prt_->addRegUse(cur->reg);
-            active_.push_back(cur);
-            handled_.push_back(cur);
-        }
-        // otherwise we are allocating a virtual register. try to find
-        // a free physical register or spill an interval in order to
-        // assign it one (we could spill the current though).
-        else {
-            assignRegOrStackSlotAtInterval(cur);
-        }
-
-        DEBUG(printIntervals("active", active_.begin(), active_.end()));
-        DEBUG(printIntervals("inactive", inactive_.begin(), inactive_.end()));
-    }
-    numIntervals += li_->getNumIntervals();
-    efficiency = double(numIterations) / double(numIntervals);
-
-    // expire any remaining active intervals
-    for (IntervalPtrs::reverse_iterator
-             i = active_.rbegin(); i != active_.rend(); ) {
-        unsigned reg = (*i)->reg;
-        DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
-        if (MRegisterInfo::isVirtualRegister(reg))
-            reg = vrm_->getPhys(reg);
-        prt_->delRegUse(reg);
-        i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-    }
-
-    // expire any remaining inactive intervals
-    for (IntervalPtrs::reverse_iterator
-             i = inactive_.rbegin(); i != inactive_.rend(); ) {
-        DEBUG(std::cerr << "\tinterval " << **i << " expired\n");
-        i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-    }
-
-    DEBUG(std::cerr << *vrm_);
+  DEBUG(std::cerr << *vrm_);
 }
 
 void RA::initIntervalSets()
 {
-    assert(unhandled_.empty() && fixed_.empty() &&
-           active_.empty() && inactive_.empty() &&
-           "interval sets should be empty on initialization");
+  assert(unhandled_.empty() && fixed_.empty() &&
+         active_.empty() && inactive_.empty() &&
+         "interval sets should be empty on initialization");
 
-    for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
-        unhandled_.push(&i->second);
-        if (MRegisterInfo::isPhysicalRegister(i->second.reg))
-            fixed_.push_back(&i->second);
-    }
+  for (LiveIntervals::iterator i = li_->begin(), e = li_->end(); i != e; ++i){
+    unhandled_.push(&i->second);
+    if (MRegisterInfo::isPhysicalRegister(i->second.reg))
+      fixed_.push_back(&i->second);
+  }
 }
 
 void RA::processActiveIntervals(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\tprocessing active intervals:\n");
-    for (IntervalPtrs::reverse_iterator
-             i = active_.rbegin(); i != active_.rend();) {
-        unsigned reg = (*i)->reg;
-        // remove expired intervals
-        if ((*i)->expiredAt(cur->start())) {
-            DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-            if (MRegisterInfo::isVirtualRegister(reg))
-                reg = vrm_->getPhys(reg);
-            prt_->delRegUse(reg);
-            // remove from active
-            i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-        }
-        // move inactive intervals to inactive list
-        else if (!(*i)->liveAt(cur->start())) {
-            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
-            i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
-        }
-        else {
-            ++i;
-        }
+  DEBUG(std::cerr << "\tprocessing active intervals:\n");
+  for (IntervalPtrs::reverse_iterator
+         i = active_.rbegin(); i != active_.rend();) {
+    unsigned reg = (*i)->reg;
+    // remove expired intervals
+    if ((*i)->expiredAt(cur->start())) {
+      DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
+      if (MRegisterInfo::isVirtualRegister(reg))
+        reg = vrm_->getPhys(reg);
+      prt_->delRegUse(reg);
+      // remove from active
+      i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
     }
+    // move inactive intervals to inactive list
+    else if (!(*i)->liveAt(cur->start())) {
+      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
+      i = IntervalPtrs::reverse_iterator(active_.erase(i.base()-1));
+    }
+    else {
+      ++i;
+    }
+  }
 }
 
 void RA::processInactiveIntervals(IntervalPtrs::value_type cur)
 {
-    DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
-    for (IntervalPtrs::reverse_iterator
-             i = inactive_.rbegin(); i != inactive_.rend();) {
-        unsigned reg = (*i)->reg;
+  DEBUG(std::cerr << "\tprocessing inactive intervals:\n");
+  for (IntervalPtrs::reverse_iterator
+         i = inactive_.rbegin(); i != inactive_.rend();) {
+    unsigned reg = (*i)->reg;
 
-        // remove expired intervals
-        if ((*i)->expiredAt(cur->start())) {
-            DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
-            // remove from inactive
-            i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-        }
-        // move re-activated intervals in active list
-        else if ((*i)->liveAt(cur->start())) {
-            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
-            i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
-        }
-        else {
-            ++i;
-        }
+    // remove expired intervals
+    if ((*i)->expiredAt(cur->start())) {
+      DEBUG(std::cerr << "\t\tinterval " << **i << " expired\n");
+      // remove from inactive
+      i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
     }
+    // move re-activated intervals in active list
+    else if ((*i)->liveAt(cur->start())) {
+      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
+      i = IntervalPtrs::reverse_iterator(inactive_.erase(i.base()-1));
+    }
+    else {
+      ++i;
+    }
+  }
 }
 
 void RA::updateSpillWeights(unsigned reg, SpillWeights::value_type weight)
 {
-    spillWeights_[reg] += weight;
-    for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
-        spillWeights_[*as] += weight;
+  spillWeights_[reg] += weight;
+  for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
+    spillWeights_[*as] += weight;
 }
 
 void RA::assignRegOrStackSlotAtInterval(LiveInterval* cur)
 {
-    DEBUG(std::cerr << "\tallocating current interval: ");
+  DEBUG(std::cerr << "\tallocating current interval: ");
 
-    PhysRegTracker backupPrt = *prt_;
+  PhysRegTracker backupPrt = *prt_;
 
-    spillWeights_.assign(mri_->getNumRegs(), 0.0);
+  spillWeights_.assign(mri_->getNumRegs(), 0.0);
 
-    // for each interval in active update spill weights
-    for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
-         i != e; ++i) {
-        unsigned reg = (*i)->reg;
-        if (MRegisterInfo::isVirtualRegister(reg))
-            reg = vrm_->getPhys(reg);
-        updateSpillWeights(reg, (*i)->weight);
+  // for each interval in active update spill weights
+  for (IntervalPtrs::const_iterator i = active_.begin(), e = active_.end();
+       i != e; ++i) {
+    unsigned reg = (*i)->reg;
+    if (MRegisterInfo::isVirtualRegister(reg))
+      reg = vrm_->getPhys(reg);
+    updateSpillWeights(reg, (*i)->weight);
+  }
+
+  // for every interval in inactive we overlap with, mark the
+  // register as not free and update spill weights
+  for (IntervalPtrs::const_iterator i = inactive_.begin(),
+         e = inactive_.end(); i != e; ++i) {
+    if (cur->overlaps(**i)) {
+      unsigned reg = (*i)->reg;
+      if (MRegisterInfo::isVirtualRegister(reg))
+        reg = vrm_->getPhys(reg);
+      prt_->addRegUse(reg);
+      updateSpillWeights(reg, (*i)->weight);
     }
+  }
 
-    // for every interval in inactive we overlap with, mark the
-    // register as not free and update spill weights
-    for (IntervalPtrs::const_iterator i = inactive_.begin(),
-             e = inactive_.end(); i != e; ++i) {
-        if (cur->overlaps(**i)) {
-            unsigned reg = (*i)->reg;
-            if (MRegisterInfo::isVirtualRegister(reg))
-                reg = vrm_->getPhys(reg);
-            prt_->addRegUse(reg);
-            updateSpillWeights(reg, (*i)->weight);
-        }
+  // for every interval in fixed we overlap with,
+  // mark the register as not free and update spill weights
+  for (IntervalPtrs::const_iterator i = fixed_.begin(),
+         e = fixed_.end(); i != e; ++i) {
+    if (cur->overlaps(**i)) {
+      unsigned reg = (*i)->reg;
+      prt_->addRegUse(reg);
+      updateSpillWeights(reg, (*i)->weight);
     }
+  }
 
-    // for every interval in fixed we overlap with,
-    // mark the register as not free and update spill weights
-    for (IntervalPtrs::const_iterator i = fixed_.begin(),
-             e = fixed_.end(); i != e; ++i) {
-        if (cur->overlaps(**i)) {
-            unsigned reg = (*i)->reg;
-            prt_->addRegUse(reg);
-            updateSpillWeights(reg, (*i)->weight);
-        }
+  unsigned physReg = getFreePhysReg(cur);
+  // restore the physical register tracker
+  *prt_ = backupPrt;
+  // if we find a free register, we are done: assign this virtual to
+  // the free physical register and add this interval to the active
+  // list.
+  if (physReg) {
+    DEBUG(std::cerr <<  mri_->getName(physReg) << '\n');
+    vrm_->assignVirt2Phys(cur->reg, physReg);
+    prt_->addRegUse(physReg);
+    active_.push_back(cur);
+    handled_.push_back(cur);
+    return;
+  }
+  DEBUG(std::cerr << "no free registers\n");
+
+  DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
+
+  float minWeight = HUGE_VAL;
+  unsigned minReg = 0;
+  const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
+  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
+       i != rc->allocation_order_end(*mf_); ++i) {
+    unsigned reg = *i;
+    if (minWeight > spillWeights_[reg]) {
+      minWeight = spillWeights_[reg];
+      minReg = reg;
     }
+  }
+  DEBUG(std::cerr << "\t\tregister with min weight: "
+        << mri_->getName(minReg) << " (" << minWeight << ")\n");
 
-    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");
+  // if the current has the minimum weight, we need to spill it and
+  // add any added intervals back to unhandled, and restart
+  // linearscan.
+  if (cur->weight <= minWeight) {
+    DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
+    int slot = vrm_->assignVirt2StackSlot(cur->reg);
+    std::vector<LiveInterval*> added =
+      li_->addIntervalsForSpills(*cur, *vrm_, slot);
+    if (added.empty())
+      return;  // Early exit if all spills were folded.
 
-    DEBUG(std::cerr << "\tassigning stack slot at interval "<< *cur << ":\n");
-
-    float minWeight = HUGE_VAL;
-    unsigned minReg = 0;
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
-    for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
-         i != rc->allocation_order_end(*mf_); ++i) {
-        unsigned reg = *i;
-        if (minWeight > spillWeights_[reg]) {
-            minWeight = spillWeights_[reg];
-            minReg = reg;
-        }
-    }
-    DEBUG(std::cerr << "\t\tregister with min weight: "
-          << mri_->getName(minReg) << " (" << minWeight << ")\n");
-
-    // if the current has the minimum weight, we need to spill it and
-    // add any added intervals back to unhandled, and restart
-    // linearscan.
-    if (cur->weight <= minWeight) {
-        DEBUG(std::cerr << "\t\t\tspilling(c): " << *cur << '\n';);
-        int slot = vrm_->assignVirt2StackSlot(cur->reg);
-        std::vector<LiveInterval*> added =
-            li_->addIntervalsForSpills(*cur, *vrm_, slot);
-        if (added.empty())
-          return;  // Early exit if all spills were folded.
-
-        // Merge added with unhandled.  Note that we know that 
-        // addIntervalsForSpills returns intervals sorted by their starting
-        // point.
-        for (unsigned i = 0, e = added.size(); i != e; ++i)
-            unhandled_.push(added[i]);
-        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(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
-    std::vector<LiveInterval*> added;
-    assert(MRegisterInfo::isPhysicalRegister(minReg) &&
-           "did not choose a register to spill?");
-    std::vector<bool> toSpill(mri_->getNumRegs(), false);
-    // we are going to spill minReg and all its aliases
-    toSpill[minReg] = true;
-    for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
-        toSpill[*as] = true;
-
-    // the earliest start of a spilled interval indicates up to where
-    // in handled we need to roll back
-    unsigned earliestStart = cur->start();
-
-    // set of spilled vregs (used later to rollback properly)
-    std::set<unsigned> spilled;
-
-    // spill live intervals of virtual regs mapped to the physical
-    // register we want to clear (and its aliases). we only spill
-    // those that overlap with the current interval as the rest do not
-    // affect its allocation. we also keep track of the earliest start
-    // of all spilled live intervals since this will mark our rollback
-    // point
-    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);
-            std::vector<LiveInterval*> newIs =
-                li_->addIntervalsForSpills(**i, *vrm_, slot);
-            std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
-            spilled.insert(reg);
-        }
-    }
-    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);
-            std::vector<LiveInterval*> newIs =
-                li_->addIntervalsForSpills(**i, *vrm_, slot);
-            std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
-            spilled.insert(reg);
-        }
-    }
-
-    DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
-    // scan handled in reverse order up to the earliaset start of a
-    // spilled live interval and undo each one, restoring the state of
-    // unhandled
-    while (!handled_.empty()) {
-        LiveInterval* i = handled_.back();
-        // if this interval starts before t we are done
-        if (i->start() < earliestStart)
-            break;
-        DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
-        handled_.pop_back();
-        // when undoing a live interval allocation we must know if it
-        // is active or inactive to properly update the PhysRegTracker
-        // and the VirtRegMap
-        IntervalPtrs::iterator it;
-        if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) {
-            active_.erase(it);
-            if (MRegisterInfo::isPhysicalRegister(i->reg)) {
-                prt_->delRegUse(i->reg);
-                unhandled_.push(i);
-            }
-            else {
-                if (!spilled.count(i->reg))
-                    unhandled_.push(i);
-                prt_->delRegUse(vrm_->getPhys(i->reg));
-                vrm_->clearVirt(i->reg);
-            }
-        }
-        else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
-            inactive_.erase(it);
-            if (MRegisterInfo::isPhysicalRegister(i->reg))
-                unhandled_.push(i);
-            else {
-                if (!spilled.count(i->reg))
-                    unhandled_.push(i);
-                vrm_->clearVirt(i->reg);
-            }
-        }
-        else {
-            if (MRegisterInfo::isVirtualRegister(i->reg))
-                vrm_->clearVirt(i->reg);
-            unhandled_.push(i);
-        }
-    }
-
-    // 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));
-        }
-    }
-
-    std::sort(added.begin(), added.end(), less_ptr<LiveInterval>());
-    // merge added with unhandled
+    // Merge added with unhandled.  Note that we know that
+    // addIntervalsForSpills returns intervals sorted by their starting
+    // point.
     for (unsigned i = 0, e = added.size(); i != e; ++i)
-        unhandled_.push(added[i]);
+      unhandled_.push(added[i]);
+    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(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
+  std::vector<LiveInterval*> added;
+  assert(MRegisterInfo::isPhysicalRegister(minReg) &&
+         "did not choose a register to spill?");
+  std::vector<bool> toSpill(mri_->getNumRegs(), false);
+  // we are going to spill minReg and all its aliases
+  toSpill[minReg] = true;
+  for (const unsigned* as = mri_->getAliasSet(minReg); *as; ++as)
+    toSpill[*as] = true;
+
+  // the earliest start of a spilled interval indicates up to where
+  // in handled we need to roll back
+  unsigned earliestStart = cur->start();
+
+  // set of spilled vregs (used later to rollback properly)
+  std::set<unsigned> spilled;
+
+  // spill live intervals of virtual regs mapped to the physical
+  // register we want to clear (and its aliases). we only spill
+  // those that overlap with the current interval as the rest do not
+  // affect its allocation. we also keep track of the earliest start
+  // of all spilled live intervals since this will mark our rollback
+  // point
+  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);
+      std::vector<LiveInterval*> newIs =
+        li_->addIntervalsForSpills(**i, *vrm_, slot);
+      std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+      spilled.insert(reg);
+    }
+  }
+  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);
+      std::vector<LiveInterval*> newIs =
+        li_->addIntervalsForSpills(**i, *vrm_, slot);
+      std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
+      spilled.insert(reg);
+    }
+  }
+
+  DEBUG(std::cerr << "\t\trolling back to: " << earliestStart << '\n');
+  // scan handled in reverse order up to the earliaset start of a
+  // spilled live interval and undo each one, restoring the state of
+  // unhandled
+  while (!handled_.empty()) {
+    LiveInterval* i = handled_.back();
+    // if this interval starts before t we are done
+    if (i->start() < earliestStart)
+      break;
+    DEBUG(std::cerr << "\t\t\tundo changes for: " << *i << '\n');
+    handled_.pop_back();
+    // when undoing a live interval allocation we must know if it
+    // is active or inactive to properly update the PhysRegTracker
+    // and the VirtRegMap
+    IntervalPtrs::iterator it;
+    if ((it = find(active_.begin(), active_.end(), i)) != active_.end()) {
+      active_.erase(it);
+      if (MRegisterInfo::isPhysicalRegister(i->reg)) {
+        prt_->delRegUse(i->reg);
+        unhandled_.push(i);
+      }
+      else {
+        if (!spilled.count(i->reg))
+          unhandled_.push(i);
+        prt_->delRegUse(vrm_->getPhys(i->reg));
+        vrm_->clearVirt(i->reg);
+      }
+    }
+    else if ((it = find(inactive_.begin(), inactive_.end(), i)) != inactive_.end()) {
+      inactive_.erase(it);
+      if (MRegisterInfo::isPhysicalRegister(i->reg))
+        unhandled_.push(i);
+      else {
+        if (!spilled.count(i->reg))
+          unhandled_.push(i);
+        vrm_->clearVirt(i->reg);
+      }
+    }
+    else {
+      if (MRegisterInfo::isVirtualRegister(i->reg))
+        vrm_->clearVirt(i->reg);
+      unhandled_.push(i);
+    }
+  }
+
+  // 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));
+    }
+  }
+
+  std::sort(added.begin(), added.end(), less_ptr<LiveInterval>());
+  // merge added with unhandled
+  for (unsigned i = 0, e = added.size(); i != e; ++i)
+    unhandled_.push(added[i]);
 }
 
 unsigned RA::getFreePhysReg(LiveInterval* cur)
 {
-    const TargetRegisterClass* rc = mf_->getSSARegMap()->getRegClass(cur->reg);
+  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 (prt_->isRegAvail(reg))
-            return reg;
-    }
-    return 0;
+  for (TargetRegisterClass::iterator i = rc->allocation_order_begin(*mf_);
+       i != rc->allocation_order_end(*mf_); ++i) {
+    unsigned reg = *i;
+    if (prt_->isRegAvail(reg))
+      return reg;
+  }
+  return 0;
 }
 
 FunctionPass* llvm::createLinearScanRegisterAllocator() {
-    return new RA();
+  return new RA();
 }
