[llvm-commits] [llvm] r44428 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/VirtRegMap.cpp lib/CodeGen/VirtRegMap.h

Evan Cheng evan.cheng at apple.com
Wed Nov 28 17:06:25 PST 2007


Author: evancheng
Date: Wed Nov 28 19:06:25 2007
New Revision: 44428

URL: http://llvm.org/viewvc/llvm-project?rev=44428&view=rev
Log:
Fixed various live interval splitting bugs / compile time issues.

Modified:
    llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
    llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
    llvm/trunk/lib/CodeGen/VirtRegMap.cpp
    llvm/trunk/lib/CodeGen/VirtRegMap.h

Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=44428&r1=44427&r2=44428&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Nov 28 19:06:25 2007
@@ -277,10 +277,13 @@
                               MachineInstr *DefMI, unsigned index, unsigned i,
                               bool isSS, int slot, unsigned reg);
 
-    bool anyKillInMBBAfterIdx(const LiveInterval &li,
-                              MachineBasicBlock *MBB, unsigned Idx,
-                              const VNInfo *VNI = NULL) const;
+    /// anyKillInMBBAfterIdx - Returns true if there is a kill of the specified
+    /// VNInfo that's after the specified index but is within the basic block.
+    bool anyKillInMBBAfterIdx(const LiveInterval &li, const VNInfo *VNI,
+                              MachineBasicBlock *MBB, unsigned Idx) const;
 
+    /// intervalIsInOneMBB - Returns true if the specified interval is entirely
+    /// within a single basic block.
     bool intervalIsInOneMBB(const LiveInterval &li) const;
 
     /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions
@@ -301,7 +304,9 @@
         VirtRegMap &vrm, SSARegMap *RegMap, const TargetRegisterClass* rc,
         SmallVector<int, 4> &ReMatIds, const LoopInfo *loopInfo,
         BitVector &SpillMBBs,
-        std::map<unsigned, std::pair<int, unsigned> > &SpillIdxes,
+        std::map<unsigned, std::pair<int, bool> > &SpillIdxes,
+        BitVector &RestoreMBBs,
+        std::map<unsigned, std::pair<int, bool> > &RestoreIdxes,
         std::map<unsigned,unsigned> &NewVRegs,
         std::vector<LiveInterval*> &NewLIs);
 

Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=44428&r1=44427&r2=44428&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Nov 28 19:06:25 2007
@@ -42,12 +42,15 @@
                               cl::init(false), cl::Hidden);
 
   cl::opt<bool> SplitAtBB("split-intervals-at-bb", 
-                              cl::init(false), cl::Hidden);
+                          cl::init(false), cl::Hidden);
+  cl::opt<int> SplitLimit("split-limit",
+                          cl::init(-1), cl::Hidden);
 }
 
 STATISTIC(numIntervals, "Number of original intervals");
 STATISTIC(numIntervalsAfter, "Number of intervals after coalescing");
-STATISTIC(numFolded   , "Number of loads/stores folded into instructions");
+STATISTIC(numFolds    , "Number of loads/stores folded into instructions");
+STATISTIC(numSplits   , "Number of intervals split");
 
 char LiveIntervals::ID = 0;
 namespace {
@@ -389,7 +392,7 @@
       unsigned killIndex = getInstructionIndex(&mbb->back()) + InstrSlots::NUM;
       LiveRange LR(defIndex, killIndex, ValNo);
       interval.addRange(LR);
-      interval.addKill(ValNo, killIndex-1); // odd # means phi node
+      interval.addKill(ValNo, killIndex+1); // odd # means phi node
       DOUT << " +" << LR;
     }
   }
@@ -652,13 +655,17 @@
     else
       LiveVariables::transferKillDeadInfo(MI, fmi, mri_);
     MachineBasicBlock &MBB = *MI->getParent();
-    vrm.virtFolded(reg, MI, i, fmi);
+    if (isSS) {
+      if (!mf_->getFrameInfo()->isFixedObjectIndex(slot))
+        vrm.virtFolded(reg, MI, i, fmi);
+    }
     vrm.transferSpillPts(MI, fmi);
+    vrm.transferRestorePts(MI, fmi);
     mi2iMap_.erase(MI);
     i2miMap_[index/InstrSlots::NUM] = fmi;
     mi2iMap_[fmi] = index;
     MI = MBB.insert(MBB.erase(MI), fmi);
-    ++numFolded;
+    ++numFolds;
     return true;
   }
   return false;
@@ -681,20 +688,6 @@
   return true;
 }
 
-static
-bool hasALaterUse(MachineBasicBlock *MBB, MachineInstr *MI, unsigned Reg) {
-  MachineBasicBlock::iterator I = MI;
-  if (I == MBB->end())
-    return false;
-  ++I;
-  while (I != MBB->end()) {
-    if (I->findRegisterUseOperandIdx(Reg) != -1)
-      return true;
-    ++I;
-  }
-  return false;
-}
-
 /// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions
 /// for addIntervalsForSpills to rewrite uses / defs for the given live range.
 void LiveIntervals::
@@ -738,6 +731,7 @@
       }
 
       // If def for this use can't be rematerialized, then try folding.
+      // If def is rematerializable and it's a load, also try folding.
       TryFold = !ReMatOrigDefMI ||
         (ReMatOrigDefMI && (MI == ReMatOrigDefMI || isLoad));
       if (isLoad) {
@@ -747,15 +741,10 @@
       }
     }
 
-    // If we are splitting live intervals, only fold if it's 1) the first
-    // use and it's a kill or 2) there isn't another use later in this MBB.
-    TryFold &= NewVReg == 0;
-    if (TryFold && TrySplit)
-      // Do not fold store into def here if we are splitting. We'll find an
-      // optimal point to insert a store later.
-      if (HasDef || mop.isDef() ||
-          (!mop.isKill() && hasALaterUse(MI->getParent(), MI, li.reg)))
-        TryFold = false;
+    // Do not fold load / store here if we are splitting. We'll find an
+    // optimal point to insert a load / store later.
+    if (TryFold)
+      TryFold = !TrySplit && NewVReg == 0;
 
     // FIXME: fold subreg use
     if (!isSubReg && TryFold &&
@@ -859,27 +848,13 @@
 }
 
 bool LiveIntervals::anyKillInMBBAfterIdx(const LiveInterval &li,
-                                         MachineBasicBlock *MBB, unsigned Idx,
-                                         const VNInfo *VNI) const {
+                                   const VNInfo *VNI,
+                                   MachineBasicBlock *MBB, unsigned Idx) const {
   unsigned End = getMBBEndIdx(MBB);
-  if (VNI) {
-    for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) {
-      unsigned KillIdx = VNI->kills[j];
-      if (KillIdx > Idx && KillIdx < End)
-        return true;
-    }
-    return false;
-  }
-
-  // Look at all the VNInfo's.
-  for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
-       i != e; ++i) {
-    const VNInfo *VNI = *i;
-    for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) {
-      unsigned KillIdx = VNI->kills[j];
-      if (KillIdx > Idx && KillIdx < End)
-        return true;
-    }
+  for (unsigned j = 0, ee = VNI->kills.size(); j != ee; ++j) {
+    unsigned KillIdx = VNI->kills[j];
+    if (KillIdx > Idx && KillIdx < End)
+      return true;
   }
   return false;
 }
@@ -895,7 +870,9 @@
                     SmallVector<int, 4> &ReMatIds,
                     const LoopInfo *loopInfo,
                     BitVector &SpillMBBs,
-                    std::map<unsigned, std::pair<int, unsigned> > &SpillIdxes,
+                    std::map<unsigned, std::pair<int, bool> > &SpillIdxes,
+                    BitVector &RestoreMBBs,
+                    std::map<unsigned, std::pair<int, bool> > &RestoreIdxes,
                     std::map<unsigned,unsigned> &NewVRegs,
                     std::vector<LiveInterval*> &NewLIs) {
   unsigned NewVReg = 0;
@@ -930,53 +907,79 @@
 
     // Update weight of spill interval.
     LiveInterval &nI = getOrCreateInterval(NewVReg);
-    if (!TrySplitMI)
+    if (!TrySplitMI) {
       // The spill weight is now infinity as it cannot be spilled again.
       nI.weight = HUGE_VALF;
-    else {
-      // Keep track of the last def in each MBB.
-      if (HasDef) {
-        if (MI != ReMatOrigDefMI || !CanDelete) {
-          // If this is a two-address code, then this index probably starts a
-          // VNInfo so we should examine all the VNInfo's.
-          bool HasKill = HasUse
-            ? anyKillInMBBAfterIdx(li, MBB, getDefIndex(index))
-            : anyKillInMBBAfterIdx(li, MBB, getDefIndex(index), I->valno);
-          if (!HasKill) {
-            unsigned MBBId = MBB->getNumber();
-            // High bit specify whether this spill ought to be folded if
-            // possible.
-            std::map<unsigned, std::pair<int,unsigned> >::iterator SII =
-              SpillIdxes.find(MBBId);
-            if (SII == SpillIdxes.end() || (int)index > SII->second.first)
-              SpillIdxes[MBBId] = std::make_pair(index, NewVReg | (1 << 31));
-            SpillMBBs.set(MBBId);
-          }
+      continue;
+    }
+
+    // Keep track of the last def and first use in each MBB.
+    unsigned MBBId = MBB->getNumber();
+    if (HasDef) {
+      if (MI != ReMatOrigDefMI || !CanDelete) {
+        // If this is a two-address code, then this index probably starts a
+        // VNInfo so we should examine all the VNInfo's.
+        bool HasKill = false;
+        if (!HasUse)
+          HasKill = anyKillInMBBAfterIdx(li, I->valno, MBB, getDefIndex(index));
+        else {
+          const VNInfo *VNI = NULL;
+          for (LiveInterval::const_vni_iterator i = li.vni_begin(),
+                 e = li.vni_end(); i != e; ++i)
+            if ((*i)->def == getDefIndex(index)) {
+              VNI = *i;
+              break;
+            }
+          if (VNI)
+            HasKill = anyKillInMBBAfterIdx(li, VNI, MBB, getDefIndex(index));
         }
-        if (!IsNew) {
-          // It this interval hasn't been assigned a stack slot
-          // (because earlier def is remat), do it now.
-          int SS = vrm.getStackSlot(NewVReg);
-          if (SS != (int)Slot) {
-            assert(SS == VirtRegMap::NO_STACK_SLOT);
-            vrm.assignVirt2StackSlot(NewVReg, Slot);
+        if (!HasKill) {
+          std::map<unsigned, std::pair<int, bool> >::iterator SII =
+            SpillIdxes.find(MBBId);
+          if (SII == SpillIdxes.end())
+            SpillIdxes[MBBId] = std::make_pair(index, true);
+          else if ((int)index > SII->second.first) {
+            // If there is an earlier def and this is a two-address
+            // instruction, then it's not possible to fold the store (which
+            // would also fold the load).
+            SpillIdxes[MBBId] = std::make_pair(index, !HasUse);
           }
+          SpillMBBs.set(MBBId);
         }
-      } else if (HasUse) {
-        // Use(s) following the last def, it's not safe to fold the spill.
-        unsigned MBBId = MBB->getNumber();
-        std::map<unsigned, std::pair<int,unsigned> >::iterator SII =
-          SpillIdxes.find(MBBId);
-        if (SII != SpillIdxes.end() &&
-            (SII->second.second & ((1<<31)-1)) == NewVReg &&
-            (int)getUseIndex(index) > SII->second.first)
-          SpillIdxes[MBBId].second &= (1<<31)-1;
       }
+      if (!IsNew) {
+        // It this interval hasn't been assigned a stack slot
+        // (because earlier def is remat), do it now.
+        int SS = vrm.getStackSlot(NewVReg);
+        if (SS != (int)Slot) {
+          assert(SS == VirtRegMap::NO_STACK_SLOT);
+          vrm.assignVirt2StackSlot(NewVReg, Slot);
+        }
+      }
+    }
 
-      // Update spill weight.
-      unsigned loopDepth = loopInfo->getLoopDepth(MBB->getBasicBlock());
-      nI.weight += getSpillWeight(HasDef, HasUse, loopDepth);
+    if (HasUse) {
+      std::map<unsigned, std::pair<int, bool> >::iterator SII =
+        SpillIdxes.find(MBBId);
+      if (SII != SpillIdxes.end() && (int)index > SII->second.first)
+        // Use(s) following the last def, it's not safe to fold the spill.
+        SII->second.second = false;
+      std::map<unsigned, std::pair<int, bool> >::iterator RII =
+        RestoreIdxes.find(MBBId);
+      if (RII != RestoreIdxes.end())
+        // If we are splitting live intervals, only fold if it's the first
+        // use and there isn't another use later in the MBB.
+        RII->second.second = false;
+      else if (IsNew) {
+        // Only need a reload if there isn't an earlier def / use.
+        RestoreIdxes[MBBId] = std::make_pair(index, true);
+        RestoreMBBs.set(MBBId);
+      }
     }
+
+    // Update spill weight.
+    unsigned loopDepth = loopInfo->getLoopDepth(MBB->getBasicBlock());
+    nI.weight += getSpillWeight(HasDef, HasUse, loopDepth);
   }
 }
 
@@ -998,7 +1001,9 @@
 
   // Each bit specify whether it a spill is required in the MBB.
   BitVector SpillMBBs(mf_->getNumBlockIDs());
-  std::map<unsigned, std::pair<int, unsigned> > SpillIdxes;
+  std::map<unsigned, std::pair<int, bool> > SpillIdxes;
+  BitVector RestoreMBBs(mf_->getNumBlockIDs());
+  std::map<unsigned, std::pair<int, bool> > RestoreIdxes;
   std::map<unsigned,unsigned> NewVRegs;
   std::vector<LiveInterval*> NewLIs;
   SSARegMap *RegMap = mf_->getSSARegMap();
@@ -1036,13 +1041,15 @@
       if (IsFirstRange) {
         rewriteInstructionsForSpills(li, false, I, NULL, ReMatDefMI,
                              Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
-                             false, vrm, RegMap, rc, ReMatIds,
-                             loopInfo, SpillMBBs, SpillIdxes, NewVRegs, NewLIs);
+                             false, vrm, RegMap, rc, ReMatIds, loopInfo,
+                             SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
+                             NewVRegs, NewLIs);
       } else {
         rewriteInstructionsForSpills(li, false, I, NULL, 0,
                              Slot, 0, false, false, false,
-                             false, vrm, RegMap, rc, ReMatIds,
-                             loopInfo, SpillMBBs, SpillIdxes, NewVRegs, NewLIs);
+                             false, vrm, RegMap, rc, ReMatIds, loopInfo,
+                             SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
+                             NewVRegs, NewLIs);
       }
       IsFirstRange = false;
     }
@@ -1050,6 +1057,10 @@
   }
 
   bool TrySplit = SplitAtBB && !intervalIsInOneMBB(li);
+  if (SplitLimit != -1 && (int)numSplits >= SplitLimit)
+    TrySplit = false;
+  if (TrySplit)
+    ++numSplits;
   bool NeedStackSlot = false;
   for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
        i != e; ++i) {
@@ -1110,39 +1121,118 @@
     bool isLoad = isLoadSS ||
       (DefIsReMat && (ReMatDefMI->getInstrDescriptor()->Flags & M_LOAD_FLAG));
     rewriteInstructionsForSpills(li, TrySplit, I, ReMatOrigDefMI, ReMatDefMI,
-                                 Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
-                                 CanDelete, vrm, RegMap, rc, ReMatIds,
-                                 loopInfo, SpillMBBs, SpillIdxes, NewVRegs, NewLIs);
-  }
+                               Slot, LdSlot, isLoad, isLoadSS, DefIsReMat,
+                               CanDelete, vrm, RegMap, rc, ReMatIds, loopInfo,
+                               SpillMBBs, SpillIdxes, RestoreMBBs, RestoreIdxes,
+                               NewVRegs, NewLIs);
+  }
+
+  // Insert spills / restores if we are splitting.
+  if (TrySplit) {
+    if (NeedStackSlot) {
+      int Id = SpillMBBs.find_first();
+      while (Id != -1) {
+        unsigned VReg = NewVRegs[Id];
+        int index = SpillIdxes[Id].first;
+        bool DoFold = SpillIdxes[Id].second;
+        bool isReMat = vrm.isReMaterialized(VReg);
+        MachineInstr *MI = getInstructionFromIndex(index);
+        int OpIdx = -1;
+        bool FoldedLoad = false;
+        if (DoFold) {
+          for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) {
+            MachineOperand &MO = MI->getOperand(j);
+            if (!MO.isRegister() || MO.getReg() != VReg)
+              continue;
+            if (MO.isUse()) {
+              // Can't fold if it's two-address code and the use isn't the
+              // first and only use.
+              // If there are more than one uses, a load is still needed.
+              if (!isReMat && !FoldedLoad &&
+                  RestoreMBBs[Id] && RestoreIdxes[Id].first == index &&
+                  RestoreIdxes[Id].second) {
+                FoldedLoad = true;
+                continue;
+              } else {
+                OpIdx = -1;
+                break;
+              }
+            }
+            OpIdx = (int)j;
+          }
+        }
+        // Fold the store into the def if possible.
+        if (OpIdx == -1)
+          DoFold = false;
+        if (DoFold) {
+          if (tryFoldMemoryOperand(MI, vrm, NULL, index, OpIdx, true, Slot,
+                                   VReg)) {
+            if (FoldedLoad) {
+              // Folded a two-address instruction, do not issue a load.
+              RestoreMBBs.reset(Id);
+              RestoreIdxes.erase(Id);
+            }
+          } else
+            DoFold = false;
+        }
+
+        // Else tell the spiller to issue a store for us.
+        if (!DoFold)
+          vrm.addSpillPoint(VReg, MI);
+        Id = SpillMBBs.find_next(Id);
+      }
+    }
 
-  // Insert spills if we are splitting.
-  if (TrySplit && NeedStackSlot) {
-    int Id = SpillMBBs.find_first();
+    int Id = RestoreMBBs.find_first();
     while (Id != -1) {
-      unsigned index = SpillIdxes[Id].first;
-      unsigned VReg = SpillIdxes[Id].second & ((1 << 31)-1);
-      bool TryFold = SpillIdxes[Id].second & (1 << 31);
+      unsigned VReg = NewVRegs[Id];
+      int index = RestoreIdxes[Id].first;
+      bool DoFold = RestoreIdxes[Id].second;
       MachineInstr *MI = getInstructionFromIndex(index);
       int OpIdx = -1;
-      if (TryFold) {
+      if (DoFold) {
         for (unsigned j = 0, ee = MI->getNumOperands(); j != ee; ++j) {
           MachineOperand &MO = MI->getOperand(j);
           if (!MO.isRegister() || MO.getReg() != VReg)
             continue;
-          if (MO.isUse()) {
+          if (MO.isDef()) {
             // Can't fold if it's two-address code.            
             OpIdx = -1;
             break;
           }
+          if (OpIdx != -1) {
+            // Multiple uses, do not fold!
+            OpIdx = -1;
+            break;
+          }
           OpIdx = (int)j;
         }
       }
-      // Fold the store into the def if possible.
-      if (OpIdx == -1 ||
-          !tryFoldMemoryOperand(MI, vrm, NULL, index, OpIdx, true, Slot, VReg))
-        // Else tell the spiller to issue a store for us.
-        vrm.addSpillPoint(VReg, MI);
-      Id = SpillMBBs.find_next(Id);
+
+      // Fold the load into the use if possible.
+      if (OpIdx == -1)
+        DoFold = false;
+      if (DoFold) {
+        if (vrm.isReMaterialized(VReg)) {
+          MachineInstr *ReMatDefMI = vrm.getReMaterializedMI(VReg);
+          int LdSlot = 0;
+          bool isLoadSS = tii_->isLoadFromStackSlot(ReMatDefMI, LdSlot);
+          // If the rematerializable def is a load, also try to fold it.
+          if (isLoadSS ||
+              (ReMatDefMI->getInstrDescriptor()->Flags & M_LOAD_FLAG))
+            DoFold = tryFoldMemoryOperand(MI, vrm, ReMatDefMI, index, OpIdx,
+                                          isLoadSS, LdSlot, VReg);
+          else
+            DoFold = false;
+        } else
+          DoFold = tryFoldMemoryOperand(MI, vrm, NULL, index, OpIdx,
+                                        true, Slot, VReg);
+      }
+      // If folding is not possible / failed, then tell the spiller to issue a
+      // load / rematerialization for us.
+      if (!DoFold)
+        vrm.addRestorePoint(VReg, MI);
+      Id = RestoreMBBs.find_next(Id);
     }
   }
 

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.cpp?rev=44428&r1=44427&r2=44428&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.cpp (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.cpp Wed Nov 28 19:06:25 2007
@@ -940,10 +940,6 @@
   // ReMatDefs - These are rematerializable def MIs which are not deleted.
   SmallSet<MachineInstr*, 4> ReMatDefs;
 
-  // ReloadedSplits - Splits must be reloaded once per MBB. This keeps track
-  // which have been reloaded.
-  SmallSet<unsigned, 8> ReloadedSplits;
-
   // Keep track of kill information.
   BitVector RegKills(MRI->getNumRegs());
   std::vector<MachineOperand*>  KillOps;
@@ -963,6 +959,31 @@
     MachineInstr &MI = *MII;
     const TargetInstrDescriptor *TID = MI.getInstrDescriptor();
 
+    // Insert restores here if asked to.
+    if (VRM.isRestorePt(&MI)) {
+      std::vector<unsigned> &RestoreRegs = VRM.getRestorePtRestores(&MI);
+      for (unsigned i = 0, e = RestoreRegs.size(); i != e; ++i) {
+        unsigned VirtReg = RestoreRegs[i];
+        if (!VRM.getPreSplitReg(VirtReg))
+          continue; // Split interval spilled again.
+        unsigned Phys = VRM.getPhys(VirtReg);
+        MF.setPhysRegUsed(Phys);
+        if (VRM.isReMaterialized(VirtReg)) {
+          MRI->reMaterialize(MBB, &MI, Phys,
+                             VRM.getReMaterializedMI(VirtReg));
+          ++NumReMats;
+        } else {
+          const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
+          MRI->loadRegFromStackSlot(MBB, &MI, Phys, VRM.getStackSlot(VirtReg), RC);
+          ++NumLoads;
+        }
+        // This invalidates Phys.
+        Spills.ClobberPhysReg(Phys);
+        UpdateKills(*prior(MII), RegKills, KillOps);
+        DOUT << '\t' << *prior(MII);
+      }
+    }
+
     // Insert spills here if asked to.
     if (VRM.isSpillPt(&MI)) {
       std::vector<unsigned> &SpillRegs = VRM.getSpillPtSpills(&MI);
@@ -1006,43 +1027,6 @@
         MF.setPhysRegUsed(Phys);
         if (MO.isDef())
           ReusedOperands.markClobbered(Phys);
-
-        // If it's a split live interval, insert a reload for the first use
-        // unless it's previously defined in the MBB.
-        unsigned SplitReg = VRM.getPreSplitReg(VirtReg);
-        if (SplitReg) {
-          if (ReloadedSplits.insert(VirtReg)) {
-            bool HasUse = MO.isUse();
-            // If it's a def, we don't need to reload the value unless it's
-            // a two-address code.
-            if (!HasUse) {
-              for (unsigned j = i+1; j != e; ++j) {
-                MachineOperand &MOJ = MI.getOperand(j);
-                if (MOJ.isRegister() && MOJ.getReg() == VirtReg) {
-                  HasUse = true;
-                  break;
-                }
-              }
-            }
-
-            if (HasUse) {
-              if (VRM.isReMaterialized(VirtReg)) {
-                MRI->reMaterialize(MBB, &MI, Phys,
-                                   VRM.getReMaterializedMI(VirtReg));
-                ++NumReMats;
-              } else {
-                const TargetRegisterClass* RC = RegMap->getRegClass(VirtReg);
-                MRI->loadRegFromStackSlot(MBB, &MI, Phys, VRM.getStackSlot(VirtReg), RC);
-                ++NumLoads;
-              }
-              // This invalidates Phys.
-              Spills.ClobberPhysReg(Phys);
-              UpdateKills(*prior(MII), RegKills, KillOps);
-              DOUT << '\t' << *prior(MII);
-            }
-          }
-        }
-
         unsigned RReg = SubIdx ? MRI->getSubReg(Phys, SubIdx) : Phys;
         MI.getOperand(i).setReg(RReg);
         continue;
@@ -1264,12 +1248,6 @@
       VirtRegMap::ModRef MR = I->second.second;
       DOUT << "Folded vreg: " << VirtReg << "  MR: " << MR;
 
-      // If this is a split live interval, remember we have seen this so
-      // we do not need to reload it for later uses.
-      unsigned SplitReg = VRM.getPreSplitReg(VirtReg);
-      if (SplitReg)
-        ReloadedSplits.insert(VirtReg);
-
       int SS = VRM.getStackSlot(VirtReg);
       if (SS == VirtRegMap::NO_STACK_SLOT)
         continue;

Modified: llvm/trunk/lib/CodeGen/VirtRegMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/VirtRegMap.h?rev=44428&r1=44427&r2=44428&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/VirtRegMap.h (original)
+++ llvm/trunk/lib/CodeGen/VirtRegMap.h Wed Nov 28 19:06:25 2007
@@ -82,6 +82,11 @@
     /// splitting.
     std::map<MachineInstr*, std::vector<unsigned> > SpillPt2VirtMap;
 
+    /// RestorePt2VirtMap - This records the virtual registers which should
+    /// be restored right before the MachineInstr due to live interval
+    /// splitting.
+    std::map<MachineInstr*, std::vector<unsigned> > RestorePt2VirtMap;
+
     /// ReMatId - Instead of assigning a stack slot to a to be rematerialized
     /// virtual register, an unique id is being assigned. This keeps track of
     /// the highest id used so far. Note, this starts at (1<<18) to avoid
@@ -239,6 +244,41 @@
       SpillPt2VirtMap.erase(I);
     }
 
+    /// @brief returns true if the specified MachineInstr is a restore point.
+    bool isRestorePt(MachineInstr *Pt) const {
+      return RestorePt2VirtMap.find(Pt) != RestorePt2VirtMap.end();
+    }
+
+    /// @brief returns the virtual registers that should be restoreed due to
+    /// splitting right after the specified MachineInstr.
+    std::vector<unsigned> &getRestorePtRestores(MachineInstr *Pt) {
+      return RestorePt2VirtMap[Pt];
+    }
+
+    /// @brief records the specified MachineInstr as a restore point for virtReg.
+    void addRestorePoint(unsigned virtReg, MachineInstr *Pt) {
+      if (RestorePt2VirtMap.find(Pt) != RestorePt2VirtMap.end())
+        RestorePt2VirtMap[Pt].push_back(virtReg);
+      else {
+        std::vector<unsigned> Virts;
+        Virts.push_back(virtReg);
+        RestorePt2VirtMap.insert(std::make_pair(Pt, Virts));
+      }
+    }
+
+    void transferRestorePts(MachineInstr *Old, MachineInstr *New) {
+      std::map<MachineInstr*,std::vector<unsigned> >::iterator I =
+        RestorePt2VirtMap.find(Old);
+      if (I == RestorePt2VirtMap.end())
+        return;
+      while (!I->second.empty()) {
+        unsigned virtReg = I->second.back();
+        I->second.pop_back();
+        addRestorePoint(virtReg, New);
+      }
+      RestorePt2VirtMap.erase(I);
+    }
+
     /// @brief Updates information about the specified virtual register's value
     /// folded into newMI machine instruction.  The OpNum argument indicates the
     /// operand number of OldMI that is folded.
@@ -261,6 +301,7 @@
     void RemoveMachineInstrFromMaps(MachineInstr *MI) {
       MI2VirtMap.erase(MI);
       SpillPt2VirtMap.erase(MI);
+      RestorePt2VirtMap.erase(MI);
     }
 
     void print(std::ostream &OS) const;





More information about the llvm-commits mailing list