mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Descriptor object used to manage abstract frame references
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5166 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1951c5b987
commit
7fd4040274
204
include/llvm/CodeGen/MachineFrameInfo.h
Normal file
204
include/llvm/CodeGen/MachineFrameInfo.h
Normal file
@ -0,0 +1,204 @@
|
||||
//===-- CodeGen/FunctionFrameInfo.h - Abstract Stack Frame Rep --*- C++ -*-===//
|
||||
//
|
||||
// The FunctionFrameInfo class represents an abstract stack frame until
|
||||
// prolog/epilog code is inserted. This class is key to allowing stack frame
|
||||
// representation optimizations, such as frame pointer elimination. It also
|
||||
// allows more mundane (but still important) optimizations, such as reordering
|
||||
// of abstract objects on the stack frame.
|
||||
//
|
||||
// To support this, the class assigns unique integer identifiers to stack
|
||||
// objects requested clients. These identifiers are negative integers for fixed
|
||||
// stack objects (such as arguments passed on the stack) or positive for objects
|
||||
// that may be reordered. Instructions which refer to stack objects use a
|
||||
// special MO_FrameIndex operand to represent these frame indexes.
|
||||
//
|
||||
// Because this class keeps track of all references to the stack frame, it knows
|
||||
// when a variable sized object is allocated on the stack. This is the sole
|
||||
// condition which prevents frame pointer elimination, which is an important
|
||||
// optimization on register-poor architectures. Because original variable sized
|
||||
// alloca's in the source program are the only source of variable sized stack
|
||||
// objects, it is safe to decide whether there will be any variable sized
|
||||
// objects before all stack objects are known (for example, register allocator
|
||||
// spill code never needs variable sized objects).
|
||||
//
|
||||
// When prolog/epilog code emission is performed, the final stack frame is built
|
||||
// and the machine instructions are modified to refer to the actual stack
|
||||
// offsets of the object, eliminating all MO_FrameIndex operands from the
|
||||
// program.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_FUNCTIONFRAMEINFO_H
|
||||
#define LLVM_CODEGEN_FUNCTIONFRAMEINFO_H
|
||||
|
||||
class FunctionFrameInfo {
|
||||
|
||||
// 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
|
||||
unsigned Size;
|
||||
|
||||
// Alignment - The required alignment of this stack slot.
|
||||
unsigned Alignment;
|
||||
|
||||
// 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.
|
||||
int SPOffset;
|
||||
|
||||
StackObject(unsigned Sz, unsigned Al, int SP)
|
||||
: Size(Sz), Alignment(Al), SPOffset(SP) {}
|
||||
};
|
||||
|
||||
/// Objects - The list of stack objects allocated...
|
||||
///
|
||||
std::vector<StackObject> Objects;
|
||||
|
||||
/// NumFixedObjects - This contains the number of fixed objects contained on
|
||||
/// the stack. Because fixed objects are stored at a negative index in the
|
||||
/// Objects list, this is also the index to the 0th object in the list.
|
||||
///
|
||||
unsigned NumFixedObjects;
|
||||
|
||||
/// HasVarSizedObjects - This boolean keeps track of whether any variable
|
||||
/// sized objects have been allocated yet.
|
||||
///
|
||||
bool HasVarSizedObjects;
|
||||
|
||||
/// StackSize - The prolog/epilog code inserter calculates the final stack
|
||||
/// offsets for all of the fixed size objects, updating the Objects list
|
||||
/// above. It then updates StackSize to contain the number of bytes that need
|
||||
/// to be allocated on entry to the function.
|
||||
///
|
||||
unsigned StackSize;
|
||||
|
||||
/// HasCalls - Set to true if this function has any function calls. This is
|
||||
/// only valid during and after prolog/epilog code insertion.
|
||||
bool HasCalls;
|
||||
|
||||
/// MaxCallFrameSize - This contains the size of the largest call frame if the
|
||||
/// target uses frame setup/destroy pseudo instructions (as defined in the
|
||||
/// TargetFrameInfo class). This information is important for frame pointer
|
||||
/// elimination. If is only valid during and after prolog/epilog code
|
||||
/// insertion.
|
||||
///
|
||||
unsigned MaxCallFrameSize;
|
||||
public:
|
||||
FunctionFrameInfo() {
|
||||
NumFixedObjects = StackSize = 0;
|
||||
HasVarSizedObjects = false;
|
||||
HasCalls = false;
|
||||
MaxCallFrameSize = 0;
|
||||
}
|
||||
|
||||
/// hasStackObjects - Return true if there are any stack objects in this
|
||||
/// function.
|
||||
///
|
||||
bool hasStackObjects() const { return !Objects.empty(); }
|
||||
|
||||
/// hasVarSizedObjects - This method may be called any time after instruction
|
||||
/// selection is complete to determine if the stack frame for this function
|
||||
/// contains any variable sized objects.
|
||||
///
|
||||
bool hasVarSizedObjects() const { return HasVarSizedObjects; }
|
||||
|
||||
/// getObjectIndexBegin - Return the minimum frame object index...
|
||||
///
|
||||
int getObjectIndexBegin() const { return -NumFixedObjects; }
|
||||
|
||||
/// getObjectIndexEnd - Return one past the maximum frame object index...
|
||||
///
|
||||
int getObjectIndexEnd() const { return Objects.size()-NumFixedObjects; }
|
||||
|
||||
/// getObjectSize - Return the size of the specified object
|
||||
///
|
||||
int getObjectSize(int ObjectIdx) const {
|
||||
assert(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!");
|
||||
return Objects[ObjectIdx+NumFixedObjects].Alignment;
|
||||
}
|
||||
|
||||
/// getObjectOffset - Return the assigned stack offset of the specified object
|
||||
/// from the incoming stack pointer.
|
||||
///
|
||||
int getObjectOffset(int ObjectIdx) const {
|
||||
assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
|
||||
return Objects[ObjectIdx+NumFixedObjects].SPOffset;
|
||||
}
|
||||
|
||||
/// setObjectOffset - Set the stack frame offset of the specified object. The
|
||||
/// offset is relative to the stack pointer on entry to the function.
|
||||
///
|
||||
void setObjectOffset(int ObjectIdx, int SPOffset) {
|
||||
assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
|
||||
Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
|
||||
}
|
||||
|
||||
/// getStackSize - Return the number of bytes that must be allocated to hold
|
||||
/// all of the fixed size frame objects. This is only valid after
|
||||
/// Prolog/Epilog code insertion has finalized the stack frame layout.
|
||||
///
|
||||
unsigned getStackSize() const { return StackSize; }
|
||||
|
||||
/// setStackSize - Set the size of the stack...
|
||||
///
|
||||
void setStackSize(unsigned Size) { StackSize = Size; }
|
||||
|
||||
/// hasCalls - Return true if the current function has no function calls.
|
||||
/// This is only valid during or after prolog/epilog code emission.
|
||||
///
|
||||
bool hasCalls() const { return HasCalls; }
|
||||
void setHasCalls(bool V) { HasCalls = V; }
|
||||
|
||||
/// getMaxCallFrameSize - Return the maximum size of a call frame that must be
|
||||
/// allocated for an outgoing function call. This is only available if
|
||||
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and
|
||||
/// then only during or after prolog/epilog code insertion.
|
||||
///
|
||||
unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
|
||||
void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
|
||||
|
||||
/// 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.
|
||||
///
|
||||
int CreateFixedObject(unsigned Size, int SPOffset) {
|
||||
assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
|
||||
Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset));
|
||||
return -++NumFixedObjects;
|
||||
}
|
||||
|
||||
/// CreateStackObject - Create a new statically sized stack object, returning
|
||||
/// a postive identifier to represent it.
|
||||
///
|
||||
int CreateStackObject(unsigned Size, unsigned Alignment) {
|
||||
assert(Size != 0 && "Cannot allocate zero size stack objects!");
|
||||
Objects.push_back(StackObject(Size, Alignment, -1));
|
||||
return Objects.size()-NumFixedObjects-1;
|
||||
}
|
||||
|
||||
/// CreateVariableSizedObject - Notify the FunctionFrameInfo 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
|
||||
/// actually used.
|
||||
///
|
||||
int CreateVariableSizedObject() {
|
||||
HasVarSizedObjects = true;
|
||||
Objects.push_back(StackObject(0, 1, -1));
|
||||
return Objects.size()-NumFixedObjects-1;
|
||||
}
|
||||
|
||||
/// print - Used by the MachineFunction printer to print information about
|
||||
/// stack objects. Implemented in MachineFunction.cpp
|
||||
///
|
||||
void print(std::ostream &OS) const;
|
||||
|
||||
/// dump - Call print(std::cerr) to be called from the debugger.
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user