LLVM API Documentation
00001 //===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // The MachineFrameInfo class represents an abstract stack frame until 00011 // prolog/epilog code is inserted. This class is key to allowing stack frame 00012 // representation optimizations, such as frame pointer elimination. It also 00013 // allows more mundane (but still important) optimizations, such as reordering 00014 // of abstract objects on the stack frame. 00015 // 00016 // To support this, the class assigns unique integer identifiers to stack 00017 // objects requested clients. These identifiers are negative integers for fixed 00018 // stack objects (such as arguments passed on the stack) or positive for objects 00019 // that may be reordered. Instructions which refer to stack objects use a 00020 // special MO_FrameIndex operand to represent these frame indexes. 00021 // 00022 // Because this class keeps track of all references to the stack frame, it knows 00023 // when a variable sized object is allocated on the stack. This is the sole 00024 // condition which prevents frame pointer elimination, which is an important 00025 // optimization on register-poor architectures. Because original variable sized 00026 // alloca's in the source program are the only source of variable sized stack 00027 // objects, it is safe to decide whether there will be any variable sized 00028 // objects before all stack objects are known (for example, register allocator 00029 // spill code never needs variable sized objects). 00030 // 00031 // When prolog/epilog code emission is performed, the final stack frame is built 00032 // and the machine instructions are modified to refer to the actual stack 00033 // offsets of the object, eliminating all MO_FrameIndex operands from the 00034 // program. 00035 // 00036 //===----------------------------------------------------------------------===// 00037 00038 #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H 00039 #define LLVM_CODEGEN_MACHINEFRAMEINFO_H 00040 00041 #include <vector> 00042 00043 namespace llvm { 00044 class TargetData; 00045 class TargetRegisterClass; 00046 class Type; 00047 class MachineFunction; 00048 00049 class MachineFrameInfo { 00050 00051 // StackObject - Represent a single object allocated on the stack. 00052 struct StackObject { 00053 // The size of this object on the stack. 0 means a variable sized object 00054 unsigned Size; 00055 00056 // Alignment - The required alignment of this stack slot. 00057 unsigned Alignment; 00058 00059 // SPOffset - The offset of this object from the stack pointer on entry to 00060 // the function. This field has no meaning for a variable sized element. 00061 int SPOffset; 00062 00063 StackObject(unsigned Sz, unsigned Al, int SP) 00064 : Size(Sz), Alignment(Al), SPOffset(SP) {} 00065 }; 00066 00067 /// Objects - The list of stack objects allocated... 00068 /// 00069 std::vector<StackObject> Objects; 00070 00071 /// NumFixedObjects - This contains the number of fixed objects contained on 00072 /// the stack. Because fixed objects are stored at a negative index in the 00073 /// Objects list, this is also the index to the 0th object in the list. 00074 /// 00075 unsigned NumFixedObjects; 00076 00077 /// HasVarSizedObjects - This boolean keeps track of whether any variable 00078 /// sized objects have been allocated yet. 00079 /// 00080 bool HasVarSizedObjects; 00081 00082 /// StackSize - The prolog/epilog code inserter calculates the final stack 00083 /// offsets for all of the fixed size objects, updating the Objects list 00084 /// above. It then updates StackSize to contain the number of bytes that need 00085 /// to be allocated on entry to the function. 00086 /// 00087 unsigned StackSize; 00088 00089 /// HasCalls - Set to true if this function has any function calls. This is 00090 /// only valid during and after prolog/epilog code insertion. 00091 bool HasCalls; 00092 00093 /// MaxCallFrameSize - This contains the size of the largest call frame if the 00094 /// target uses frame setup/destroy pseudo instructions (as defined in the 00095 /// TargetFrameInfo class). This information is important for frame pointer 00096 /// elimination. If is only valid during and after prolog/epilog code 00097 /// insertion. 00098 /// 00099 unsigned MaxCallFrameSize; 00100 public: 00101 MachineFrameInfo() { 00102 NumFixedObjects = StackSize = 0; 00103 HasVarSizedObjects = false; 00104 HasCalls = false; 00105 MaxCallFrameSize = 0; 00106 } 00107 00108 /// hasStackObjects - Return true if there are any stack objects in this 00109 /// function. 00110 /// 00111 bool hasStackObjects() const { return !Objects.empty(); } 00112 00113 /// hasVarSizedObjects - This method may be called any time after instruction 00114 /// selection is complete to determine if the stack frame for this function 00115 /// contains any variable sized objects. 00116 /// 00117 bool hasVarSizedObjects() const { return HasVarSizedObjects; } 00118 00119 /// getObjectIndexBegin - Return the minimum frame object index... 00120 /// 00121 int getObjectIndexBegin() const { return -NumFixedObjects; } 00122 00123 /// getObjectIndexEnd - Return one past the maximum frame object index... 00124 /// 00125 int getObjectIndexEnd() const { return Objects.size()-NumFixedObjects; } 00126 00127 /// getObjectSize - Return the size of the specified object 00128 /// 00129 int getObjectSize(int ObjectIdx) const { 00130 assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!"); 00131 return Objects[ObjectIdx+NumFixedObjects].Size; 00132 } 00133 00134 /// getObjectAlignment - Return the alignment of the specified stack object... 00135 int getObjectAlignment(int ObjectIdx) const { 00136 assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!"); 00137 return Objects[ObjectIdx+NumFixedObjects].Alignment; 00138 } 00139 00140 /// getObjectOffset - Return the assigned stack offset of the specified object 00141 /// from the incoming stack pointer. 00142 /// 00143 int getObjectOffset(int ObjectIdx) const { 00144 assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!"); 00145 return Objects[ObjectIdx+NumFixedObjects].SPOffset; 00146 } 00147 00148 /// setObjectOffset - Set the stack frame offset of the specified object. The 00149 /// offset is relative to the stack pointer on entry to the function. 00150 /// 00151 void setObjectOffset(int ObjectIdx, int SPOffset) { 00152 assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!"); 00153 Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset; 00154 } 00155 00156 /// getStackSize - Return the number of bytes that must be allocated to hold 00157 /// all of the fixed size frame objects. This is only valid after 00158 /// Prolog/Epilog code insertion has finalized the stack frame layout. 00159 /// 00160 unsigned getStackSize() const { return StackSize; } 00161 00162 /// setStackSize - Set the size of the stack... 00163 /// 00164 void setStackSize(unsigned Size) { StackSize = Size; } 00165 00166 /// hasCalls - Return true if the current function has no function calls. 00167 /// This is only valid during or after prolog/epilog code emission. 00168 /// 00169 bool hasCalls() const { return HasCalls; } 00170 void setHasCalls(bool V) { HasCalls = V; } 00171 00172 /// getMaxCallFrameSize - Return the maximum size of a call frame that must be 00173 /// allocated for an outgoing function call. This is only available if 00174 /// CallFrameSetup/Destroy pseudo instructions are used by the target, and 00175 /// then only during or after prolog/epilog code insertion. 00176 /// 00177 unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; } 00178 void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; } 00179 00180 /// CreateFixedObject - Create a new object at a fixed location on the stack. 00181 /// All fixed objects should be created before other objects are created for 00182 /// efficiency. This returns an index with a negative value. 00183 /// 00184 int CreateFixedObject(unsigned Size, int SPOffset) { 00185 assert(Size != 0 && "Cannot allocate zero size fixed stack objects!"); 00186 Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset)); 00187 return -++NumFixedObjects; 00188 } 00189 00190 /// CreateStackObject - Create a new statically sized stack object, returning 00191 /// a postive identifier to represent it. 00192 /// 00193 int CreateStackObject(unsigned Size, unsigned Alignment) { 00194 assert(Size != 0 && "Cannot allocate zero size stack objects!"); 00195 Objects.push_back(StackObject(Size, Alignment, -1)); 00196 return Objects.size()-NumFixedObjects-1; 00197 } 00198 00199 /// CreateStackObject - Create a stack object for a value of the specified 00200 /// LLVM type. 00201 /// 00202 int CreateStackObject(const Type *Ty, const TargetData &TD); 00203 00204 /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a 00205 /// variable sized object has been created. This must be created whenever a 00206 /// variable sized object is created, whether or not the index returned is 00207 /// actually used. 00208 /// 00209 int CreateVariableSizedObject() { 00210 HasVarSizedObjects = true; 00211 Objects.push_back(StackObject(0, 1, -1)); 00212 return Objects.size()-NumFixedObjects-1; 00213 } 00214 00215 /// print - Used by the MachineFunction printer to print information about 00216 /// stack objects. Implemented in MachineFunction.cpp 00217 /// 00218 void print(const MachineFunction &MF, std::ostream &OS) const; 00219 00220 /// dump - Call print(MF, std::cerr) to be called from the debugger. 00221 void dump(const MachineFunction &MF) const; 00222 }; 00223 00224 } // End llvm namespace 00225 00226 #endif