LLVM API Documentation
00001 //===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // The file defines the MachineFrameInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H 00015 #define LLVM_CODEGEN_MACHINEFRAMEINFO_H 00016 00017 #include "llvm/Support/DataTypes.h" 00018 #include <cassert> 00019 #include <iosfwd> 00020 #include <vector> 00021 00022 namespace llvm { 00023 class TargetData; 00024 class TargetRegisterClass; 00025 class Type; 00026 class MachineModuleInfo; 00027 class MachineFunction; 00028 class TargetFrameInfo; 00029 00030 /// The CalleeSavedInfo class tracks the information need to locate where a 00031 /// callee saved register in the current frame. 00032 class CalleeSavedInfo { 00033 00034 private: 00035 unsigned Reg; 00036 const TargetRegisterClass *RegClass; 00037 int FrameIdx; 00038 00039 public: 00040 CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0) 00041 : Reg(R) 00042 , RegClass(RC) 00043 , FrameIdx(FI) 00044 {} 00045 00046 // Accessors. 00047 unsigned getReg() const { return Reg; } 00048 const TargetRegisterClass *getRegClass() const { return RegClass; } 00049 int getFrameIdx() const { return FrameIdx; } 00050 void setFrameIdx(int FI) { FrameIdx = FI; } 00051 }; 00052 00053 /// The MachineFrameInfo class represents an abstract stack frame until 00054 /// prolog/epilog code is inserted. This class is key to allowing stack frame 00055 /// representation optimizations, such as frame pointer elimination. It also 00056 /// allows more mundane (but still important) optimizations, such as reordering 00057 /// of abstract objects on the stack frame. 00058 /// 00059 /// To support this, the class assigns unique integer identifiers to stack 00060 /// objects requested clients. These identifiers are negative integers for 00061 /// fixed stack objects (such as arguments passed on the stack) or nonnegative 00062 /// for objects that may be reordered. Instructions which refer to stack 00063 /// objects use a special MO_FrameIndex operand to represent these frame 00064 /// indexes. 00065 /// 00066 /// Because this class keeps track of all references to the stack frame, it 00067 /// knows when a variable sized object is allocated on the stack. This is the 00068 /// sole condition which prevents frame pointer elimination, which is an 00069 /// important optimization on register-poor architectures. Because original 00070 /// variable sized alloca's in the source program are the only source of 00071 /// variable sized stack objects, it is safe to decide whether there will be 00072 /// any variable sized objects before all stack objects are known (for 00073 /// example, register allocator spill code never needs variable sized 00074 /// objects). 00075 /// 00076 /// When prolog/epilog code emission is performed, the final stack frame is 00077 /// built and the machine instructions are modified to refer to the actual 00078 /// stack offsets of the object, eliminating all MO_FrameIndex operands from 00079 /// the program. 00080 /// 00081 /// @brief Abstract Stack Frame Information 00082 class MachineFrameInfo { 00083 00084 // StackObject - Represent a single object allocated on the stack. 00085 struct StackObject { 00086 // The size of this object on the stack. 0 means a variable sized object, 00087 // ~0ULL means a dead object. 00088 uint64_t Size; 00089 00090 // Alignment - The required alignment of this stack slot. 00091 unsigned Alignment; 00092 00093 // isImmutable - If true, the value of the stack object is set before 00094 // entering the function and is not modified inside the function. By 00095 // default, fixed objects are immutable unless marked otherwise. 00096 bool isImmutable; 00097 00098 // SPOffset - The offset of this object from the stack pointer on entry to 00099 // the function. This field has no meaning for a variable sized element. 00100 int64_t SPOffset; 00101 00102 StackObject(uint64_t Sz, unsigned Al, int64_t SP = 0, bool IM = false) 00103 : Size(Sz), Alignment(Al), isImmutable(IM), SPOffset(SP) {} 00104 }; 00105 00106 /// Objects - The list of stack objects allocated... 00107 /// 00108 std::vector<StackObject> Objects; 00109 00110 /// NumFixedObjects - This contains the number of fixed objects contained on 00111 /// the stack. Because fixed objects are stored at a negative index in the 00112 /// Objects list, this is also the index to the 0th object in the list. 00113 /// 00114 unsigned NumFixedObjects; 00115 00116 /// HasVarSizedObjects - This boolean keeps track of whether any variable 00117 /// sized objects have been allocated yet. 00118 /// 00119 bool HasVarSizedObjects; 00120 00121 /// FrameAddressTaken - This boolean keeps track of whether there is a call 00122 /// to builtin @llvm.frameaddress. 00123 bool FrameAddressTaken; 00124 00125 /// StackSize - The prolog/epilog code inserter calculates the final stack 00126 /// offsets for all of the fixed size objects, updating the Objects list 00127 /// above. It then updates StackSize to contain the number of bytes that need 00128 /// to be allocated on entry to the function. 00129 /// 00130 uint64_t StackSize; 00131 00132 /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to 00133 /// have the actual offset from the stack/frame pointer. The calculation is 00134 /// MFI->getObjectOffset(Index) + StackSize - TFI.getOffsetOfLocalArea() + 00135 /// OffsetAdjustment. If OffsetAdjustment is zero (default) then offsets are 00136 /// away from TOS. If OffsetAdjustment == StackSize then offsets are toward 00137 /// TOS. 00138 int OffsetAdjustment; 00139 00140 /// MaxAlignment - The prolog/epilog code inserter may process objects 00141 /// that require greater alignment than the default alignment the target 00142 /// provides. To handle this, MaxAlignment is set to the maximum alignment 00143 /// needed by the objects on the current frame. If this is greater than the 00144 /// native alignment maintained by the compiler, dynamic alignment code will 00145 /// be needed. 00146 /// 00147 unsigned MaxAlignment; 00148 00149 /// HasCalls - Set to true if this function has any function calls. This is 00150 /// only valid during and after prolog/epilog code insertion. 00151 bool HasCalls; 00152 00153 /// StackProtectorIdx - The frame index for the stack protector. 00154 int StackProtectorIdx; 00155 00156 /// MaxCallFrameSize - This contains the size of the largest call frame if the 00157 /// target uses frame setup/destroy pseudo instructions (as defined in the 00158 /// TargetFrameInfo class). This information is important for frame pointer 00159 /// elimination. If is only valid during and after prolog/epilog code 00160 /// insertion. 00161 /// 00162 unsigned MaxCallFrameSize; 00163 00164 /// CSInfo - The prolog/epilog code inserter fills in this vector with each 00165 /// callee saved register saved in the frame. Beyond its use by the prolog/ 00166 /// epilog code inserter, this data used for debug info and exception 00167 /// handling. 00168 std::vector<CalleeSavedInfo> CSInfo; 00169 00170 /// MMI - This field is set (via setMachineModuleInfo) by a module info 00171 /// consumer (ex. DwarfWriter) to indicate that frame layout information 00172 /// should be acquired. Typically, it's the responsibility of the target's 00173 /// TargetRegisterInfo prologue/epilogue emitting code to inform 00174 /// MachineModuleInfo of frame layouts. 00175 MachineModuleInfo *MMI; 00176 00177 /// TargetFrameInfo - Target information about frame layout. 00178 /// 00179 const TargetFrameInfo &TFI; 00180 public: 00181 explicit MachineFrameInfo(const TargetFrameInfo &tfi) : TFI(tfi) { 00182 StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0; 00183 HasVarSizedObjects = false; 00184 FrameAddressTaken = false; 00185 HasCalls = false; 00186 StackProtectorIdx = -1; 00187 MaxCallFrameSize = 0; 00188 MMI = 0; 00189 } 00190 00191 /// hasStackObjects - Return true if there are any stack objects in this 00192 /// function. 00193 /// 00194 bool hasStackObjects() const { return !Objects.empty(); } 00195 00196 /// hasVarSizedObjects - This method may be called any time after instruction 00197 /// selection is complete to determine if the stack frame for this function 00198 /// contains any variable sized objects. 00199 /// 00200 bool hasVarSizedObjects() const { return HasVarSizedObjects; } 00201 00202 /// getStackProtectorIndex/setStackProtectorIndex - Return the index for the 00203 /// stack protector object. 00204 /// 00205 int getStackProtectorIndex() const { return StackProtectorIdx; } 00206 void setStackProtectorIndex(int I) { StackProtectorIdx = I; } 00207 00208 /// isFrameAddressTaken - This method may be called any time after instruction 00209 /// selection is complete to determine if there is a call to 00210 /// @llvm.frameaddress in this function. 00211 bool isFrameAddressTaken() const { return FrameAddressTaken; } 00212 void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; } 00213 00214 /// getObjectIndexBegin - Return the minimum frame object index. 00215 /// 00216 int getObjectIndexBegin() const { return -NumFixedObjects; } 00217 00218 /// getObjectIndexEnd - Return one past the maximum frame object index. 00219 /// 00220 int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; } 00221 00222 /// getNumFixedObjects() - Return the number of fixed objects. 00223 unsigned getNumFixedObjects() const { return NumFixedObjects; } 00224 00225 /// getNumObjects() - Return the number of objects. 00226 /// 00227 unsigned getNumObjects() const { return Objects.size(); } 00228 00229 /// getObjectSize - Return the size of the specified object. 00230 /// 00231 int64_t getObjectSize(int ObjectIdx) const { 00232 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00233 "Invalid Object Idx!"); 00234 return Objects[ObjectIdx+NumFixedObjects].Size; 00235 } 00236 00237 /// setObjectSize - Change the size of the specified stack object. 00238 void setObjectSize(int ObjectIdx, int64_t Size) { 00239 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00240 "Invalid Object Idx!"); 00241 Objects[ObjectIdx+NumFixedObjects].Size = Size; 00242 } 00243 00244 /// getObjectAlignment - Return the alignment of the specified stack object. 00245 unsigned getObjectAlignment(int ObjectIdx) const { 00246 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00247 "Invalid Object Idx!"); 00248 return Objects[ObjectIdx+NumFixedObjects].Alignment; 00249 } 00250 00251 /// setObjectAlignment - Change the alignment of the specified stack object. 00252 void setObjectAlignment(int ObjectIdx, unsigned Align) { 00253 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00254 "Invalid Object Idx!"); 00255 Objects[ObjectIdx+NumFixedObjects].Alignment = Align; 00256 } 00257 00258 /// getObjectOffset - Return the assigned stack offset of the specified object 00259 /// from the incoming stack pointer. 00260 /// 00261 int64_t getObjectOffset(int ObjectIdx) const { 00262 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00263 "Invalid Object Idx!"); 00264 assert(!isDeadObjectIndex(ObjectIdx) && 00265 "Getting frame offset for a dead object?"); 00266 return Objects[ObjectIdx+NumFixedObjects].SPOffset; 00267 } 00268 00269 /// setObjectOffset - Set the stack frame offset of the specified object. The 00270 /// offset is relative to the stack pointer on entry to the function. 00271 /// 00272 void setObjectOffset(int ObjectIdx, int64_t SPOffset) { 00273 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00274 "Invalid Object Idx!"); 00275 assert(!isDeadObjectIndex(ObjectIdx) && 00276 "Setting frame offset for a dead object?"); 00277 Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset; 00278 } 00279 00280 /// getStackSize - Return the number of bytes that must be allocated to hold 00281 /// all of the fixed size frame objects. This is only valid after 00282 /// Prolog/Epilog code insertion has finalized the stack frame layout. 00283 /// 00284 uint64_t getStackSize() const { return StackSize; } 00285 00286 /// setStackSize - Set the size of the stack... 00287 /// 00288 void setStackSize(uint64_t Size) { StackSize = Size; } 00289 00290 /// getOffsetAdjustment - Return the correction for frame offsets. 00291 /// 00292 int getOffsetAdjustment() const { return OffsetAdjustment; } 00293 00294 /// setOffsetAdjustment - Set the correction for frame offsets. 00295 /// 00296 void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } 00297 00298 /// getMaxAlignment - Return the alignment in bytes that this function must be 00299 /// aligned to, which is greater than the default stack alignment provided by 00300 /// the target. 00301 /// 00302 unsigned getMaxAlignment() const { return MaxAlignment; } 00303 00304 /// setMaxAlignment - Set the preferred alignment. 00305 /// 00306 void setMaxAlignment(unsigned Align) { MaxAlignment = Align; } 00307 00308 /// hasCalls - Return true if the current function has no function calls. 00309 /// This is only valid during or after prolog/epilog code emission. 00310 /// 00311 bool hasCalls() const { return HasCalls; } 00312 void setHasCalls(bool V) { HasCalls = V; } 00313 00314 /// getMaxCallFrameSize - Return the maximum size of a call frame that must be 00315 /// allocated for an outgoing function call. This is only available if 00316 /// CallFrameSetup/Destroy pseudo instructions are used by the target, and 00317 /// then only during or after prolog/epilog code insertion. 00318 /// 00319 unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; } 00320 void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; } 00321 00322 /// CreateFixedObject - Create a new object at a fixed location on the stack. 00323 /// All fixed objects should be created before other objects are created for 00324 /// efficiency. By default, fixed objects are immutable. This returns an 00325 /// index with a negative value. 00326 /// 00327 int CreateFixedObject(uint64_t Size, int64_t SPOffset, 00328 bool Immutable = true); 00329 00330 00331 /// isFixedObjectIndex - Returns true if the specified index corresponds to a 00332 /// fixed stack object. 00333 bool isFixedObjectIndex(int ObjectIdx) const { 00334 return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects); 00335 } 00336 00337 /// isImmutableObjectIndex - Returns true if the specified index corresponds 00338 /// to an immutable object. 00339 bool isImmutableObjectIndex(int ObjectIdx) const { 00340 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00341 "Invalid Object Idx!"); 00342 return Objects[ObjectIdx+NumFixedObjects].isImmutable; 00343 } 00344 00345 /// isDeadObjectIndex - Returns true if the specified index corresponds to 00346 /// a dead object. 00347 bool isDeadObjectIndex(int ObjectIdx) const { 00348 assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 00349 "Invalid Object Idx!"); 00350 return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; 00351 } 00352 00353 /// CreateStackObject - Create a new statically sized stack object, returning 00354 /// a nonnegative identifier to represent it. 00355 /// 00356 int CreateStackObject(uint64_t Size, unsigned Alignment) { 00357 assert(Size != 0 && "Cannot allocate zero size stack objects!"); 00358 Objects.push_back(StackObject(Size, Alignment)); 00359 return (int)Objects.size()-NumFixedObjects-1; 00360 } 00361 00362 /// RemoveStackObject - Remove or mark dead a statically sized stack object. 00363 /// 00364 void RemoveStackObject(int ObjectIdx) { 00365 // Mark it dead. 00366 Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL; 00367 } 00368 00369 /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a 00370 /// variable sized object has been created. This must be created whenever a 00371 /// variable sized object is created, whether or not the index returned is 00372 /// actually used. 00373 /// 00374 int CreateVariableSizedObject() { 00375 HasVarSizedObjects = true; 00376 Objects.push_back(StackObject(0, 1)); 00377 return (int)Objects.size()-NumFixedObjects-1; 00378 } 00379 00380 /// getCalleeSavedInfo - Returns a reference to call saved info vector for the 00381 /// current function. 00382 const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const { 00383 return CSInfo; 00384 } 00385 00386 /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's 00387 /// callee saved information. 00388 void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) { 00389 CSInfo = CSI; 00390 } 00391 00392 /// getMachineModuleInfo - Used by a prologue/epilogue 00393 /// emitter (TargetRegisterInfo) to provide frame layout information. 00394 MachineModuleInfo *getMachineModuleInfo() const { return MMI; } 00395 00396 /// setMachineModuleInfo - Used by a meta info consumer (DwarfWriter) to 00397 /// indicate that frame layout information should be gathered. 00398 void setMachineModuleInfo(MachineModuleInfo *mmi) { MMI = mmi; } 00399 00400 /// print - Used by the MachineFunction printer to print information about 00401 /// stack objects. Implemented in MachineFunction.cpp 00402 /// 00403 void print(const MachineFunction &MF, std::ostream &OS) const; 00404 00405 /// dump - Call print(MF, std::cerr) to be called from the debugger. 00406 void dump(const MachineFunction &MF) const; 00407 }; 00408 00409 } // End llvm namespace 00410 00411 #endif