[llvm-commits] CVS: llvm/lib/CodeGen/PrologEpilogInserter.cpp RegisterScavenging.cpp

Evan Cheng evan.cheng at apple.com
Tue May 1 02:02:00 PDT 2007



Changes in directory llvm/lib/CodeGen:

PrologEpilogInserter.cpp updated: 1.83 -> 1.84
RegisterScavenging.cpp updated: 1.16 -> 1.17
---
Log message:

If call frame is not part of stack frame and no dynamic alloc, eliminateFrameIndex() must adjust SP offset with size of call frames.

---
Diffs of the changes:  (+49 -18)

 PrologEpilogInserter.cpp |   58 +++++++++++++++++++++++++++++++++++------------
 RegisterScavenging.cpp   |    9 ++++---
 2 files changed, 49 insertions(+), 18 deletions(-)


Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
diff -u llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.83 llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.84
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp:1.83	Mon Apr 30 19:51:28 2007
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp	Tue May  1 04:01:42 2007
@@ -26,6 +26,7 @@
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/ADT/STLExtras.h"
 #include <climits>
 using namespace llvm;
 
@@ -151,9 +152,14 @@
   MachineFrameInfo *FFI = Fn.getFrameInfo();
   FFI->setHasCalls(HasCalls);
   FFI->setMaxCallFrameSize(MaxCallFrameSize);
+
   for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) {
     MachineBasicBlock::iterator I = FrameSDOps[i];
-    RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
+    // If call frames are not being included as part of the stack frame,
+    // and there is no dynamic allocation (therefore referencing frame slots
+    // off sp), leave the pseudo ops alone. We'll eliminate them later.
+    if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn))
+      RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
   }
 
   // Now figure out which *callee saved* registers are modified by the current
@@ -491,25 +497,49 @@
   const TargetMachine &TM = Fn.getTarget();
   assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
   const MRegisterInfo &MRI = *TM.getRegisterInfo();
+  const TargetFrameInfo *TFI = TM.getFrameInfo();
+  bool StackGrowsDown =
+    TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
+  int FrameSetupOpcode   = MRI.getCallFrameSetupOpcode();
+  int FrameDestroyOpcode = MRI.getCallFrameDestroyOpcode();
 
   for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+    int SPAdj = 0;  // SP offset due to call frame setup / destroy.
     if (RS) RS->enterBasicBlock(BB);
     for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
-      MachineInstr *MI = I++;
-      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
-        if (MI->getOperand(i).isFrameIndex()) {
-          // If this instruction has a FrameIndex operand, we need to use that
-          // target machine register info object to eliminate it.
-          MRI.eliminateFrameIndex(MI, RS);
-
-          // Revisit the instruction in full.  Some instructions (e.g. inline
-          // asm instructions) can have multiple frame indices.
-          --I;
-          MI = 0;
-          break;
-        }
+      MachineInstr *MI = I;
+
+      // Remember how much SP has been adjustment to create the call frame.
+      if (I->getOpcode() == FrameSetupOpcode ||
+          I->getOpcode() == FrameDestroyOpcode) {
+        int Size = I->getOperand(0).getImmedValue();
+        if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
+            (StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
+          Size = -Size;
+        SPAdj += Size;
+        MachineBasicBlock::iterator PrevI = prior(I);
+        MRI.eliminateCallFramePseudoInstr(Fn, *BB, I);
+        // Visit the instructions created by eliminateCallFramePseudoInstr().
+        I = next(PrevI);
+        MI = NULL;
+      } else {
+        I++;
+        for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
+          if (MI->getOperand(i).isFrameIndex()) {
+            // If this instruction has a FrameIndex operand, we need to use that
+            // target machine register info object to eliminate it.
+            MRI.eliminateFrameIndex(MI, SPAdj, RS);
+
+            // Revisit the instruction in full.  Some instructions (e.g. inline
+            // asm instructions) can have multiple frame indices.
+            --I;
+            MI = 0;
+            break;
+          }
+      }
       // Update register states.
       if (RS && MI) RS->forward(MI);
     }
+    assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?");
   }
 }


Index: llvm/lib/CodeGen/RegisterScavenging.cpp
diff -u llvm/lib/CodeGen/RegisterScavenging.cpp:1.16 llvm/lib/CodeGen/RegisterScavenging.cpp:1.17
--- llvm/lib/CodeGen/RegisterScavenging.cpp:1.16	Thu Apr 26 13:59:33 2007
+++ llvm/lib/CodeGen/RegisterScavenging.cpp	Tue May  1 04:01:42 2007
@@ -75,7 +75,7 @@
   RegInfo->loadRegFromStackSlot(*MBB, MBBI, ScavengedReg,
                                 ScavengingFrameIndex, ScavengedRC);
   MachineBasicBlock::iterator II = prior(MBBI);
-  RegInfo->eliminateFrameIndex(II, this);
+  RegInfo->eliminateFrameIndex(II, 0, this);
   setUsed(ScavengedReg);
   ScavengedReg = 0;
   ScavengedRC = NULL;
@@ -243,7 +243,8 @@
 }
 
 unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
-                                        MachineBasicBlock::iterator I) {
+                                        MachineBasicBlock::iterator I,
+                                        int SPAdj) {
   assert(ScavengingFrameIndex >= 0 &&
          "Cannot scavenge a register without an emergency spill slot!");
 
@@ -277,12 +278,12 @@
     RegInfo->loadRegFromStackSlot(*MBB, I, ScavengedReg,
                                   ScavengingFrameIndex, ScavengedRC);
     MachineBasicBlock::iterator II = prior(I);
-    RegInfo->eliminateFrameIndex(II, this);
+    RegInfo->eliminateFrameIndex(II, SPAdj, this);
   }
 
   RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC);
   MachineBasicBlock::iterator II = prior(I);
-  RegInfo->eliminateFrameIndex(II, this);
+  RegInfo->eliminateFrameIndex(II, SPAdj, this);
   ScavengedReg = SReg;
   ScavengedRC = RC;
 






More information about the llvm-commits mailing list