Local spiller kills a store if the folded restore is turned into a copy.
authorEvan Cheng <evan.cheng@apple.com>
Sun, 30 Apr 2006 08:41:47 +0000 (08:41 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sun, 30 Apr 2006 08:41:47 +0000 (08:41 +0000)
But this is incorrect if the spilled value live range extends beyond the
current BB.
It is currently controlled by a temporary option -spiller-check-liveout.

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

lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/VirtRegMap.cpp
lib/CodeGen/VirtRegMap.h

index 125a18dd24ec7d44a18a86b1ca8f4deec612a4ae..c6dc2b92d44230b8257ee7c6e62feaecc381271c 100644 (file)
@@ -271,14 +271,15 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
             // can do this, we don't need to insert spill code.
             if (lv_)
               lv_->instructionChanged(MI, fmi);
-            vrm.virtFolded(li.reg, MI, i, fmi);
+            MachineBasicBlock &MBB = *MI->getParent();
+            bool LiveOut = li.liveAt(getInstructionIndex(&MBB.back()) +
+                                     InstrSlots::NUM);
+            vrm.virtFolded(li.reg, MI, i, fmi, LiveOut);
             mi2iMap_.erase(MI);
             i2miMap_[index/InstrSlots::NUM] = fmi;
             mi2iMap_[fmi] = index;
-            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;
index f0dd40d1e16aab15ca365f3edcc919c8fbb3a213..6122dc1bb499befcb767f4187ce518041d766678 100644 (file)
@@ -50,6 +50,10 @@ namespace {
                         clEnumVal(local,  "  local spiller"),
                         clEnumValEnd),
              cl::init(local));
+
+  // TEMPORARY option to test a fix.
+  cl::opt<bool>
+  SpillerCheckLiveOut("spiller-check-liveout", cl::Hidden);
 }
 
 //===----------------------------------------------------------------------===//
@@ -81,7 +85,8 @@ void VirtRegMap::assignVirt2StackSlot(unsigned virtReg, int frameIndex) {
 }
 
 void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI,
-                            unsigned OpNo, MachineInstr *NewMI) {
+                            unsigned OpNo, MachineInstr *NewMI,
+                            bool LiveOut) {
   // Move previous memory references folded to new instruction.
   MI2VirtMapTy::iterator IP = MI2VirtMap.lower_bound(NewMI);
   for (MI2VirtMapTy::iterator I = MI2VirtMap.lower_bound(OldMI),
@@ -96,6 +101,7 @@ void VirtRegMap::virtFolded(unsigned VirtReg, MachineInstr *OldMI,
     MRInfo = isRef;
   } else {
     MRInfo = OldMI->getOperand(OpNo).isUse() ? isModRef : isMod;
+    if (LiveOut) MRInfo = (ModRef)(MRInfo | isLiveOut);
   }
 
   // add new memory reference
@@ -727,10 +733,14 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) {
           MaybeDeadStores.erase(MDSI);
         else {
           // If we get here, the store is dead, nuke it now.
-          assert(MR == VirtRegMap::isMod && "Can't be modref!");
-          MBB.erase(MDSI->second);
-          MaybeDeadStores.erase(MDSI);
-          ++NumDSE;
+          assert(!(MR & VirtRegMap::isRef) && "Can't be modref!");
+          // Don't nuke it if the value is needed in another block.
+          if (!SpillerCheckLiveOut || !(MR & VirtRegMap::isLiveOut)) {
+            DEBUG(std::cerr << " Killed store:\t" << *MDSI->second);
+            MBB.erase(MDSI->second);
+            MaybeDeadStores.erase(MDSI);
+            ++NumDSE;
+          }
         }
       }
 
index d8c371c6dd01d425902cd933bcdd0ccbab927374..343a4e066aa18c95e36e24ee1164fcb739bd7861 100644 (file)
@@ -26,7 +26,7 @@ namespace llvm {
 
   class VirtRegMap {
   public:
-    enum ModRef { isRef = 1, isMod = 2, isModRef = 3 };
+    enum ModRef { isRef = 1, isMod = 2, isModRef = 3, isLiveOut = 4 };
     typedef std::multimap<MachineInstr*,
                           std::pair<unsigned, ModRef> > MI2VirtMapTy;
 
@@ -128,7 +128,7 @@ namespace llvm {
     /// folded into newMI machine instruction.  The OpNum argument indicates the
     /// operand number of OldMI that is folded.
     void virtFolded(unsigned VirtReg, MachineInstr *OldMI, unsigned OpNum,
-                    MachineInstr *NewMI);
+                    MachineInstr *NewMI, bool LiveOut);
 
     /// @brief returns the virtual registers' values folded in memory
     /// operands of this instruction