[llvm-commits] [llvm] r111836 - in /llvm/trunk/lib/CodeGen: LocalStackSlotAllocation.cpp PrologEpilogInserter.cpp

Jim Grosbach grosbach at apple.com
Mon Aug 23 13:40:38 PDT 2010


Author: grosbach
Date: Mon Aug 23 15:40:38 2010
New Revision: 111836

URL: http://llvm.org/viewvc/llvm-project?rev=111836&view=rev
Log:
Better handling of local offsets for downwards growing stacks. This corrects
relative offsets when there are offsets encoded in the instructions and
simplifies final allocation in PEI. rdar://8277890

Modified:
    llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp

Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp?rev=111836&r1=111835&r2=111836&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp (original)
+++ llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Mon Aug 23 15:40:38 2010
@@ -46,7 +46,7 @@
     SmallVector<int64_t,16> LocalOffsets;
 
     void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, int64_t &Offset,
-                           unsigned &MaxAlign);
+                           bool StackGrowsDown, unsigned &MaxAlign);
     void calculateFrameObjectOffsets(MachineFunction &Fn);
     bool insertFrameReferenceRegisters(MachineFunction &Fn);
   public:
@@ -102,7 +102,12 @@
 /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
 void LocalStackSlotPass::AdjustStackOffset(MachineFrameInfo *MFI,
                                            int FrameIdx, int64_t &Offset,
+                                           bool StackGrowsDown,
                                            unsigned &MaxAlign) {
+  // If the stack grows down, add the object size to find the lowest address.
+  if (StackGrowsDown)
+    Offset += MFI->getObjectSize(FrameIdx);
+
   unsigned Align = MFI->getObjectAlignment(FrameIdx);
 
   // If the alignment of this object is greater than that of the stack, then
@@ -112,13 +117,16 @@
   // Adjust to alignment boundary.
   Offset = (Offset + Align - 1) / Align * Align;
 
+  int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;
   DEBUG(dbgs() << "Allocate FI(" << FrameIdx << ") to local offset "
-        << Offset << "\n");
+        << LocalOffset << "\n");
   // Keep the offset available for base register allocation
-  LocalOffsets[FrameIdx] = Offset;
+  LocalOffsets[FrameIdx] = LocalOffset;
   // And tell MFI about it for PEI to use later
-  MFI->mapLocalFrameObject(FrameIdx, Offset);
-  Offset += MFI->getObjectSize(FrameIdx);
+  MFI->mapLocalFrameObject(FrameIdx, LocalOffset);
+
+  if (!StackGrowsDown)
+    Offset += MFI->getObjectSize(FrameIdx);
 
   ++NumAllocations;
 }
@@ -129,6 +137,9 @@
 void LocalStackSlotPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
   // Loop over all of the stack objects, assigning sequential addresses...
   MachineFrameInfo *MFI = Fn.getFrameInfo();
+  const TargetFrameInfo &TFI = *Fn.getTarget().getFrameInfo();
+  bool StackGrowsDown =
+    TFI.getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
   int64_t Offset = 0;
   unsigned MaxAlign = 0;
 
@@ -136,7 +147,8 @@
   // stack.
   SmallSet<int, 16> LargeStackObjs;
   if (MFI->getStackProtectorIndex() >= 0) {
-    AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset, MaxAlign);
+    AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), Offset,
+                      StackGrowsDown, MaxAlign);
 
     // Assign large stack objects first.
     for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
@@ -147,7 +159,7 @@
       if (!MFI->MayNeedStackProtector(i))
         continue;
 
-      AdjustStackOffset(MFI, i, Offset, MaxAlign);
+      AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
       LargeStackObjs.insert(i);
     }
   }
@@ -162,7 +174,7 @@
     if (LargeStackObjs.count(i))
       continue;
 
-    AdjustStackOffset(MFI, i, Offset, MaxAlign);
+    AdjustStackOffset(MFI, i, Offset, StackGrowsDown, MaxAlign);
   }
 
   // Remember how big this blob of stack space is
@@ -173,8 +185,8 @@
 static inline bool
 lookupCandidateBaseReg(const SmallVector<std::pair<unsigned, int64_t>, 8> &Regs,
                        std::pair<unsigned, int64_t> &RegOffset,
+                       int64_t FrameSizeAdjust,
                        int64_t LocalFrameOffset,
-                       bool StackGrowsDown,
                        const MachineInstr *MI,
                        const TargetRegisterInfo *TRI) {
   unsigned e = Regs.size();
@@ -182,9 +194,7 @@
     RegOffset = Regs[i];
     // Check if the relative offset from the where the base register references
     // to the target address is in range for the instruction.
-    int64_t Offset = LocalFrameOffset - RegOffset.second;
-    if (StackGrowsDown)
-      Offset = -Offset;
+    int64_t Offset = FrameSizeAdjust + LocalFrameOffset - RegOffset.second;
     if (TRI->isFrameOffsetLegal(MI, Offset))
       return true;
   }
@@ -241,6 +251,8 @@
           if (TRI->needsFrameBaseReg(MI, i)) {
             unsigned BaseReg = 0;
             int64_t Offset = 0;
+            int64_t FrameSizeAdjust = StackGrowsDown ? MFI->getLocalFrameSize()
+              : 0;
 
             DEBUG(dbgs() << "  Replacing FI in: " << *MI);
 
@@ -251,15 +263,15 @@
             // register.
             std::pair<unsigned, int64_t> RegOffset;
             if (lookupCandidateBaseReg(BaseRegisters, RegOffset,
+                                       FrameSizeAdjust,
                                        LocalOffsets[FrameIdx],
-                                       StackGrowsDown, MI, TRI)) {
+                                       MI, TRI)) {
               DEBUG(dbgs() << "  Reusing base register " <<
                     RegOffset.first << "\n");
               // We found a register to reuse.
               BaseReg = RegOffset.first;
-              Offset = LocalOffsets[FrameIdx] - RegOffset.second;
-              if (StackGrowsDown)
-                Offset = -Offset;
+              Offset = FrameSizeAdjust + LocalOffsets[FrameIdx] -
+                RegOffset.second;
             } else {
               // No previously defined register was in range, so create a
               // new one.
@@ -280,9 +292,10 @@
               // applied twice.
               Offset = -InstrOffset;
 
+              int64_t BaseOffset = FrameSizeAdjust + LocalOffsets[FrameIdx] +
+                InstrOffset;
               BaseRegisters.push_back(
-                std::pair<unsigned, int64_t>(BaseReg,
-                                      LocalOffsets[FrameIdx] + InstrOffset));
+                std::pair<unsigned, int64_t>(BaseReg, BaseOffset));
               ++NumBaseRegisters;
               UsedBaseReg = true;
             }
@@ -295,7 +308,6 @@
 
             ++NumReplacements;
           }
-
         }
       }
     }

Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=111836&r1=111835&r2=111836&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Mon Aug 23 15:40:38 2010
@@ -572,16 +572,18 @@
 
     DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
 
-    // Allocate the local block
-    Offset += MFI->getLocalFrameSize();
-
     // Resolve offsets for objects in the local block.
     for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
       std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
-      int64_t FIOffset = MFI->getLocalFrameBaseOffset() + Entry.second;
-
-      AdjustStackOffset(MFI, Entry.first, StackGrowsDown, FIOffset, MaxAlign);
+      int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
+      DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
+            FIOffset << "]\n");
+      MFI->setObjectOffset(Entry.first, FIOffset);
     }
+    // Allocate the local block
+    Offset += MFI->getLocalFrameSize();
+
+    MaxAlign = std::max(Align, MaxAlign);
   }
 
   // Make sure that the stack protector comes before the local variables on the





More information about the llvm-commits mailing list