Apply patch review feedback.
[oota-llvm.git] / lib / CodeGen / PreAllocSplitting.cpp
index 1180dee7b793463d0316fa5231c349c67b1ba6e5..97d4728348e561c15d99503f933b20e2c35b2b8c 100644 (file)
@@ -15,6 +15,7 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "pre-alloc-split"
+#include "VirtRegMap.h"
 #include "llvm/CodeGen/LiveIntervalAnalysis.h"
 #include "llvm/CodeGen/LiveStackAnalysis.h"
 #include "llvm/CodeGen/MachineDominators.h"
@@ -38,10 +39,12 @@ using namespace llvm;
 
 static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
 static cl::opt<int> DeadSplitLimit("dead-split-limit", cl::init(-1), cl::Hidden);
+static cl::opt<int> RestoreFoldLimit("restore-fold-limit", cl::init(-1), cl::Hidden);
 
 STATISTIC(NumSplits, "Number of intervals split");
 STATISTIC(NumRemats, "Number of intervals split by rematerialization");
 STATISTIC(NumFolds, "Number of intervals split with spill folding");
+STATISTIC(NumRestoreFolds, "Number of intervals split with restore folding");
 STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers");
 STATISTIC(NumDeadSpills, "Number of dead spills removed");
 
@@ -55,6 +58,7 @@ namespace {
     MachineRegisterInfo   *MRI;
     LiveIntervals         *LIs;
     LiveStacks            *LSs;
+    VirtRegMap            *VRM;
 
     // Barrier - Current barrier being processed.
     MachineInstr          *Barrier;
@@ -98,8 +102,10 @@ namespace {
         AU.addPreservedID(PHIEliminationID);
       AU.addRequired<MachineDominatorTree>();
       AU.addRequired<MachineLoopInfo>();
+      AU.addRequired<VirtRegMap>();
       AU.addPreserved<MachineDominatorTree>();
       AU.addPreserved<MachineLoopInfo>();
+      AU.addPreserved<VirtRegMap>();
       MachineFunctionPass::getAnalysisUsage(AU);
     }
     
@@ -159,21 +165,35 @@ namespace {
                             MachineBasicBlock* MBB,
                             int& SS,
                             SmallPtrSet<MachineInstr*, 4>& RefsInMBB);
+    MachineInstr* FoldRestore(unsigned vreg, 
+                              const TargetRegisterClass* RC,
+                              MachineInstr* Barrier,
+                              MachineBasicBlock* MBB,
+                              int SS,
+                              SmallPtrSet<MachineInstr*, 4>& RefsInMBB);
     void RenumberValno(VNInfo* VN);
     void ReconstructLiveInterval(LiveInterval* LI);
     bool removeDeadSpills(SmallPtrSet<LiveInterval*, 8>& split);
     unsigned getNumberOfNonSpills(SmallPtrSet<MachineInstr*, 4>& MIs,
                                unsigned Reg, int FrameIndex, bool& TwoAddr);
-    VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use,
-                                   MachineBasicBlock* MBB,
-                                   LiveInterval* LI,
+    VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator Use,
+                                   MachineBasicBlock* MBB, LiveInterval* LI,
                                    SmallPtrSet<MachineInstr*, 4>& Visited,
             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
                                       DenseMap<MachineInstr*, VNInfo*>& NewVNs,
                                 DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
                                 DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
-                                        bool toplevel, bool intrablock);
+                                        bool IsTopLevel, bool IsIntraBlock);
+    VNInfo* PerformPHIConstructionFallBack(MachineBasicBlock::iterator Use,
+                                   MachineBasicBlock* MBB, LiveInterval* LI,
+                                   SmallPtrSet<MachineInstr*, 4>& Visited,
+            DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
+            DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
+                                      DenseMap<MachineInstr*, VNInfo*>& NewVNs,
+                                DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
+                                DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
+                                        bool IsTopLevel, bool IsIntraBlock);
 };
 } // end anonymous namespace
 
@@ -212,41 +232,38 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI,
                                   unsigned &SpillIndex) {
   MachineBasicBlock::iterator Pt = MBB->begin();
 
-  // Go top down if RefsInMBB is empty.
-  if (RefsInMBB.empty() && !DefMI) {
-    MachineBasicBlock::iterator MII = MBB->begin();
-    MachineBasicBlock::iterator EndPt = MI;
-    do {
-      ++MII;
-      unsigned Index = LIs->getInstructionIndex(MII);
-      unsigned Gap = LIs->findGapBeforeInstr(Index);
-      if (Gap) {
-        Pt = MII;
-        SpillIndex = Gap;
-        break;
-      
-      // We can't insert the spill between the barrier (a call), and its
-      // corresponding call frame setup.
-      } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode() &&
-                 MII == MachineBasicBlock::iterator(MI))
-        break;
-    } while (MII != EndPt);
-  } else {
-    MachineBasicBlock::iterator MII = MI;
-    MachineBasicBlock::iterator EndPt = DefMI
-      ? MachineBasicBlock::iterator(DefMI) : MBB->begin();
+  MachineBasicBlock::iterator MII = MI;
+  MachineBasicBlock::iterator EndPt = DefMI
+    ? MachineBasicBlock::iterator(DefMI) : MBB->begin();
+    
+  while (MII != EndPt && !RefsInMBB.count(MII) &&
+         MII->getOpcode() != TRI->getCallFrameSetupOpcode())
+    --MII;
+  if (MII == EndPt || RefsInMBB.count(MII)) return Pt;
+    
+  while (MII != EndPt && !RefsInMBB.count(MII)) {
+    unsigned Index = LIs->getInstructionIndex(MII);
     
     // We can't insert the spill between the barrier (a call), and its
     // corresponding call frame setup.
-    if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) --MII;
-    while (MII != EndPt && !RefsInMBB.count(MII)) {
-      unsigned Index = LIs->getInstructionIndex(MII);
-      if (LIs->hasGapBeforeInstr(Index)) {
-        Pt = MII;
-        SpillIndex = LIs->findGapBeforeInstr(Index, true);
+    if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+      while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) {
+        --MII;
+        if (MII == EndPt) {
+          return Pt;
+        }
       }
-      --MII;
+      continue;
+    } else if (LIs->hasGapBeforeInstr(Index)) {
+      Pt = MII;
+      SpillIndex = LIs->findGapBeforeInstr(Index, true);
     }
+    
+    if (RefsInMBB.count(MII))
+      return Pt;
+    
+    
+    --MII;
   }
 
   return Pt;
@@ -264,52 +281,44 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI,
   // FIXME: Allow spill to be inserted to the beginning of the mbb. Update mbb
   // begin index accordingly.
   MachineBasicBlock::iterator Pt = MBB->end();
-  unsigned EndIdx = LIs->getMBBEndIdx(MBB);
+  MachineBasicBlock::iterator EndPt = MBB->getFirstTerminator();
 
-  // Go bottom up if RefsInMBB is empty and the end of the mbb isn't beyond
-  // the last index in the live range.
-  if (RefsInMBB.empty() && LastIdx >= EndIdx) {
-    MachineBasicBlock::iterator MII = MBB->getFirstTerminator();
-    MachineBasicBlock::iterator EndPt = MI;
-    --MII;
-    do {
-      unsigned Index = LIs->getInstructionIndex(MII);
-      unsigned Gap = LIs->findGapBeforeInstr(Index);
-      if (Gap) {
-        Pt = MII;
-        RestoreIndex = Gap;
-        break;
+  // We start at the call, so walk forward until we find the call frame teardown
+  // since we can't insert restores before that.  Bail if we encounter a use
+  // during this time.
+  MachineBasicBlock::iterator MII = MI;
+  if (MII == EndPt) return Pt;
+  
+  while (MII != EndPt && !RefsInMBB.count(MII) &&
+         MII->getOpcode() != TRI->getCallFrameDestroyOpcode())
+    ++MII;
+  if (MII == EndPt || RefsInMBB.count(MII)) return Pt;
+  ++MII;
+  
+  // FIXME: Limit the number of instructions to examine to reduce
+  // compile time?
+  while (MII != EndPt) {
+    unsigned Index = LIs->getInstructionIndex(MII);
+    if (Index > LastIdx)
+      break;
+    unsigned Gap = LIs->findGapBeforeInstr(Index);
       
-      // We can't insert a restore between the barrier (a call) and its 
-      // corresponding call frame teardown.
-      } else if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode() &&
-                 prior(MII) == MachineBasicBlock::iterator(MI))
-        break;
-      --MII;
-    } while (MII != EndPt);
-  } else {
-    MachineBasicBlock::iterator MII = MI;
-    MII = ++MII;
     // We can't insert a restore between the barrier (a call) and its 
     // corresponding call frame teardown.
-    if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode())
-      ++MII;
-    
-    // FIXME: Limit the number of instructions to examine to reduce
-    // compile time?
-    while (MII != MBB->getFirstTerminator()) {
-      unsigned Index = LIs->getInstructionIndex(MII);
-      if (Index > LastIdx)
-        break;
-      unsigned Gap = LIs->findGapBeforeInstr(Index);
-      if (Gap) {
-        Pt = MII;
-        RestoreIndex = Gap;
-      }
-      if (RefsInMBB.count(MII))
-        break;
-      ++MII;
+    if (MII->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+      do {
+        if (MII == EndPt || RefsInMBB.count(MII)) return Pt;
+        ++MII;
+      } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode());
+    } else if (Gap) {
+      Pt = MII;
+      RestoreIndex = Gap;
     }
+    
+    if (RefsInMBB.count(MII))
+      return Pt;
+    
+    ++MII;
   }
 
   return Pt;
@@ -330,7 +339,7 @@ int PreAllocSplitting::CreateSpillStackSlot(unsigned Reg,
   }
 
   // Create live interval for stack slot.
-  CurrSLI = &LSs->getOrCreateInterval(SS);
+  CurrSLI = &LSs->getOrCreateInterval(SS, RC);
   if (CurrSLI->hasAtLeastOneValue())
     CurrSValNo = CurrSLI->getValNumInfo(0);
   else
@@ -431,95 +440,35 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex,
 
 /// PerformPHIConstruction - From properly set up use and def lists, use a PHI
 /// construction algorithm to compute the ranges and valnos for an interval.
-VNInfo* PreAllocSplitting::PerformPHIConstruction(
-                                                MachineBasicBlock::iterator use,
-                                                         MachineBasicBlock* MBB,
-                                                               LiveInterval* LI,
+VNInfo*
+PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI,
+                                       MachineBasicBlock* MBB, LiveInterval* LI,
                                        SmallPtrSet<MachineInstr*, 4>& Visited,
              DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
              DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
                                        DenseMap<MachineInstr*, VNInfo*>& NewVNs,
                                  DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
                                  DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
-                                              bool toplevel, bool intrablock) {
+                                           bool IsTopLevel, bool IsIntraBlock) {
   // Return memoized result if it's available.
-  if (toplevel && Visited.count(use) && NewVNs.count(use))
-    return NewVNs[use];
-  else if (!toplevel && intrablock && NewVNs.count(use))
-    return NewVNs[use];
-  else if (!intrablock && LiveOut.count(MBB))
+  if (IsTopLevel && Visited.count(UseI) && NewVNs.count(UseI))
+    return NewVNs[UseI];
+  else if (!IsTopLevel && IsIntraBlock && NewVNs.count(UseI))
+    return NewVNs[UseI];
+  else if (!IsIntraBlock && LiveOut.count(MBB))
     return LiveOut[MBB];
   
-  typedef DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> > RegMap;
-  
   // Check if our block contains any uses or defs.
   bool ContainsDefs = Defs.count(MBB);
   bool ContainsUses = Uses.count(MBB);
   
-  VNInfo* ret = 0;
+  VNInfo* RetVNI = 0;
   
   // Enumerate the cases of use/def contaning blocks.
   if (!ContainsDefs && !ContainsUses) {
-  Fallback:
-    // NOTE: Because this is the fallback case from other cases, we do NOT
-    // assume that we are not intrablock here.
-    if (Phis.count(MBB)) return Phis[MBB];
-    
-    unsigned StartIndex = LIs->getMBBStartIdx(MBB);
-    
-    if (MBB->pred_size() == 1) {
-      Phis[MBB] = ret = PerformPHIConstruction((*MBB->pred_begin())->end(),
-                                          *(MBB->pred_begin()), LI, Visited,
-                                          Defs, Uses, NewVNs, LiveOut, Phis,
-                                          false, false);
-      unsigned EndIndex = 0;
-      if (intrablock) {
-        EndIndex = LIs->getInstructionIndex(use);
-        EndIndex = LiveIntervals::getUseIndex(EndIndex);
-      } else
-        EndIndex = LIs->getMBBEndIdx(MBB);
-      
-      LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
-      if (intrablock)
-        LI->addKill(ret, EndIndex);
-    } else {
-      Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0,
-                                          LIs->getVNInfoAllocator());
-      if (!intrablock) LiveOut[MBB] = ret;
-    
-      // If there are no uses or defs between our starting point and the
-      // beginning of the block, then recursive perform phi construction
-      // on our predecessors.
-      DenseMap<MachineBasicBlock*, VNInfo*> IncomingVNs;
-      for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
-           PE = MBB->pred_end(); PI != PE; ++PI) {
-        VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, 
-                                            Visited, Defs, Uses, NewVNs,
-                                            LiveOut, Phis, false, false);
-        if (Incoming != 0)
-          IncomingVNs[*PI] = Incoming;
-      }
-    
-      // Otherwise, merge the incoming VNInfos with a phi join.  Create a new
-      // VNInfo to represent the joined value.
-      for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I =
-           IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
-        I->second->hasPHIKill = true;
-        unsigned KillIndex = LIs->getMBBEndIdx(I->first);
-        if (!LiveInterval::isKill(I->second, KillIndex))
-          LI->addKill(I->second, KillIndex);
-      }
-      
-      unsigned EndIndex = 0;
-      if (intrablock) {
-        EndIndex = LIs->getInstructionIndex(use);
-        EndIndex = LiveIntervals::getUseIndex(EndIndex);
-      } else
-        EndIndex = LIs->getMBBEndIdx(MBB);
-      LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
-      if (intrablock)
-        LI->addKill(ret, EndIndex);
-    }
+    return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses,
+                                          NewVNs, LiveOut, Phis,
+                                          IsTopLevel, IsIntraBlock);
   } else if (ContainsDefs && !ContainsUses) {
     SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
 
@@ -527,71 +476,75 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
     // instruction we care about, go to the fallback case.  Note that that
     // should never happen: this cannot be intrablock, so use should
     // always be an end() iterator.
-    assert(use == MBB->end() && "No use marked in intrablock");
+    assert(UseI == MBB->end() && "No use marked in intrablock");
     
-    MachineBasicBlock::iterator walker = use;
-    --walker;
-    while (walker != MBB->begin())
-      if (BlockDefs.count(walker)) {
+    MachineBasicBlock::iterator Walker = UseI;
+    --Walker;
+    while (Walker != MBB->begin()) {
+      if (BlockDefs.count(Walker))
         break;
-      } else
-        --walker;
+      --Walker;
+    }
     
     // Once we've found it, extend its VNInfo to our instruction.
-    unsigned DefIndex = LIs->getInstructionIndex(walker);
+    unsigned DefIndex = LIs->getInstructionIndex(Walker);
     DefIndex = LiveIntervals::getDefIndex(DefIndex);
     unsigned EndIndex = LIs->getMBBEndIdx(MBB);
     
-    ret = NewVNs[walker];
-    LI->addRange(LiveRange(DefIndex, EndIndex+1, ret));
+    RetVNI = NewVNs[Walker];
+    LI->addRange(LiveRange(DefIndex, EndIndex+1, RetVNI));
   } else if (!ContainsDefs && ContainsUses) {
     SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
     
     // Search for the use in this block that precedes the instruction we care 
-    // about, going to the fallback case if we don't find it.
+    // about, going to the fallback case if we don't find it.    
+    if (UseI == MBB->begin())
+      return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+                                            Uses, NewVNs, LiveOut, Phis,
+                                            IsTopLevel, IsIntraBlock);
     
-    if (use == MBB->begin())
-      goto Fallback;
-    
-    MachineBasicBlock::iterator walker = use;
-    --walker;
+    MachineBasicBlock::iterator Walker = UseI;
+    --Walker;
     bool found = false;
-    while (walker != MBB->begin())
-      if (BlockUses.count(walker)) {
+    while (Walker != MBB->begin()) {
+      if (BlockUses.count(Walker)) {
         found = true;
         break;
-      } else
-        --walker;
+      }
+      --Walker;
+    }
         
     // Must check begin() too.
     if (!found) {
-      if (BlockUses.count(walker))
+      if (BlockUses.count(Walker))
         found = true;
       else
-        goto Fallback;
+        return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+                                              Uses, NewVNs, LiveOut, Phis,
+                                              IsTopLevel, IsIntraBlock);
     }
 
-    unsigned UseIndex = LIs->getInstructionIndex(walker);
+    unsigned UseIndex = LIs->getInstructionIndex(Walker);
     UseIndex = LiveIntervals::getUseIndex(UseIndex);
     unsigned EndIndex = 0;
-    if (intrablock) {
-      EndIndex = LIs->getInstructionIndex(use);
+    if (IsIntraBlock) {
+      EndIndex = LIs->getInstructionIndex(UseI);
       EndIndex = LiveIntervals::getUseIndex(EndIndex);
     } else
       EndIndex = LIs->getMBBEndIdx(MBB);
 
     // Now, recursively phi construct the VNInfo for the use we found,
     // and then extend it to include the instruction we care about
-    ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
-                                 NewVNs, LiveOut, Phis, false, true);
+    RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses,
+                                    NewVNs, LiveOut, Phis, false, true);
     
-    LI->addRange(LiveRange(UseIndex, EndIndex+1, ret));
+    LI->addRange(LiveRange(UseIndex, EndIndex+1, RetVNI));
     
     // FIXME: Need to set kills properly for inter-block stuff.
-    if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex);
-    if (intrablock)
-      LI->addKill(ret, EndIndex);
-  } else if (ContainsDefs && ContainsUses){
+    if (LI->isKill(RetVNI, UseIndex)) LI->removeKill(RetVNI, UseIndex);
+    if (IsIntraBlock)
+      LI->addKill(RetVNI, EndIndex);
+  } else if (ContainsDefs && ContainsUses) {
     SmallPtrSet<MachineInstr*, 2>& BlockDefs = Defs[MBB];
     SmallPtrSet<MachineInstr*, 2>& BlockUses = Uses[MBB];
     
@@ -599,67 +552,159 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
     // special note that checking for defs must take precedence over checking
     // for uses, because of two-address instructions.
     
-    if (use == MBB->begin())
-      goto Fallback;
+    if (UseI == MBB->begin())
+      return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses,
+                                            NewVNs, LiveOut, Phis,
+                                            IsTopLevel, IsIntraBlock);
     
-    MachineBasicBlock::iterator walker = use;
-    --walker;
+    MachineBasicBlock::iterator Walker = UseI;
+    --Walker;
     bool foundDef = false;
     bool foundUse = false;
-    while (walker != MBB->begin())
-      if (BlockDefs.count(walker)) {
+    while (Walker != MBB->begin()) {
+      if (BlockDefs.count(Walker)) {
         foundDef = true;
         break;
-      } else if (BlockUses.count(walker)) {
+      } else if (BlockUses.count(Walker)) {
         foundUse = true;
         break;
-      } else
-        --walker;
+      }
+      --Walker;
+    }
         
     // Must check begin() too.
     if (!foundDef && !foundUse) {
-      if (BlockDefs.count(walker))
+      if (BlockDefs.count(Walker))
         foundDef = true;
-      else if (BlockUses.count(walker))
+      else if (BlockUses.count(Walker))
         foundUse = true;
       else
-        goto Fallback;
+        return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs,
+                                              Uses, NewVNs, LiveOut, Phis,
+                                              IsTopLevel, IsIntraBlock);
     }
 
-    unsigned StartIndex = LIs->getInstructionIndex(walker);
+    unsigned StartIndex = LIs->getInstructionIndex(Walker);
     StartIndex = foundDef ? LiveIntervals::getDefIndex(StartIndex) :
                             LiveIntervals::getUseIndex(StartIndex);
     unsigned EndIndex = 0;
-    if (intrablock) {
-      EndIndex = LIs->getInstructionIndex(use);
+    if (IsIntraBlock) {
+      EndIndex = LIs->getInstructionIndex(UseI);
       EndIndex = LiveIntervals::getUseIndex(EndIndex);
     } else
       EndIndex = LIs->getMBBEndIdx(MBB);
 
     if (foundDef)
-      ret = NewVNs[walker];
+      RetVNI = NewVNs[Walker];
     else
-      ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses,
-                                   NewVNs, LiveOut, Phis, false, true);
+      RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses,
+                                      NewVNs, LiveOut, Phis, false, true);
 
-    LI->addRange(LiveRange(StartIndex, EndIndex+1, ret));
+    LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI));
     
-    if (foundUse && LI->isKill(ret, StartIndex))
-      LI->removeKill(ret, StartIndex);
-    if (intrablock) {
-      LI->addKill(ret, EndIndex);
+    if (foundUse && LI->isKill(RetVNI, StartIndex))
+      LI->removeKill(RetVNI, StartIndex);
+    if (IsIntraBlock) {
+      LI->addKill(RetVNI, EndIndex);
     }
   }
   
   // Memoize results so we don't have to recompute them.
-  if (!intrablock) LiveOut[MBB] = ret;
+  if (!IsIntraBlock) LiveOut[MBB] = RetVNI;
   else {
-    if (!NewVNs.count(use))
-      NewVNs[use] = ret;
-    Visited.insert(use);
+    if (!NewVNs.count(UseI))
+      NewVNs[UseI] = RetVNI;
+    Visited.insert(UseI);
   }
 
-  return ret;
+  return RetVNI;
+}
+
+/// PerformPHIConstructionFallBack - PerformPHIConstruction fall back path.
+///
+VNInfo*
+PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator UseI,
+                                       MachineBasicBlock* MBB, LiveInterval* LI,
+                                       SmallPtrSet<MachineInstr*, 4>& Visited,
+             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Defs,
+             DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 2> >& Uses,
+                                       DenseMap<MachineInstr*, VNInfo*>& NewVNs,
+                                 DenseMap<MachineBasicBlock*, VNInfo*>& LiveOut,
+                                 DenseMap<MachineBasicBlock*, VNInfo*>& Phis,
+                                           bool IsTopLevel, bool IsIntraBlock) {
+  // NOTE: Because this is the fallback case from other cases, we do NOT
+  // assume that we are not intrablock here.
+  if (Phis.count(MBB)) return Phis[MBB]; 
+
+  unsigned StartIndex = LIs->getMBBStartIdx(MBB);
+  VNInfo *RetVNI = Phis[MBB] = LI->getNextValue(~0U, /*FIXME*/ 0,
+                                                LIs->getVNInfoAllocator());
+  if (!IsIntraBlock) LiveOut[MBB] = RetVNI;
+    
+  // If there are no uses or defs between our starting point and the
+  // beginning of the block, then recursive perform phi construction
+  // on our predecessors.
+  DenseMap<MachineBasicBlock*, VNInfo*> IncomingVNs;
+  for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+         PE = MBB->pred_end(); PI != PE; ++PI) {
+    VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, 
+                                              Visited, Defs, Uses, NewVNs,
+                                              LiveOut, Phis, false, false);
+    if (Incoming != 0)
+      IncomingVNs[*PI] = Incoming;
+  }
+    
+  if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) {
+    VNInfo* OldVN = RetVNI;
+    VNInfo* NewVN = IncomingVNs.begin()->second;
+    VNInfo* MergedVN = LI->MergeValueNumberInto(OldVN, NewVN);
+    if (MergedVN == OldVN) std::swap(OldVN, NewVN);
+    
+    for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator LOI = LiveOut.begin(),
+         LOE = LiveOut.end(); LOI != LOE; ++LOI)
+      if (LOI->second == OldVN)
+        LOI->second = MergedVN;
+    for (DenseMap<MachineInstr*, VNInfo*>::iterator NVI = NewVNs.begin(),
+         NVE = NewVNs.end(); NVI != NVE; ++NVI)
+      if (NVI->second == OldVN)
+        NVI->second = MergedVN;
+    for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator PI = Phis.begin(),
+         PE = Phis.end(); PI != PE; ++PI)
+      if (PI->second == OldVN)
+        PI->second = MergedVN;
+    RetVNI = MergedVN;
+  } else {
+    // Otherwise, merge the incoming VNInfos with a phi join.  Create a new
+    // VNInfo to represent the joined value.
+    for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator I =
+           IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
+      I->second->hasPHIKill = true;
+      unsigned KillIndex = LIs->getMBBEndIdx(I->first);
+      if (!LiveInterval::isKill(I->second, KillIndex))
+        LI->addKill(I->second, KillIndex);
+    }
+  }
+      
+  unsigned EndIndex = 0;
+  if (IsIntraBlock) {
+    EndIndex = LIs->getInstructionIndex(UseI);
+    EndIndex = LiveIntervals::getUseIndex(EndIndex);
+  } else
+    EndIndex = LIs->getMBBEndIdx(MBB);
+  LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI));
+  if (IsIntraBlock)
+    LI->addKill(RetVNI, EndIndex);
+
+  // Memoize results so we don't have to recompute them.
+  if (!IsIntraBlock)
+    LiveOut[MBB] = RetVNI;
+  else {
+    if (!NewVNs.count(UseI))
+      NewVNs[UseI] = RetVNI;
+    Visited.insert(UseI);
+  }
+
+  return RetVNI;
 }
 
 /// ReconstructLiveInterval - Recompute a live interval from scratch.
@@ -758,7 +803,7 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
       MachineInstr* MI = LIs->getInstructionFromIndex(*KI);
       unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg);
       if (DefIdx == ~0U) continue;
-      if (MI->isRegReDefinedByTwoAddr(DefIdx)) {
+      if (MI->isRegTiedToUseOperand(DefIdx)) {
         VNInfo* NextVN =
                      CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI));
         if (NextVN == OldVN) continue;
@@ -809,6 +854,9 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
     MO.setReg(NewVReg);
   }
   
+  // Grow the VirtRegMap, since we've created a new vreg.
+  VRM->grow();
+  
   // The renumbered vreg shares a stack slot with the old register.
   if (IntervalSSMap.count(CurrLI->reg))
     IntervalSSMap[NewVReg] = IntervalSSMap[CurrLI->reg];
@@ -878,8 +926,7 @@ MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,
   if (I != IntervalSSMap.end()) {
     SS = I->second;
   } else {
-    SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());
-    
+    SS = MFI->CreateStackObject(RC->getSize(), RC->getAlignment());    
   }
   
   MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(),
@@ -891,7 +938,7 @@ MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,
     ++NumFolds;
     
     IntervalSSMap[vreg] = SS;
-    CurrSLI = &LSs->getOrCreateInterval(SS);
+    CurrSLI = &LSs->getOrCreateInterval(SS, RC);
     if (CurrSLI->hasAtLeastOneValue())
       CurrSValNo = CurrSLI->getValNumInfo(0);
     else
@@ -901,6 +948,79 @@ MachineInstr* PreAllocSplitting::FoldSpill(unsigned vreg,
   return FMI;
 }
 
+MachineInstr* PreAllocSplitting::FoldRestore(unsigned vreg, 
+                                             const TargetRegisterClass* RC,
+                                             MachineInstr* Barrier,
+                                             MachineBasicBlock* MBB,
+                                             int SS,
+                                     SmallPtrSet<MachineInstr*, 4>& RefsInMBB) {
+  if ((int)RestoreFoldLimit != -1 && RestoreFoldLimit == (int)NumRestoreFolds)
+    return 0;
+                                       
+  // Go top down if RefsInMBB is empty.
+  if (RefsInMBB.empty())
+    return 0;
+  
+  // Can't fold a restore between a call stack setup and teardown.
+  MachineBasicBlock::iterator FoldPt = Barrier;
+  
+  // Advance from barrier to call frame teardown.
+  while (FoldPt != MBB->getFirstTerminator() &&
+         FoldPt->getOpcode() != TRI->getCallFrameDestroyOpcode()) {
+    if (RefsInMBB.count(FoldPt))
+      return 0;
+    
+    ++FoldPt;
+  }
+  
+  if (FoldPt == MBB->getFirstTerminator())
+    return 0;
+  else
+    ++FoldPt;
+  
+  // Now find the restore point.
+  while (FoldPt != MBB->getFirstTerminator() && !RefsInMBB.count(FoldPt)) {
+    if (FoldPt->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+      while (FoldPt != MBB->getFirstTerminator() &&
+             FoldPt->getOpcode() != TRI->getCallFrameDestroyOpcode()) {
+        if (RefsInMBB.count(FoldPt))
+          return 0;
+        
+        ++FoldPt;
+      }
+      
+      if (FoldPt == MBB->getFirstTerminator())
+        return 0;
+    } 
+    
+    ++FoldPt;
+  }
+  
+  if (FoldPt == MBB->getFirstTerminator())
+    return 0;
+  
+  int OpIdx = FoldPt->findRegisterUseOperandIdx(vreg, true);
+  if (OpIdx == -1)
+    return 0;
+  
+  SmallVector<unsigned, 1> Ops;
+  Ops.push_back(OpIdx);
+  
+  if (!TII->canFoldMemoryOperand(FoldPt, Ops))
+    return 0;
+  
+  MachineInstr* FMI = TII->foldMemoryOperand(*MBB->getParent(),
+                                             FoldPt, Ops, SS);
+  
+  if (FMI) {
+    LIs->ReplaceMachineInstrInMaps(FoldPt, FMI);
+    FMI = MBB->insert(MBB->erase(FoldPt), FMI);
+    ++NumRestoreFolds;
+  }
+  
+  return FMI;
+}
+
 /// SplitRegLiveInterval - Split (spill and restore) the given live interval
 /// so it would not cross the barrier that's being processed. Shrink wrap
 /// (minimize) the live interval to the last uses.
@@ -1008,18 +1128,29 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) {
     Def2SpillMap[ValNo->def] = SpillIndex;
 
   // Add restore.
-  TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC);
-  MachineInstr *LoadMI = prior(RestorePt);
-  LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
+  bool FoldedRestore = false;
+  if (MachineInstr* LMI = FoldRestore(CurrLI->reg, RC, Barrier,
+                                      BarrierMBB, SS, RefsInMBB)) {
+    RestorePt = LMI;
+    RestoreIndex = LIs->getInstructionIndex(RestorePt);
+    FoldedRestore = true;
+  } else {
+    TII->loadRegFromStackSlot(*BarrierMBB, RestorePt, CurrLI->reg, SS, RC);
+    MachineInstr *LoadMI = prior(RestorePt);
+    LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex);
+  }
 
   // Update spill stack slot live interval.
   UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1,
                           LIs->getDefIndex(RestoreIndex));
 
   ReconstructLiveInterval(CurrLI);
-  unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt));
-  RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx);
-  RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx));
+  
+  if (!FoldedRestore) {
+    unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt));
+    RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx);
+    RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx));
+  }
   
   ++NumSplits;
   return true;
@@ -1034,7 +1165,10 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs,
   // by the current barrier.
   SmallVector<LiveInterval*, 8> Intervals;
   for (const TargetRegisterClass **RC = RCs; *RC; ++RC) {
-    if (TII->IgnoreRegisterClassBarriers(*RC))
+    // FIXME: If it's not safe to move any instruction that defines the barrier
+    // register class, then it means there are some special dependencies which
+    // codegen is not modelling. Ignore these barriers for now.
+    if (!TII->isSafeToMoveRegClassDefs(*RC))
       continue;
     std::vector<unsigned> &VRs = MRI->getRegClassVirtRegs(*RC);
     for (unsigned i = 0, e = VRs.size(); i != e; ++i) {
@@ -1079,7 +1213,7 @@ unsigned PreAllocSplitting::getNumberOfNonSpills(
       NonSpills++;
     
     int DefIdx = (*UI)->findRegisterDefOperandIdx(Reg);
-    if (DefIdx != -1 && (*UI)->isRegReDefinedByTwoAddr(DefIdx))
+    if (DefIdx != -1 && (*UI)->isRegTiedToUseOperand(DefIdx))
       FeedsTwoAddr = true;
   }
   
@@ -1317,6 +1451,7 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
   MRI    = &MF.getRegInfo();
   LIs    = &getAnalysis<LiveIntervals>();
   LSs    = &getAnalysis<LiveStacks>();
+  VRM    = &getAnalysis<VirtRegMap>();
 
   bool MadeChange = false;