Don't track max alignment during stack object allocations since they can be deleted...
[oota-llvm.git] / include / llvm / CodeGen / MachineFrameInfo.h
index be481f7ab8271c2300fa8cd7e5e67fe1a87a4a40..4be3bd474e0c418e7a669e6e03006294c1680273 100644 (file)
@@ -2,11 +2,14 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The file defines the MachineFrameInfo class.
 //
 //===----------------------------------------------------------------------===//
-
 
 #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
 #define LLVM_CODEGEN_MACHINEFRAMEINFO_H
@@ -19,6 +22,7 @@ class TargetRegisterClass;
 class Type;
 class MachineModuleInfo;
 class MachineFunction;
+class TargetFrameInfo;
 
 /// The CalleeSavedInfo class tracks the information need to locate where a
 /// callee saved register in the current frame.  
@@ -76,18 +80,24 @@ class MachineFrameInfo {
 
   // StackObject - Represent a single object allocated on the stack.
   struct StackObject {
-    // The size of this object on the stack. 0 means a variable sized object
+    // The size of this object on the stack. 0 means a variable sized object,
+    // ~0ULL means a dead object.
     uint64_t Size;
 
     // Alignment - The required alignment of this stack slot.
     unsigned Alignment;
 
+    // isImmutable - If true, the value of the stack object is set before
+    // entering the function and is not modified inside the function. By
+    // default, fixed objects are immutable unless marked otherwise.
+    bool isImmutable;
+
     // SPOffset - The offset of this object from the stack pointer on entry to
     // the function.  This field has no meaning for a variable sized element.
     int64_t SPOffset;
-
-    StackObject(uint64_t Sz, unsigned Al, int64_t SP)
-      : Size(Sz), Alignment(Al), SPOffset(SP) {}
+    
+    StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM = false)
+      : Size(Sz), Alignment(Al), isImmutable(IM), SPOffset(SP) {}
   };
 
   /// Objects - The list of stack objects allocated...
@@ -150,12 +160,15 @@ class MachineFrameInfo {
   /// MMI - This field is set (via setMachineModuleInfo) by a module info
   /// consumer (ex. DwarfWriter) to indicate that frame layout information
   /// should be acquired.  Typically, it's the responsibility of the target's
-  /// MRegisterInfo prologue/epilogue emitting code to inform MachineModuleInfo
-  /// of frame layouts.
+  /// TargetRegisterInfo prologue/epilogue emitting code to inform
+  /// MachineModuleInfo of frame layouts.
   MachineModuleInfo *MMI;
   
+  /// TargetFrameInfo - Target information about frame layout.
+  ///
+  const TargetFrameInfo &TFI;
 public:
-  MachineFrameInfo() {
+  MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) {
     StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
     HasVarSizedObjects = false;
     HasCalls = false;
@@ -185,13 +198,15 @@ public:
   /// getObjectSize - Return the size of the specified object
   ///
   int64_t getObjectSize(int ObjectIdx) const {
-    assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
     return Objects[ObjectIdx+NumFixedObjects].Size;
   }
 
   /// getObjectAlignment - Return the alignment of the specified stack object...
   int getObjectAlignment(int ObjectIdx) const {
-    assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
     return Objects[ObjectIdx+NumFixedObjects].Alignment;
   }
 
@@ -199,7 +214,8 @@ public:
   /// from the incoming stack pointer.
   ///
   int64_t getObjectOffset(int ObjectIdx) const {
-    assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
     return Objects[ObjectIdx+NumFixedObjects].SPOffset;
   }
 
@@ -207,7 +223,8 @@ public:
   /// offset is relative to the stack pointer on entry to the function.
   ///
   void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
-    assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
     Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
   }
 
@@ -255,32 +272,55 @@ public:
 
   /// CreateFixedObject - Create a new object at a fixed location on the stack.
   /// All fixed objects should be created before other objects are created for
-  /// efficiency.  This returns an index with a negative value.
+  /// efficiency. By default, fixed objects are immutable. This returns an
+  /// index with a negative value.
   ///
-  int CreateFixedObject(uint64_t Size, int64_t SPOffset) {
-    assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
-    Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset));
-    return -++NumFixedObjects;
-  }
-
+  int CreateFixedObject(uint64_t Size, int64_t SPOffset,
+                        bool Immutable = true);
+  
+  
   /// isFixedObjectIndex - Returns true if the specified index corresponds to a
   /// fixed stack object.
   bool isFixedObjectIndex(int ObjectIdx) const {
     return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
   }
 
+  /// isImmutableObjectIndex - Returns true if the specified index corresponds
+  /// to an immutable object.
+  bool isImmutableObjectIndex(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].isImmutable;
+  }
+
+  /// isDeadObjectIndex - Returns true if the specified index corresponds to
+  /// a dead object.
+  bool isDeadObjectIndex(int ObjectIdx) const {
+    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+           "Invalid Object Idx!");
+    return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
+  }
+
   /// CreateStackObject - Create a new statically sized stack object, returning
   /// a postive identifier to represent it.
   ///
   int CreateStackObject(uint64_t Size, unsigned Alignment) {
-    // Keep track of the maximum alignment.
-    if (MaxAlignment < Alignment) MaxAlignment = Alignment;
-    
     assert(Size != 0 && "Cannot allocate zero size stack objects!");
     Objects.push_back(StackObject(Size, Alignment, -1));
     return Objects.size()-NumFixedObjects-1;
   }
 
+  /// RemoveStackObject - Remove or mark dead a statically sized stack object.
+  ///
+  void RemoveStackObject(int ObjectIdx) {
+    if (ObjectIdx == (int)(Objects.size()-NumFixedObjects-1))
+      // Last object, simply pop it off the list.
+      Objects.pop_back();
+    else
+      // Mark it dead.
+      Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
+  }
+
   /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
   /// variable sized object has been created.  This must be created whenever a
   /// variable sized object is created, whether or not the index returned is
@@ -288,7 +328,6 @@ public:
   ///
   int CreateVariableSizedObject() {
     HasVarSizedObjects = true;
-    if (MaxAlignment < 1) MaxAlignment = 1;
     Objects.push_back(StackObject(0, 1, -1));
     return Objects.size()-NumFixedObjects-1;
   }
@@ -305,8 +344,8 @@ public:
     CSInfo = CSI;
   }
 
-  /// getMachineModuleInfo - Used by a prologue/epilogue emitter (MRegisterInfo)
-  /// to provide frame layout information. 
+  /// getMachineModuleInfo - Used by a prologue/epilogue
+  /// emitter (TargetRegisterInfo) to provide frame layout information. 
   MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
 
   /// setMachineModuleInfo - Used by a meta info consumer (DwarfWriter) to