//
// 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
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.
// 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...
/// 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;
/// 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;
}
/// 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;
}
/// 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;
}
/// 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
///
int CreateVariableSizedObject() {
HasVarSizedObjects = true;
- if (MaxAlignment < 1) MaxAlignment = 1;
Objects.push_back(StackObject(0, 1, -1));
return Objects.size()-NumFixedObjects-1;
}
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