[llvm-commits] [llvm] r63837 - /llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp

Owen Anderson resistor at mac.com
Wed Feb 4 21:58:41 PST 2009


Author: resistor
Date: Wed Feb  4 23:58:41 2009
New Revision: 63837

URL: http://llvm.org/viewvc/llvm-project?rev=63837&view=rev
Log:
Pre-alloc splitting needs to be more careful to avoid inserting spills/restores
between call frame setup/restore points.  Unfortunately, this regresses 
code size a bit, but at least it's correct now!

Modified:
    llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp

Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=63837&r1=63836&r2=63837&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original)
+++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Wed Feb  4 23:58:41 2009
@@ -228,28 +228,52 @@
       ++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))
+      // corresponding call frame setup/teardown.
+      if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+        bool reachedBarrier = false;
+        do {
+          if (MII == EndPt) {
+            reachedBarrier = true;
+            break;
+          }
+          ++MII;
+        } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode());
+        
+        if (reachedBarrier) break;
+      } else if (Gap) {
+        Pt = MII;
+        SpillIndex = Gap;
         break;
+      }
     } while (MII != EndPt);
   } else {
     MachineBasicBlock::iterator MII = MI;
     MachineBasicBlock::iterator EndPt = DefMI
       ? MachineBasicBlock::iterator(DefMI) : MBB->begin();
     
-    // 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)) {
+      
+      // We can't insert the spill between the barrier (a call), and its
+      // corresponding call frame setup.
+      if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+        --MII;
+        continue;
+      } if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+        bool reachedBarrier = false;
+        while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) {
+          --MII;
+          if (MII == EndPt) {
+            reachedBarrier = true;
+            break;
+          }
+        }
+        
+        if (reachedBarrier) break;
+        else continue;
+      } else if (LIs->hasGapBeforeInstr(Index)) {
         Pt = MII;
         SpillIndex = LIs->findGapBeforeInstr(Index, true);
       }
@@ -283,25 +307,32 @@
     do {
       unsigned Index = LIs->getInstructionIndex(MII);
       unsigned Gap = LIs->findGapBeforeInstr(Index);
-      if (Gap) {
-        Pt = MII;
-        RestoreIndex = Gap;
-        break;
       
       // 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))
+      if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+        bool reachedBarrier = false;
+        while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) {
+          --MII;
+          if (MII == EndPt) {
+            reachedBarrier = true;
+            break;
+          }
+        }
+        
+        if (reachedBarrier) break;
+        else continue;
+      } else if (Gap) {
+        Pt = MII;
+        RestoreIndex = Gap;
         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?
@@ -310,10 +341,29 @@
       if (Index > LastIdx)
         break;
       unsigned Gap = LIs->findGapBeforeInstr(Index);
-      if (Gap) {
+      
+      // We can't insert a restore between the barrier (a call) and its 
+      // corresponding call frame teardown.
+      if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+        ++MII;
+        continue;
+      } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+        bool reachedBarrier = false;
+        do {
+          if (MII == MBB->getFirstTerminator() || RefsInMBB.count(MII)) {
+            reachedBarrier = true;
+            break;
+          }
+          
+          ++MII;
+        } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode());
+        
+        if (reachedBarrier) break;
+      } else if (Gap) {
         Pt = MII;
         RestoreIndex = Gap;
       }
+      
       if (RefsInMBB.count(MII))
         break;
       ++MII;





More information about the llvm-commits mailing list