LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MachineFrameInfo.h

Go to the documentation of this file.
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