It's better to have the arrays, which would trigger the creation of stack
authorBill Wendling <isanbard@gmail.com>
Tue, 27 Jul 2010 01:55:19 +0000 (01:55 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 27 Jul 2010 01:55:19 +0000 (01:55 +0000)
protectors, to be near the stack protectors on the stack. Accomplish this by
tagging the stack object with a predicate that indicates that it would trigger
this. In the prolog-epilog inserter, assign these objects to the stack after the
stack protector but before the other objects.

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

include/llvm/CodeGen/MachineFrameInfo.h
lib/CodeGen/MachineFunction.cpp
lib/CodeGen/PrologEpilogInserter.cpp
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp

index 57f3b6a0a9f902a298528bbdde8ad30323d66e63..03ff6af3cc3b300adb130c4dd2dc4d907ec33f7a 100644 (file)
@@ -94,13 +94,19 @@ class MachineFrameInfo {
     // default, fixed objects are immutable unless marked otherwise.
     bool isImmutable;
 
-    // isSpillSlot - If true, the stack object is used as spill slot. It
+    // isSpillSlot - If true the stack object is used as spill slot. It
     // cannot alias any other memory objects.
     bool isSpillSlot;
 
-    StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS)
+    // MayNeedSP - If true the stack object triggered the creation of the stack
+    // protector. We should allocate this object right after the stack
+    // protector.
+    bool MayNeedSP;
+
+    StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
+                bool isSS, bool NSP)
       : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
-        isSpillSlot(isSS) {}
+        isSpillSlot(isSS), MayNeedSP(NSP) {}
   };
 
   /// Objects - The list of stack objects allocated...
@@ -276,6 +282,14 @@ public:
     MaxAlignment = std::max(MaxAlignment, Align);
   }
 
+  /// NeedsStackProtector - Returns true if the object may need stack
+  /// protectors.
+  bool MayNeedStackProtector(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].MayNeedSP;
+  }
+
   /// getObjectOffset - Return the assigned stack offset of the specified object
   /// from the incoming stack pointer.
   ///
@@ -382,25 +396,26 @@ public:
     return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
   }
 
-  /// CreateStackObject - Create a new statically sized stack object,
-  /// returning a nonnegative identifier to represent it.
+  /// CreateStackObject - Create a new statically sized stack object, returning
+  /// a nonnegative identifier to represent it.
   ///
-  int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS) {
+  int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
+                        bool MayNeedSP = false) {
     assert(Size != 0 && "Cannot allocate zero size stack objects!");
-    Objects.push_back(StackObject(Size, Alignment, 0, false, isSS));
-    int Index = (int)Objects.size()-NumFixedObjects-1;
+    Objects.push_back(StackObject(Size, Alignment, 0, false, isSS, MayNeedSP));
+    int Index = (int)Objects.size() - NumFixedObjects - 1;
     assert(Index >= 0 && "Bad frame index!");
     MaxAlignment = std::max(MaxAlignment, Alignment);
     return Index;
   }
 
-  /// CreateSpillStackObject - Create a new statically sized stack
-  /// object that represents a spill slot, returning a nonnegative
-  /// identifier to represent it.
+  /// CreateSpillStackObject - Create a new statically sized stack object that
+  /// represents a spill slot, returning a nonnegative identifier to represent
+  /// it.
   ///
   int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
-    CreateStackObject(Size, Alignment, true);
-    int Index = (int)Objects.size()-NumFixedObjects-1;
+    CreateStackObject(Size, Alignment, true, false);
+    int Index = (int)Objects.size() - NumFixedObjects - 1;
     MaxAlignment = std::max(MaxAlignment, Alignment);
     return Index;
   }
@@ -419,7 +434,7 @@ public:
   ///
   int CreateVariableSizedObject(unsigned Alignment) {
     HasVarSizedObjects = true;
-    Objects.push_back(StackObject(0, Alignment, 0, false, false));
+    Objects.push_back(StackObject(0, Alignment, 0, false, false, true));
     MaxAlignment = std::max(MaxAlignment, Alignment);
     return (int)Objects.size()-NumFixedObjects-1;
   }
index 9a52b7b0b411252bbcfff1c9b8ec3f66024207e5..017170076cebb9e2a64bb3174925987af48b5690 100644 (file)
@@ -446,7 +446,7 @@ int MachineFrameInfo::CreateFixedObject(uint64_t Size, int64_t SPOffset,
   unsigned StackAlign = TFI.getStackAlignment();
   unsigned Align = MinAlign(SPOffset, StackAlign);
   Objects.insert(Objects.begin(), StackObject(Size, Align, SPOffset, Immutable,
-                                              /*isSS*/false));
+                                              /*isSS*/false, false));
   return -++NumFixedObjects;
 }
 
index 3787d0b7bedc838b8173987e983333a2cdac16a3..827b6a30ad5a90a71d63f18d3530419223350135 100644 (file)
@@ -33,6 +33,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include <climits>
 
@@ -549,10 +550,29 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
 
   // Make sure that the stack protector comes before the local variables on the
   // stack.
-  if (MFI->getStackProtectorIndex() >= 0)
+  SmallSet<int, 16> LargeStackObjs;
+  if (MFI->getStackProtectorIndex() >= 0) {
     AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
                       Offset, MaxAlign);
 
+    // Assign large stack objects first.
+    for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
+      if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
+        continue;
+      if (RS && (int)i == RS->getScavengingFrameIndex())
+        continue;
+      if (MFI->isDeadObjectIndex(i))
+        continue;
+      if (MFI->getStackProtectorIndex() == (int)i)
+        continue;
+      if (!MFI->MayNeedStackProtector(i))
+        continue;
+
+      AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
+      LargeStackObjs.insert(i);
+    }
+  }
+
   // Then assign frame offsets to stack objects that are not used to spill
   // callee saved registers.
   for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
@@ -564,6 +584,8 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
       continue;
     if (MFI->getStackProtectorIndex() == (int)i)
       continue;
+    if (LargeStackObjs.count(i))
+      continue;
 
     AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
   }
index ee3bc0abbcffba47012226280a67821b12432387..77a2c866966376df8fe94ee6378edbd5eaa96d85 100644 (file)
@@ -112,8 +112,16 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) {
 
         TySize *= CUI->getZExtValue();   // Get total allocated size.
         if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
+
+        // The object may need to be placed onto the stack near the stack
+        // protector if one exists. Determine here if this object is a suitable
+        // candidate. I.e., it would trigger the creation of a stack protector.
+        bool MayNeedSP =
+          (AI->isArrayAllocation() ||
+           (TySize > 8 && isa<ArrayType>(Ty) &&
+            cast<ArrayType>(Ty)->getElementType()->isIntegerTy(8)));
         StaticAllocaMap[AI] =
-          MF->getFrameInfo()->CreateStackObject(TySize, Align, false);
+          MF->getFrameInfo()->CreateStackObject(TySize, Align, false, MayNeedSP);
       }
 
   for (; BB != EB; ++BB)