Resurrect some ancient code to add spill ranges without attempting folding, remat...
authorOwen Anderson <resistor@mac.com>
Mon, 18 Aug 2008 18:05:32 +0000 (18:05 +0000)
committerOwen Anderson <resistor@mac.com>
Mon, 18 Aug 2008 18:05:32 +0000 (18:05 +0000)
in so far as it compiles and, in theory, works, but does not take advantage of recent advancements.  For instance, it could be improved by using
MachineRegisterInfo::use_iterator.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54924 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp

index a94840e89621a39bdb4a9f16ddd2adbca854769f..d588190cc4365e5f4f422465bbb2bbd3016f7bac 100644 (file)
@@ -323,6 +323,13 @@ namespace llvm {
     addIntervalsForSpills(const LiveInterval& i,
                           const MachineLoopInfo *loopInfo, VirtRegMap& vrm,
                           float &SSWeight);
+    
+    /// addIntervalsForSpillsFast - Quickly create new intervals for spilled
+    /// defs / uses without remat or splitting.
+    std::vector<LiveInterval*>
+    addIntervalsForSpillsFast(const LiveInterval &li,
+                              const MachineLoopInfo *loopInfo,
+                              VirtRegMap &vrm, float& SSWeight);
 
     /// spillPhysRegAroundRegDefsUses - Spill the specified physical register
     /// around all defs and uses of the specified interval.
index d027a81e84412087671a7ab1850439666cabb566..8f721451d04dbb88526389b09690ae4d78758fe4 100644 (file)
@@ -1597,6 +1597,111 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
 }
 
 
+std::vector<LiveInterval*> LiveIntervals::
+addIntervalsForSpillsFast(const LiveInterval &li,
+                          const MachineLoopInfo *loopInfo,
+                          VirtRegMap &vrm, float& SSWeight) {
+  unsigned slot = vrm.assignVirt2StackSlot(li.reg);
+  
+  // since this is called after the analysis is done we don't know if
+  // LiveVariables is available
+  lv_ = getAnalysisToUpdate<LiveVariables>();
+
+  std::vector<LiveInterval*> added;
+
+  assert(li.weight != HUGE_VALF &&
+         "attempt to spill already spilled interval!");
+
+  DOUT << "\t\t\t\tadding intervals for spills for interval: ";
+  DEBUG(li.dump());
+  DOUT << '\n';
+
+  const TargetRegisterClass* rc = mri_->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;
+
+      MachineInstr *MI = getInstructionFromIndex(index);
+
+      for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
+        MachineOperand& mop = MI->getOperand(i);
+        if (mop.isRegister() && mop.getReg() == li.reg) {
+          // Create a new virtual register for the spill interval.
+          unsigned NewVReg = mri_->createVirtualRegister(rc);
+            
+          // Scan all of the operands of this instruction rewriting operands
+          // to use NewVReg instead of li.reg as appropriate.  We do this for
+          // two reasons:
+          //
+          //   1. If the instr reads the same spilled vreg multiple times, we
+          //      want to reuse the NewVReg.
+          //   2. If the instr is a two-addr instruction, we are required to
+          //      keep the src/dst regs pinned.
+          //
+          // Keep track of whether we replace a use and/or def so that we can
+          // create the spill interval with the appropriate range. 
+          mop.setReg(NewVReg);
+          
+          bool HasUse = mop.isUse();
+          bool HasDef = mop.isDef();
+          for (unsigned j = i+1, e = MI->getNumOperands(); j != e; ++j) {
+            if (MI->getOperand(j).isReg() &&
+                MI->getOperand(j).getReg() == li.reg) {
+              MI->getOperand(j).setReg(NewVReg);
+              HasUse |= MI->getOperand(j).isUse();
+              HasDef |= MI->getOperand(j).isDef();
+            }
+          }
+
+          // create a new register for this spill
+          vrm.grow();
+          vrm.assignVirt2StackSlot(NewVReg, slot);
+          LiveInterval &nI = getOrCreateInterval(NewVReg);
+          assert(nI.empty());
+
+          // the spill weight is now infinity as it
+          // cannot be spilled again
+          nI.weight = HUGE_VALF;
+
+          if (HasUse) {
+            LiveRange LR(getLoadIndex(index), getUseIndex(index),
+                         nI.getNextValue(~0U, 0, getVNInfoAllocator()));
+            DOUT << " +" << LR;
+            nI.addRange(LR);
+          }
+          if (HasDef) {
+            LiveRange LR(getDefIndex(index), getStoreIndex(index),
+                         nI.getNextValue(~0U, 0, getVNInfoAllocator()));
+            DOUT << " +" << LR;
+            nI.addRange(LR);
+          }
+          
+          added.push_back(&nI);
+
+          // update live variables if it is available
+          if (lv_)
+            lv_->addVirtualRegisterKilled(NewVReg, MI);
+          
+          DOUT << "\t\t\t\tadded new interval: ";
+          DEBUG(nI.dump());
+          DOUT << '\n';
+        }
+      }
+    }
+  }
+  
+  SSWeight = HUGE_VALF;
+
+  return added;
+}
+
 std::vector<LiveInterval*> LiveIntervals::
 addIntervalsForSpills(const LiveInterval &li,
                       const MachineLoopInfo *loopInfo, VirtRegMap &vrm,