DwarfWriter reading basic type information from llvm-gcc4 code.
[oota-llvm.git] / lib / CodeGen / LiveIntervalAnalysis.cpp
index 95ed508fcb3e68e4dcee22ad0eccd7026f333259..125a18dd24ec7d44a18a86b1ca8f4deec612a4ae 100644 (file)
@@ -16,7 +16,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "liveintervals"
-#include "LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "VirtRegMap.h"
 #include "llvm/Value.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/CodeGen/LiveVariables.h"
@@ -31,9 +32,9 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/STLExtras.h"
-#include "VirtRegMap.h"
+#include <algorithm>
 #include <cmath>
-
+#include <iostream>
 using namespace llvm;
 
 namespace {
@@ -62,7 +63,6 @@ namespace {
 
 void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const
 {
-  AU.addPreserved<LiveVariables>();
   AU.addRequired<LiveVariables>();
   AU.addPreservedID(PHIEliminationID);
   AU.addRequiredID(PHIEliminationID);
@@ -86,8 +86,32 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   mf_ = &fn;
   tm_ = &fn.getTarget();
   mri_ = tm_->getRegisterInfo();
+  tii_ = tm_->getInstrInfo();
   lv_ = &getAnalysis<LiveVariables>();
   allocatableRegs_ = mri_->getAllocatableSet(fn);
+  r2rMap_.grow(mf_->getSSARegMap()->getLastVirtReg());
+
+  // If this function has any live ins, insert a dummy instruction at the
+  // beginning of the function that we will pretend "defines" the values.  This
+  // is to make the interval analysis simpler by providing a number.
+  if (fn.livein_begin() != fn.livein_end()) {
+    unsigned FirstLiveIn = fn.livein_begin()->first;
+
+    // Find a reg class that contains this live in.
+    const TargetRegisterClass *RC = 0;
+    for (MRegisterInfo::regclass_iterator RCI = mri_->regclass_begin(),
+           E = mri_->regclass_end(); RCI != E; ++RCI)
+      if ((*RCI)->contains(FirstLiveIn)) {
+        RC = *RCI;
+        break;
+      }
+
+    MachineInstr *OldFirstMI = fn.begin()->begin();
+    mri_->copyRegToReg(*fn.begin(), fn.begin()->begin(),
+                       FirstLiveIn, FirstLiveIn, RC);
+    assert(OldFirstMI != fn.begin()->begin() &&
+           "copyRetToReg didn't insert anything!");
+  }
 
   // number MachineInstrs
   unsigned miIndex = 0;
@@ -101,15 +125,28 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
       miIndex += InstrSlots::NUM;
     }
 
+  // Note intervals due to live-in values.
+  if (fn.livein_begin() != fn.livein_end()) {
+    MachineBasicBlock *Entry = fn.begin();
+    for (MachineFunction::livein_iterator I = fn.livein_begin(),
+           E = fn.livein_end(); I != E; ++I) {
+      handlePhysicalRegisterDef(Entry, Entry->begin(),
+                                getOrCreateInterval(I->first), 0, 0, true);
+      for (const unsigned* AS = mri_->getAliasSet(I->first); *AS; ++AS)
+        handlePhysicalRegisterDef(Entry, Entry->begin(),
+                                  getOrCreateInterval(*AS), 0, 0, true);
+    }
+  }
+
   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
+  DEBUG(std::cerr << "********** INTERVALS **********\n";
+        for (iterator I = begin(), E = end(); I != E; ++I) {
+          I->second.print(std::cerr, mri_);
+          std::cerr << "\n";
+        });
 
   // join intervals if requested
   if (EnableJoining) joinIntervals();
@@ -119,7 +156,6 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   // 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) {
@@ -130,7 +166,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
          mii != mie; ) {
       // if the move will be an identity move delete it
       unsigned srcReg, dstReg, RegRep;
-      if (tii.isMoveInstr(*mii, srcReg, dstReg) &&
+      if (tii_->isMoveInstr(*mii, srcReg, dstReg) &&
           (RegRep = rep(srcReg)) == rep(dstReg)) {
         // remove from def list
         LiveInterval &interval = getOrCreateInterval(RegRep);
@@ -155,7 +191,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
 
             LiveInterval &RegInt = getInterval(reg);
             RegInt.weight +=
-              (mop.isUse() + mop.isDef()) * pow(10.0F, loopDepth);
+              (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
           }
         }
         ++mii;
@@ -163,29 +199,31 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
     }
   }
 
-  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_);
-      }
-    });
-
+  DEBUG(dump());
   return true;
 }
 
-std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
-  const LiveInterval& li,
-  VirtRegMap& vrm,
-  int slot)
-{
+/// print - Implement the dump method.
+void LiveIntervals::print(std::ostream &O, const Module* ) const {
+  O << "********** INTERVALS **********\n";
+  for (const_iterator I = begin(), E = end(); I != E; ++I) {
+    I->second.print(std::cerr, mri_);
+    std::cerr << "\n";
+  }
+
+  O << "********** MACHINEINSTRS **********\n";
+  for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
+       mbbi != mbbe; ++mbbi) {
+    O << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
+    for (MachineBasicBlock::iterator mii = mbbi->begin(),
+           mie = mbbi->end(); mii != mie; ++mii) {
+      O << getInstructionIndex(mii) << '\t' << *mii;
+    }
+  }
+}
+
+std::vector<LiveInterval*> LiveIntervals::
+addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
   // since this is called after the analysis is done we don't know if
   // LiveVariables is available
   lv_ = getAnalysisToUpdate<LiveVariables>();
@@ -210,60 +248,81 @@ std::vector<LiveInterval*> LiveIntervals::addIntervalsForSpills(
         index += InstrSlots::NUM;
       if (index == end) break;
 
-      MachineBasicBlock::iterator mi = getInstructionFromIndex(index);
+      MachineInstr *MI = getInstructionFromIndex(index);
+
+      // NewRegLiveIn - This instruction might have multiple uses of the spilled
+      // register.  In this case, for the first use, keep track of the new vreg
+      // that we reload it into.  If we see a second use, reuse this vreg
+      // instead of creating live ranges for two reloads.
+      unsigned NewRegLiveIn = 0;
 
     for_operand:
-      for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
-        MachineOperand& mop = mi->getOperand(i);
+      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)) {
+          if (NewRegLiveIn && mop.isUse()) {
+            // We already emitted a reload of this value, reuse it for
+            // subsequent operands.
+            MI->SetMachineOperandReg(i, NewRegLiveIn);
+            DEBUG(std::cerr << "\t\t\t\treused reload into reg" << NewRegLiveIn
+                            << " for operand #" << i << '\n');
+          } else if (MachineInstr* fmi = mri_->foldMemoryOperand(MI, i, slot)) {
+            // Attempt to fold the memory reference into the instruction.  If we
+            // can do this, we don't need to insert spill code.
             if (lv_)
-              lv_->instructionChanged(mi, fmi);
-            vrm.virtFolded(li.reg, mi, fmi);
-            mi2iMap_.erase(mi);
+              lv_->instructionChanged(MI, fmi);
+            vrm.virtFolded(li.reg, MI, i, fmi);
+            mi2iMap_.erase(MI);
             i2miMap_[index/InstrSlots::NUM] = fmi;
             mi2iMap_[fmi] = index;
-            MachineBasicBlock& mbb = *mi->getParent();
-            mi = mbb.insert(mbb.erase(mi), fmi);
+            MachineBasicBlock &MBB = *MI->getParent();
+            MI = MBB.insert(MBB.erase(MI), fmi);
             ++numFolded;
+
+            // Folding the load/store can completely change the instruction in
+            // unpredictable ways, rescan it from the beginning.
             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.
+          } 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.
+            // 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.
+            // 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);
+            NewRegLiveIn = mf_->getSSARegMap()->createVirtualRegister(rc);
+            MI->SetMachineOperandReg(i, NewRegLiveIn);
             vrm.grow();
-            vrm.assignVirt2StackSlot(nReg, slot);
-            LiveInterval& nI = getOrCreateInterval(nReg);
+            vrm.assignVirt2StackSlot(NewRegLiveIn, slot);
+            LiveInterval& nI = getOrCreateInterval(NewRegLiveIn);
             assert(nI.empty());
+
             // the spill weight is now infinity as it
             // cannot be spilled again
-            nI.weight = HUGE_VAL;
+            nI.weight = float(HUGE_VAL);
             LiveRange LR(start, end, nI.getNextValue());
             DEBUG(std::cerr << " +" << LR);
             nI.addRange(LR);
             added.push_back(&nI);
+
             // update live variables if it is available
             if (lv_)
-              lv_->addVirtualRegisterKilled(nReg, mi);
+              lv_->addVirtualRegisterKilled(NewRegLiveIn, MI);
+            
+            // If this is a live in, reuse it for subsequent live-ins.  If it's
+            // a def, we can't do this.
+            if (!mop.isUse()) NewRegLiveIn = 0;
+            
             DEBUG(std::cerr << "\t\t\t\tadded new interval: " << nI << '\n');
           }
         }
@@ -388,12 +447,8 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
 
       // 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;
-        }
+      if (lv_->RegisterDefIsDead(mi, interval.reg))
+        interval.addRange(LiveRange(RedefIndex, RedefIndex+1, 0));
 
       DEBUG(std::cerr << "RESULT: " << interval);
 
@@ -438,7 +493,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
 
 void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
                                               MachineBasicBlock::iterator mi,
-                                              LiveInterval& interval)
+                                              LiveInterval& interval,
+                                              unsigned SrcReg, unsigned DestReg,
+                                              bool isLiveIn)
 {
   // A physical register cannot be live across basic block, so its
   // lifetime must end somewhere in its defining basic block.
@@ -452,34 +509,71 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
   // 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 (lv_->RegisterDefIsDead(mi, interval.reg)) {
+    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!");
+  while (++mi != MBB->end()) {
     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;
-      }
+    if (lv_->KillsRegister(mi, interval.reg)) {
+      DEBUG(std::cerr << " killed");
+      end = getUseIndex(baseIndex) + 1;
+      goto exit;
     }
   }
+  
+  // The only case we should have a dead physreg here without a killing or
+  // instruction where we know it's dead is if it is live-in to the function
+  // and never used.
+  assert(isLiveIn && "physreg was not killed in defining block!");
+  end = getDefIndex(start) + 1;  // It's dead.
 
 exit:
   assert(start < end && "did not find end of interval?");
+
+  // Finally, if this is defining a new range for the physical register, and if
+  // that physreg is just a copy from a vreg, and if THAT vreg was a copy from
+  // the physreg, then the new fragment has the same value as the one copied
+  // into the vreg.
+  if (interval.reg == DestReg && !interval.empty() &&
+      MRegisterInfo::isVirtualRegister(SrcReg)) {
+
+    // Get the live interval for the vreg, see if it is defined by a copy.
+    LiveInterval &SrcInterval = getOrCreateInterval(SrcReg);
+
+    if (SrcInterval.containsOneValue()) {
+      assert(!SrcInterval.empty() && "Can't contain a value and be empty!");
+
+      // Get the first index of the first range.  Though the interval may have
+      // multiple liveranges in it, we only check the first.
+      unsigned StartIdx = SrcInterval.begin()->start;
+      MachineInstr *SrcDefMI = getInstructionFromIndex(StartIdx);
+
+      // Check to see if the vreg was defined by a copy instruction, and that
+      // the source was this physreg.
+      unsigned VRegSrcSrc, VRegSrcDest;
+      if (tii_->isMoveInstr(*SrcDefMI, VRegSrcSrc, VRegSrcDest) &&
+          SrcReg == VRegSrcDest && VRegSrcSrc == DestReg) {
+        // Okay, now we know that the vreg was defined by a copy from this
+        // physreg.  Find the value number being copied and use it as the value
+        // for this range.
+        const LiveRange *DefRange = interval.getLiveRangeContaining(StartIdx-1);
+        if (DefRange) {
+          LiveRange LR(start, end, DefRange->ValId);
+          interval.addRange(LR);
+          DEBUG(std::cerr << " +" << LR << '\n');
+          return;
+        }
+      }
+    }
+  }
+
+
   LiveRange LR(start, end, interval.getNextValue());
   interval.addRange(LR);
   DEBUG(std::cerr << " +" << LR << '\n');
@@ -491,9 +585,15 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
   if (MRegisterInfo::isVirtualRegister(reg))
     handleVirtualRegisterDef(MBB, MI, getOrCreateInterval(reg));
   else if (allocatableRegs_[reg]) {
-    handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg));
+    unsigned SrcReg = 0, DestReg = 0;
+    if (!tii_->isMoveInstr(*MI, SrcReg, DestReg))
+      SrcReg = DestReg = 0;
+
+    handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(reg),
+                              SrcReg, DestReg);
     for (const unsigned* AS = mri_->getAliasSet(reg); *AS; ++AS)
-      handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS));
+      handlePhysicalRegisterDef(MBB, MI, getOrCreateInterval(*AS),
+                                SrcReg, DestReg);
   }
 }
 
@@ -506,18 +606,19 @@ void LiveIntervals::computeIntervals()
   DEBUG(std::cerr << "********** COMPUTING LIVE INTERVALS **********\n");
   DEBUG(std::cerr << "********** Function: "
         << ((Value*)mf_->getFunction())->getName() << '\n');
+  bool IgnoreFirstInstr = mf_->livein_begin() != mf_->livein_end();
 
   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) {
+    MachineBasicBlock::iterator mi = mbb->begin(), miEnd = mbb->end();
+    if (IgnoreFirstInstr) { ++mi; IgnoreFirstInstr = false; }
+    for (; mi != miEnd; ++mi) {
       const TargetInstrDescriptor& tid =
         tm_->getInstrInfo()->get(mi->getOpcode());
-      DEBUG(std::cerr << getInstructionIndex(mi) << "\t";
-            mi->print(std::cerr, tm_));
+      DEBUG(std::cerr << getInstructionIndex(mi) << "\t" << *mi);
 
       // handle implicit defs
       for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
@@ -534,9 +635,51 @@ void LiveIntervals::computeIntervals()
   }
 }
 
+/// IntA is defined as a copy from IntB and we know it only has one value
+/// number.  If all of the places that IntA and IntB overlap are defined by
+/// copies from IntA to IntB, we know that these two ranges can really be
+/// merged if we adjust the value numbers.  If it is safe, adjust the value
+/// numbers and return true, allowing coalescing to occur.
+bool LiveIntervals::
+AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA,
+                                          LiveInterval &IntB,
+                                          unsigned CopyIdx) {
+  std::vector<LiveRange*> Ranges;
+  IntA.getOverlapingRanges(IntB, CopyIdx, Ranges);
+  
+  assert(!Ranges.empty() && "Why didn't we do a simple join of this?");
+  
+  unsigned IntBRep = rep(IntB.reg);
+  
+  // Check to see if all of the overlaps (entries in Ranges) are defined by a
+  // copy from IntA.  If not, exit.
+  for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
+    unsigned Idx = Ranges[i]->start;
+    MachineInstr *MI = getInstructionFromIndex(Idx);
+    unsigned SrcReg, DestReg;
+    if (!tii_->isMoveInstr(*MI, SrcReg, DestReg)) return false;
+    
+    // If this copy isn't actually defining this range, it must be a live
+    // range spanning basic blocks or something.
+    if (rep(DestReg) != rep(IntA.reg)) return false;
+    
+    // Check to see if this is coming from IntB.  If not, bail out.
+    if (rep(SrcReg) != IntBRep) return false;
+  }
+
+  // Okay, we can change this one.  Get the IntB value number that IntA is
+  // copied from.
+  unsigned ActualValNo = IntA.getLiveRangeContaining(CopyIdx-1)->ValId;
+  
+  // Change all of the value numbers to the same as what we IntA is copied from.
+  for (unsigned i = 0, e = Ranges.size(); i != e; ++i)
+    Ranges[i]->ValId = ActualValNo;
+  
+  return true;
+}
+
 void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
   DEBUG(std::cerr << ((Value*)MBB->getBasicBlock())->getName() << ":\n");
-  const TargetInstrInfo &TII = *tm_->getInstrInfo();
 
   for (MachineBasicBlock::iterator mi = MBB->begin(), mie = MBB->end();
        mi != mie; ++mi) {
@@ -545,60 +688,72 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) {
     // we only join virtual registers with allocatable
     // physical registers since we do not have liveness information
     // on not allocatable physical registers
-    unsigned regA, regB;
-    if (TII.isMoveInstr(*mi, regA, regB) &&
-        (MRegisterInfo::isVirtualRegister(regA) || allocatableRegs_[regA]) &&
-        (MRegisterInfo::isVirtualRegister(regB) || allocatableRegs_[regB])) {
+    unsigned SrcReg, DestReg;
+    if (tii_->isMoveInstr(*mi, SrcReg, DestReg) &&
+        (MRegisterInfo::isVirtualRegister(SrcReg) || allocatableRegs_[SrcReg])&&
+        (MRegisterInfo::isVirtualRegister(DestReg)||allocatableRegs_[DestReg])){
 
       // Get representative registers.
-      regA = rep(regA);
-      regB = rep(regB);
+      SrcReg = rep(SrcReg);
+      DestReg = rep(DestReg);
 
       // If they are already joined we continue.
-      if (regA == regB)
+      if (SrcReg == DestReg)
         continue;
 
       // If they are both physical registers, we cannot join them.
-      if (MRegisterInfo::isPhysicalRegister(regA) &&
-          MRegisterInfo::isPhysicalRegister(regB))
+      if (MRegisterInfo::isPhysicalRegister(SrcReg) &&
+          MRegisterInfo::isPhysicalRegister(DestReg))
         continue;
 
       // If they are not of the same register class, we cannot join them.
-      if (differingRegisterClasses(regA, regB))
+      if (differingRegisterClasses(SrcReg, DestReg))
         continue;
 
-      LiveInterval &IntA = getInterval(regA);
-      LiveInterval &IntB = getInterval(regB);
-      assert(IntA.reg == regA && IntB.reg == regB &&
+      LiveInterval &SrcInt = getInterval(SrcReg);
+      LiveInterval &DestInt = getInterval(DestReg);
+      assert(SrcInt.reg == SrcReg && DestInt.reg == DestReg &&
              "Register mapping is horribly broken!");
 
-      DEBUG(std::cerr << "\t\tInspecting " << IntA << " and " << IntB << ": ");
+      DEBUG(std::cerr << "\t\tInspecting " << SrcInt << " and " << DestInt
+                      << ": ");
 
       // If two intervals contain a single value and are joined by a copy, it
       // does not matter if the intervals overlap, they can always be joined.
-      bool TriviallyJoinable =
-        IntA.containsOneValue() && IntB.containsOneValue();
+      bool Joinable = SrcInt.containsOneValue() && DestInt.containsOneValue();
 
       unsigned MIDefIdx = getDefIndex(getInstructionIndex(mi));
-      if ((TriviallyJoinable || IntB.joinable(IntA, MIDefIdx)) &&
-          !overlapsAliases(&IntA, &IntB)) {
-        IntB.join(IntA, MIDefIdx);
+      
+      // If the intervals think that this is joinable, do so now.
+      if (!Joinable && DestInt.joinable(SrcInt, MIDefIdx))
+        Joinable = true;
+
+      // If DestInt is actually a copy from SrcInt (which we know) that is used
+      // to define another value of SrcInt, we can change the other range of
+      // SrcInt to be the value of the range that defines DestInt, allowing a
+      // coalesce.
+      if (!Joinable && DestInt.containsOneValue() &&
+          AdjustIfAllOverlappingRangesAreCopiesFrom(SrcInt, DestInt, MIDefIdx))
+        Joinable = true;
+      
+      if (!Joinable || overlapsAliases(&SrcInt, &DestInt)) {
+        DEBUG(std::cerr << "Interference!\n");
+      } else {
+        DestInt.join(SrcInt, MIDefIdx);
+        DEBUG(std::cerr << "Joined.  Result = " << DestInt << "\n");
 
-        if (!MRegisterInfo::isPhysicalRegister(regA)) {
-          r2iMap_.erase(regA);
-          r2rMap_[regA] = regB;
+        if (!MRegisterInfo::isPhysicalRegister(SrcReg)) {
+          r2iMap_.erase(SrcReg);
+          r2rMap_[SrcReg] = DestReg;
         } else {
           // Otherwise merge the data structures the other way so we don't lose
           // the physreg information.
-          r2rMap_[regB] = regA;
-          IntB.reg = regA;
-          IntA.swap(IntB);
-          r2iMap_.erase(regB);
+          r2rMap_[DestReg] = SrcReg;
+          DestInt.reg = SrcReg;
+          SrcInt.swap(DestInt);
+          r2iMap_.erase(DestReg);
         }
-        DEBUG(std::cerr << "Joined.  Result = " << IntB << "\n");
         ++numJoins;
-      } else {
-        DEBUG(std::cerr << "Interference!\n");
       }
     }
   }
@@ -644,24 +799,25 @@ void LiveIntervals::joinIntervals() {
   }
 
   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";);
+  DEBUG(for (int i = 0, e = r2rMap_.size(); i != e; ++i)
+          if (r2rMap_[i])
+             std::cerr << "  reg " << i << " -> reg " << r2rMap_[i] << "\n");
 }
 
 /// Return true if the two specified registers belong to different register
 /// classes.  The registers may be either phys or virt regs.
 bool LiveIntervals::differingRegisterClasses(unsigned RegA,
                                              unsigned RegB) const {
-  const TargetRegisterClass *RegClass;
 
   // Get the register classes for the first reg.
-  if (MRegisterInfo::isVirtualRegister(RegA))
-    RegClass = mf_->getSSARegMap()->getRegClass(RegA);
-  else
-    RegClass = mri_->getRegClass(RegA);
+  if (MRegisterInfo::isPhysicalRegister(RegA)) {
+    assert(MRegisterInfo::isVirtualRegister(RegB) &&
+           "Shouldn't consider two physregs!");
+    return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA);
+  }
 
   // Compare against the regclass for the second reg.
+  const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA);
   if (MRegisterInfo::isVirtualRegister(RegB))
     return RegClass != mf_->getSSARegMap()->getRegClass(RegB);
   else
@@ -688,6 +844,7 @@ bool LiveIntervals::overlapsAliases(const LiveInterval *LHS,
 }
 
 LiveInterval LiveIntervals::createInterval(unsigned reg) {
-  float Weight = MRegisterInfo::isPhysicalRegister(reg) ?  HUGE_VAL :0.0F;
+  float Weight = MRegisterInfo::isPhysicalRegister(reg) ?
+                       (float)HUGE_VAL :0.0F;
   return LiveInterval(reg, Weight);
 }